Figuring out why Date.parse() does not equal comparison date - javascript

When I compare arriveDate1 to holiday they are not equal and I'm not sure why. In the console both dates appear the same. Any ideas why this might be? (using Date.js).
var orderShip1 = Date.today(); //date it ships
var arriveDate1 = orderShip1.addDays(3); //first day it could arrive
var holiday = Date.parse('8/8/2014');
console.log(arriveDate1); // Fri Aug 08 2014 00:00:00 GMT-0400 (EDT)
console.log(holiday); // Fri Aug 08 2014 00:00:00 GMT-0400 (EDT)
if (arriveDate1 === holiday) {
orderShip1.addDays(1);
//arriveDate1 = orderShip1.addDays(1);
}

This happens because when you check with the == and === operators, Javascript performs a check by reference. This two objects, unless they are declared like holiday = arriveDate1, will then never be equal, because they don't share the same memory reference.
Example:
a = {foo: 'hello'};
b = {foo: 'hello'};
a == b;
> false
You should perform the check using .toISOString or the unary operator + to convert the data objects in milliseconds, like this:
// this
if (arriveDate1.toISOString() == holiday.toISOString()) ...
// or this
if (+arriveDate1 == +holiday) ...

The triple equals sign tests if objects are identical, that is they are the same object. Try double equals.

Related

Can not compare two ISO format dates using Javascript

I am comparing two dates using javascript but always its returning the wrong result. I am explaining my code below.
dateLessThan(from: string, to: string) {
console.log(from,to);
var d1 = new Date(from);
var d2 = new Date(to);
console.log('converted time',d1,d2);
if (from > to) {
return false;
} else {
return true;
}
}
here in my second console message I am getting converted time Fri Jan 24 2020 00:00:00 GMT+0530 (India Standard Time) Wed Jan 01 2020 00:00:00 GMT+0530 (India Standard Time) but its always returns true. Here I need to compare both dates.
Here is a quick-and-dirty solution. Please note that this will not work if you attempt to compare two dates in two different timezones. It assumes that each date is in the same timezone.
function dateLessThan(from, to) {
//console.log(from,to);
var d1 = new Date(from);
var d2 = new Date(to);
//console.log('converted time',d1,d2);
/* This is your code.
if (from > to) {
return false;
} else {
return true;
}
*/
// Here is the easy way to do it with the strings.
return d1.toISOString() < d2.toISOString();
}
console.log('Should be true: ' + dateLessThan('2011-01-01', '2013-01-01'));
console.log('Should be false: ' + dateLessThan('2014-01-01', '2013-01-01'));

Moment JS not recognising ISO 8601 date

So I've got two dates I'd like to get the difference of:
console.log(new Date(Date.now()).toISOString()); //2017-07-07T16:55:30.471Z
console.log(asset.past[i].date); //2017-07-06T20:29:00.670Z
var a = moment([new Date(Date.now()).toISOString()]);
console.log(a); //Moment Date:Sun Jan 01 2017 00:00:00 GMT+0000
var b = moment([asset.past[i].date]);
console.log(b); //Moment Date:Sun Jan 01 2017 00:00:00 GMT+0000
console.log(a.diff(b, 'seconds', true)); //0
console.log(a.diff(b, 'days', true)); //0
console.log(a.diff(b, 'months', true)); //0
I've put the out put of the console logs as comments afterwards. I assume it doesn't recognize the date format as ISO 8601 and defaults to Sun Jan 01 2017 00:00:00 GMT+0000. Either way, any idea how to fix it?
Cheers, Ed.
Why are you passing in an array to the moment constructor? What do you want a to actually be, just the current date? If so just do moment(). If you want to pass in a string do it like you correctly did on line 1.
Here are just the 2 fixes where I removed the square brackets. Again, you can just do moment() to get a moment that points to now.
// var a = moment(new Date(Date.now()).toISOString());
var a = moment();
var b = moment(asset.past[i].date);

Javascript date less than or equal to returning only less than

I have a jQuery datepicker tool returning back a maximum and a minimum date.
The dates are to filter out results from an array. I use jQuery.grep to filter based on the date. For some reason, while >= will work, <= only returns less than.
// Function to filter based on date minimum
function filterListGreaterThan(filter, list, min){
var result = jQuery.grep(list, function (obj){
return new Date(obj[filter]) >= min;
});
return result;
};
function filterListLessThan(filter, list, max){
var result = jQuery.grep(list, function (obj){
return new Date(obj[filter]) <= max;
});
return result;
};
So if i put in Nov 1, 2013 - Nov 5, 2013 it will only return Nov 1 - Nov 4... and I have no idea why.
Edit: Mac gave me the correct answer. When comparing the dates jQuery Sets the time to midnight. So even though I had it searching on the correct day it was not looking past midnight. This is the Corrected function:
// Function to filter based on date maximum
function filterListLessThan(filter, list, max){
var result = jQuery.grep(list, function (obj){
//add time to date because jQuery sets the time at 00:00:00
max.setHours(23,59,59);
return new Date(obj[filter]) <= max;
})
return result;
};
It seems the problem is likely due to the max date having a time component set to 00:00 AM - all items in the array occurring on the max date are probably being filtered out because they occur some time after 00:00 AM.
To fix this, the best approach is either to change the max date to have a time component of 11:59:59 PM, or to set the max date to 00:00 AM the following day and use a less-than (rather than a less-than-or-equal).
Not entirely sure I understand what you are trying to do, so apologies if this is not what you need but if you just want to filter an array of dates I'd try something like below.
You need to make sure you are comparing a Date object with another Date object and that the values in your array are formatted so as to make a valid Date object.
I'm not sure how that jQuery function works but using vanilla javascript I would do something like this to filter dates:
var list = ['2013,10,01','2013,10,02','2013,10,03','2013,10,04','2013,10,05',
'2013,10,06'];
function filterListGreaterThan(list, min_date){
var filtered_dates = [];
for(var i=0; i < list.length; i++){
var parts = list[i].split(','),
test_date = new Date(parts[0],parts[1],parts[2]);
if(test_date >= min_date){
filtered_dates.push(test_date);
}
}
return filtered_dates;
}
var min_date = new Date('2013','10','04'),
dates = filterListGreaterThan2(list, min_date);
console.log(dates);
//RETURNS:
//Mon Nov 04 2013 00:00:00 GMT+0000 (GMT Standard Time)
//Tue Nov 05 2013 00:00:00 GMT+0000 (GMT Standard Time)
//Wed Nov 06 2013 00:00:00 GMT+0000 (GMT Standard Time)
//

round up/ round down a momentjs moment to nearest minute

How do you round up/ round down a momentjs moment to nearest minute?
I have checked the docs, but there doesn't appear to be a method for this.
Note that I do not want a string rounded to the nearest minute, I want a moment returned (or modified in place, either is fine). I prefer not to have to convert to a string, and the convert back too.
Thanks.
As requested, here is some code:
var now = new moment(new Date());
if (now.seconds() > 0) {
now.add('minutes', -1);
}
now.seconds(0);
as you can see, I have managed to manually round down the moment here, but it seems rather hacky. Just after a more elegant way of accomplishing this.
To round up, you need to add a minute and then round it down. To round down, just use the startOf method.
Note the use of a ternary operator to check if the time should be rounded (for instance, 13:00:00 on the dot doesn't need to be rounded).
Round up/down to the nearest minute
var m = moment('2017-02-17 12:01:01');
var roundDown = m.startOf('minute');
console.log(roundDown.toString()); // outputs Tue Feb 17 2017 12:01:00 GMT+0000
var m = moment('2017-02-17 12:01:01');
var roundUp = m.second() || m.millisecond() ? m.add(1, 'minute').startOf('minute') : m.startOf('minute');
console.log(roundUp.toString()); // outputs Tue Feb 17 2017 12:02:00 GMT+0000
Round up/down to the nearest hour
var m = moment('2017-02-17 12:59:59');
var roundDown = m.startOf('hour');
console.log(roundDown.toString()); // outputs Tue Feb 17 2017 12:00:00 GMT+0000
var m = moment('2017-02-17 12:59:59');
var roundUp = m.minute() || m.second() || m.millisecond() ? m.add(1, 'hour').startOf('hour') : m.startOf('hour');
console.log(roundUp.toString()); // outputs Tue Feb 17 2017 13:00:00 GMT+0000
Partial answer:
To round down to nearest moment minute:
var m = moment();
m.startOf('minute');
However, the equivalent for rounding up, endOf, doesn't quite give the expected result.
Rounding to the nearest hour can be achieved by adding half an hour and then run .startOf('hour'). This is the same for any time measurement.
var now = moment();
// -> Wed Sep 30 2015 11:01:00
now.add(30, 'minutes').startOf('hour'); // -> Wed Sep 30 2015 11:31:00
// -> Wed Sep 30 2015 11:00:00
var now = moment();
// -> Wed Sep 30 2015 11:31:00
now.add(30, 'minutes').startOf('hour'); // -> Wed Sep 30 2015 12:01:00
// -> Wed Sep 30 2015 12:00:00
The roundTo feature could make it into a future release.
Examples:
moment().roundTo('minute', 15); // output: 12:45
moment().roundTo('minute', 15, 'down'); // output: 12:30
Rounding Down
Easy. As stated by many others, just use Moment.startOf:
var roundDown = moment('2015-02-17 12:59:59').startOf('hour');
roundDown.format('HH:mm:SS'); // 12:00:00
Importantly, this also works as expected:
var roundDown = moment('2015-02-17 12:00:00').startOf('hour');
roundDown.format('HH:mm:SS'); // 12:00:00
Rounding Up
Slightly trickier, if we want to round up with a proper ceiling function: for example, when rounding up by hour, we want 12:00:00 to round up to 12:00:00.
This does not work
var roundUp = moment('2015-02-17 12:00:00').add(1, 'hour').startOf('hour');
roundUp.format('HH:mm:SS'); // ERROR: 13:00:00
Solution
function roundUp(momentObj, roundBy){
return momentObj.add(1, roundBy).startOf(roundBy);
}
var caseA = moment('2015-02-17 12:00:00');
roundUp(caseA, 'minute').format('HH:mm:SS'); // 12:00:00
var caseB = moment('2015-02-17 12:00:00.001');
roundUp(caseB, 'minute').format('HH:mm:SS'); // 12:01:00
var caseC = moment('2015-02-17 12:00:59');
roundUp(caseC, 'minute').format('HH:mm:SS'); // 12:01:00
A more precise answer:
t.add(30, 'seconds').startOf('minute')
Case1: Rounding down if seconds < 30
t = moment(); //12:00:05
t.add(30, 'seconds').startOf('minute') //12:00:00
Case2: Rounding up if seconds >= 30
t = moment(); //12:00:33
t.add(30, 'seconds').startOf('minute') //12:01:00
I was searching for this same question and found a better solution:
Use the third parameter in diff() function:
moment("2019-05-02 17:10:20").diff("2019-05-02 17:09:30","minutes",true)
By setting third parameter to true, you get the raw value as response that you can round by yourself using Math.round()
See JSFiddle:
https://jsfiddle.net/2wqs4o0v/3/
This solution worked for me;
function round_up_to_nearest_hour(date = new Date()) {
return moment(date).add(59, 'minutes').startOf('hour').toDate();
}
Just another possibility:
const now = moment();
// -> Wed Sep 30 2015 11:57:20 GMT+0200 (CEST)
now.add(1, 'm').startOf('minute');
// -> Wed Sep 30 2015 11:58:00 GMT+0200 (CEST)
The simplest solution so far:
function floor(time, floorBy = 'minute') {
return time.startOf(floorBy);
}
function ceil(time, ceilBy = 'minute') {
return time.subtract(1, 'millisecond').add(1, ceilBy).startOf(ceilBy);
}
// The solution is above. The code below is an optional test:
console.log(
floor(moment('2019-01-01 12:00:00.000')).format('H:mm:ss.SSS') === '12:00:00.000',
ceil(moment('2019-01-01 12:00:00.000')).format('H:mm:ss.SSS') === '12:00:00.000',
floor(moment('2019-01-01 12:00:00.001')).format('H:mm:ss.SSS') === '12:00:00.000',
ceil(moment('2019-01-01 12:00:00.001')).format('H:mm:ss.SSS') === '12:01:00.000',
floor(moment('2019-01-01 12:15:16.876'), 'hour' ).format('H:mm:ss.SSS') === '12:00:00.000',
ceil(moment('2019-01-01 12:15:16.876'), 'hour' ).format('H:mm:ss.SSS') === '13:00:00.000',
floor(moment('2019-01-01 12:59:59.999'), 'second').format('H:mm:ss.SSS') === '12:59:59.000',
ceil(moment('2019-01-01 12:59:59.999'), 'second').format('H:mm:ss.SSS') === '13:00:00.000',
floor(moment('2019-01-01 12:00:00.025'), 'ms' ).format('H:mm:ss.SSS') === '12:00:00.025',
ceil(moment('2019-01-01 12:00:00.025'), 'ms' ).format('H:mm:ss.SSS') === '12:00:00.025'
);
<script src="//cdn.jsdelivr.net/npm/moment#2.24.0/min/moment.min.js"></script>

Test if a string has timezone in javascript

I receive a date time as a string from the server that might look like this:
07/08/2012 13:17:32
This is a UTC time.
Or it might have timezone in format:
07/08/2012 13:17:32 UTC+01:00
I need a general way to parse this into a Date object for display. If I do a var d = new Date(str) then the first example it assumes is a local time.
Edit:
It might not always be 'UTC' in the string, I think it could be GMT, or Z, or any other timezone signifier.
Any ideas?
If your timezone is always in format UTC+nn, and strings with explicit UTC TZ are parsed correctly, as I assume from your question, then simple
if (date_string.search(/a-z/i) == -1) {
date_string += 'UTC+00:00'
}
will do.
As a quick and dirty solution, it looks like the timezone is a final "part" of the format separated by whitespace. So you could count the number of "parts" in the input string and add a default timezone if none is found. For example:
function parseDateDefaultUTC(str) {
var parts = str.split(/\s+/);
return new Date((parts.length===3) ? str : str + ' UTC');
}
var d;
d = parseDateDefaultUTC("07/08/2012 13:17:32");
d; // => Sun Jul 08 2012 07:17:32 GMT-0600 (MDT)
d = parseDateDefaultUTC("07/08/2012 13:17:32 UTC+01:00");
d; // => Sun Jul 08 2012 06:17:32 GMT-0600 (MDT)

Categories

Resources