Subtracting 100s of minutes accurately with Javascript - javascript

If I have two values, each representing a date such as YYYYMMDDHHMM (YearMonthDayHourMinute) like:
202012141800
202012141614
What I was trying to convey in the question is that this gives me 186 minutes, but this isn't accurate, however, since the last two digits will never be larger than 59 given 60 minutes in an hour. The 100 in 186 comes from hours 18 (6pm) and 16 (4pm).
How can I subtract these in Javascript to account for the extra 40 minutes tacked on if the two timestamps are more than an hour apart?
I have this, but it's not that efficient since I'd need to know the maximum number of hours two timestamps could be apart:
var end_time = $('#the-agenda li.current time').data('end-time'),
time_now = current_display_number,
timer_duration = end_time - time_now;
if (timer_duration > 200) {
// if more than 2 hours, subtract 80 minutes
timer_duration = timer_duration - 80;
}
else if (timer_duration > 100) {
// if more than 1 hour, subtract 40 minutes
timer_duration = timer_duration - 40;
}
I feel like the answer may somehow be in this question's answer, but I am not sure how to apply that parseInt to this situation.

You wouldn't use parseInt. You would use Date.parse, except that the string has to be in a predefined format. Without using a specialized library, you'll have to parse the parts yourself and then create a new Date with the parts. Fortunately though the incoming strings seem straightforward to parse. Do something like this:
let startTimeStr = '202012141614';
let endTimeStr = '202012141800';
let asDateTime = (d) => new Date(
d.substring(0,4),
d.substring(4,6) - 1,
d.substring(6,8),
d.substring(8,10),
d.substring(10,12)
)
let startTime = asDateTime(startTimeStr);
let endTime = asDateTime(endTimeStr);
let result = (endTime - startTime) / 60000;
console.log(result);

// Different in milliseconds
const difference = (new Date('2020-12-14T18:00:00')) - (new Date('2020-12-14T16:14:00'));
const inMinutes = Math.floor(difference / 60000);
You need to convert the string formats to a date object to get accurate date info.

Related

Parse and manipulate date times with micro seconds

I have date time strings with the following format: YYYY-MM-DD HH:MM:SS.SSSSSS
For example:
const d1 = '2022-07-03 03:45:15.679570'
const d2 = '2022-07-03 03:45:15.679638'
What I'd like to achieve is the ability to subtract these date times, e.g. in the above example the result would be:
console.log(subtractDates(d1, d2)) // -0000-00-00 00-00-00.000068
console.log(subtractDates(d2, d1)) // 0000-00-00 00-00-00.000068
I was looking for different libraries but they all have resolution of 0-999 ms and that's it.
The subtraction of dates becomes ambiguous when months are subtracted. For instance, there are several possibilities on how to represent the difference between 2022-03-31 and 2022-02-28. If this is considered to be a difference of 1 months and 3 days, then what if we add one day to both dates? Is then the difference (of the same number of days) suddenly an exact month?
To avoid this ambiguity, I would suggest to express the difference in a number of days (and smaller units of time) even when that number of days exceeds a month or even a year. Just keep the greatest unit of measure to the day when dealing with durations.
Here is a pair of classes that could easily be extended to provide more functionality. The general idea is to use the numeric system of the native Date type, but to multiply it by 1000.
class MicroDuration {
constructor(us) {
this.us = Math.abs(us); // Don't work with negative durations.
}
toString() { // dddddd hh:mm:ss.ssssss
return (Math.floor(this.us / 86_400_000_000) + " "
+ new Date(Math.floor(this.us / 1000)).toJSON().slice(11, 23)
+ (this.us % 1000 + "").padStart(3, "0")
).padStart(22, "0");
}
}
class MicroDate {
constructor(iso) {
iso = iso.replace(" ", "T").replace(/\d$/, "$&Z");
this.us = Date.parse(iso) * 1000 + parseInt(iso.slice(-4));
}
diff(arg) {
if (!(arg instanceof MicroDate)) arg = new MicroDate(arg);
return new MicroDuration(this.us - arg.us);
}
toString() {
return new Date(Math.floor(this.us / 1000)).toJSON()
.replace("Z", (this.us % 1000 + "").padStart(3, "0"))
.replace("T", " ");
}
}
// Demo
const d1 = '2022-07-03 03:45:15.679570'
const d2 = '2024-08-03 15:45:15.678638'
const diff = new MicroDate(d1).diff(d2).toString();
console.log(diff);

Convert timezone offset "+00:00" to minutes

I have a function that returns timezone offset strings (like "+03:00")
And I want to convert this string to minutes offset("+03:00" should turn to 180) using moment.js or built-in plain javascript options
How can I do that?
I've found the solution:
moment().utcOffset("+03:00").utcOffset() // returns 180
moment().utcOffset("-09:00").utcOffset() // returns -540
Using vanilla JS you get the minutes using the below and it will honour positive and negative offsets.
let offset = '-03:30';
let [h, m] = offset.split(':');
let hours = Number.parseInt(h);
let minutes = Number.parseInt(m);
let totalMinutes = hours * 60 + (hours < 0 ? (-minutes) : minutes);
Just get the offset hour and then multiply it by 60 like below:
function parseOffset(offset){
var minutesOffset = (parseInt(offset[1] + offset[2]) * 60)
console.log(parseInt(offset[0] + minutesOffset.toString()))
}
parseOffset("+03:00");
parseOffset("-02:00");
The above returns negative offset too.
The only way to get minutes from the date object in plain javascript is by using
.getTimezoneOffset() - but that doesn't seem to be the case based on your question.
There is no other way that I'm aware of to parse "+03:00" to minutes.
You can try to use Parse Offset method of momentjs timezone.
Usage:
var zone = moment.tz.zone('America/New_York');
zone.parse(Date.UTC(2012, 2, 19, 8, 30)); // 240

JavaScript, how to create difference of date with moment.js

I am having a problem with creating an error message on a page where there is a "from date:", and a "to date:". If the difference between the two dates is greater than or equal to 60 days, I have to put up an error message.
I am trying to use moment.js and this is what my code is looking like now. It was recommended that I use it in knockout validation code. this is what it looks like right now:
var greaterThan60 = (moment().subtract('days', 60) === true) ? "The max range for from/to date is 60 days." : null;
I am still not sure how to make it greater than 60 days, not just equal to 60 days. This is what my boss gave me to help.
Reference site for moment().subtract
moment.js provides a diff() method to find difference between dates. please check below example.
var fromDate = 20180606;
var toDate = 20180406;
var dif = moment(fromDate, 'YYYYMMDD').diff(moment(toDate, 'YYYYMMDD'),'days')
console.log(dif) // 61
subtract returns a new moment object. So checking for true always returns false. You can use range and diff to calculate a diff in days and check that:
let start = moment('2016-02-27');
let end = moment('2016-03-02');
let range = moment.range(start, end);
let days = range.diff('days');
let error = null;
if (days > 60) {
error = "The max range for from/to date is 60 days.";
}
You Can try this.
var date = Date.parse("2018-04-04 00:00:00");
var selectedFromDate = new Date(date);
var todayDate = new Date();
var timedifference = Math.abs(todayDate.getTime() - selectedFromDate.getTime());
var daysDifference = Math.ceil(timedifference/(1000 * 3600 * 24));
just use if else loop for greater than 60 days validation.
if(daysDifference > 60)
{
alert("From Date should be less than 2 months");
}
Use the .isSameOrAfter function to compare if the end value is greater than or equal to the start value plus sixty days. Example:
var greaterThan60 = toDate.isSameOrAfter(startDate.add(60, 'days'));
where toDate is your end time as a moment object and startDate is the start time as a moment object. If the end date is greater than or equal to 60 days after the start date, greaterThan60 will be true.
References:
isSameOrAfter
add

Compare 2 ISO 8601 timestamps and output seconds/minutes difference

I need to write JavaScript that's going to allow me to compare two ISO timestamps and then print out the difference between them, for example: "32 seconds".
Below is a function I found on Stack Overflow, it turns an ordinary date into an ISO formatted one. So, that's the first thing out the way, getting the current time in ISO format.
The next thing I need to do is get another ISO timestamp to compare it with, well, I have that stored in an object. It can be accessed like this: marker.timestamp (as shown in the code below). Now I need to compare those two two timestamps and work out the difference between them. If it's < 60 seconds, it should output in seconds, if it's > 60 seconds, it should output 1 minute and 12 seconds ago for example.
Thanks!
function ISODateString(d){
function pad(n){return n<10 ? '0'+n : n}
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'}
var date = new Date();
var currentISODateTime = ISODateString(date);
var ISODateTimeToCompareWith = marker.timestamp;
// Now how do I compare them?
Comparing two dates is as simple as
var differenceInMs = dateNewer - dateOlder;
So, convert the timestamps back into Date instances
var d1 = new Date('2013-08-02T10:09:08Z'), // 10:09 to
d2 = new Date('2013-08-02T10:20:08Z'); // 10:20 is 11 mins
Get the difference
var diff = d2 - d1;
Format this as desired
if (diff > 60e3) console.log(
Math.floor(diff / 60e3), 'minutes ago'
);
else console.log(
Math.floor(diff / 1e3), 'seconds ago'
);
// 11 minutes ago
I would just store the Date object as part of your ISODate class. You can just do the string conversion when you need to display it, say in a toString method. That way you can just use very simple logic with the Date class to determine the difference between two ISODates:
var difference = ISODate.date - ISODateToCompare.date;
if (difference > 60000) {
// display minutes and seconds
} else {
// display seconds
}
I'd recommend getting the time in seconds from both timestamps, like this:
// currentISODateTime and ISODateTimeToCompareWith are ISO 8601 strings as defined in the original post
var firstDate = new Date(currentISODateTime),
secondDate = new Date(ISODateTimeToCompareWith),
firstDateInSeconds = firstDate.getTime() / 1000,
secondDateInSeconds = secondDate.getTime() / 1000,
difference = Math.abs(firstDateInSeconds - secondDateInSeconds);
And then working with the difference. For example:
if (difference < 60) {
alert(difference + ' seconds');
} else if (difference < 3600) {
alert(Math.floor(difference / 60) + ' minutes');
} else {
alert(Math.floor(difference / 3600) + ' hours');
}
Important: I used Math.abs to compare the dates in seconds to obtain the absolute difference between them, regardless of which is earlier.

Convert UNIX timestamp difference to minutes

I have 2 dates, that I convert to UNIX timestamp - start date and confirm date. I subtract one from another and get numbers like these:
-12643,
0,
3037,
1509,
-3069
Basically, what I need to do is to get the difference between the two dates in minutes, but I don't know how to convert those to minutes. The end output should be something like: -25, 13, 155
How did you get the original numbers? I believe the standard Unix timestamps are in seconds, so you should be able to divide by 60 to get minutes. However, Date.now() in JavaScript, for example, returns milliseconds, so you'd need to divide by 60,000.
Given two UNIX timestamps: a, b; you can calculate the difference between them in minutes like this:
var a = 1377005400000; //2013-07-20 15:30
var b = 1377783900000; //2013-07-29 15:45
var dateA = new Date(a);
var dateB = new Date(b);
var dayRelativeDifference = dateB.getHours()*60 + dateB.getMinutes()
- dateA.getHours()*60 - dateA.getMinutes();
// dayRelativeDifference will be 15
var absoluteDifference = (b-a)/60
// absoluteDifference will be 12975000
Also have a look at http://www.w3schools.com/jsref/jsref_obj_date.asp
You just need to divide by 60. You already have the difference between the two timestamps, so none of the Date overhead above is necessary:
var diffs = new Array(-12643, 0, 3037, 1509, -3069);
for (var i = 0; i < diffs.length; i++)
document.write(diffs[i] % 60);

Categories

Resources