When comparing date objects in Javascript I found that even comparing the same date does not return true.
var startDate1 = new Date("02/10/2012");
var startDate2 = new Date("01/10/2012");
var startDate3 = new Date("01/10/2012");
alert(startDate1>startDate2); // true
alert(startDate2==startDate3); //false
How could I compare the equality of these dates? I am interested in utilizing the native Date object of JS and not any third party libraries since its not appropriate to use a third party JS just to compare the dates.
That is because in the second case, the actual date objects are compared, and two objects are never equal to each other. Coerce them to number:
alert( +startDate2 == +startDate3 ); // true
If you want a more explicity conversion to number, use either:
alert( startDate2.getTime() == startDate3.getTime() ); // true
or
alert( Number(startDate2) == Number(startDate3) ); // true
Oh, a reference to the spec: §11.9.3 The Abstract Equality Comparison Algorithm which basically says when comparing objects, obj1 == obj2 is true only if they refer to the same object, otherwise the result is false.
Compare dates using getTime() returning number of milliseconds from epoch (i.e. a number):
var startDate1 = new Date("02/10/2012");
var startDate2 = new Date("01/10/2012");
var startDate3 = new Date("01/10/2012");
alert(startDate1.getTime() > startDate2.getTime()); // true
alert(startDate2.getTime() == startDate3.getTime()); //true
Also consider using Date constructor taking explicit year/month/date number rather then relying on string representation (see: Date.parse()). And remember that dates in JavaScript are always represented using client (browser) timezone.
You do not need to use the getTime method- you can subtract a date object from another date object. It will return the milliseconds difference(negative, if the second is a later date)
var startDate1 = new Date("02/10/2012");
var startDate2 = new Date("01/10/2012");
var diff= (startDate1 -startDate2)
// evaluates to 0 if the dates have the same timestamp
you can compare the actual milliseconds :
alert(startDate2.getTime() === startDate3.getTime());
tl;dr
Use date.getTime() for comparisons.
Based on my testing, it was at least 25% than the next fastest alternative (date.valueOf()).
Details
Came across this in 2022. As others have already said, comparing like date1.getTime() === date2.getTime() is the way to go.
Someone else shared a jsperf link in an answer that seems broken for me right now, so decided to add some performance comparison of my own.
I created two arrays containing 1000 dates each. All dates will naturally be different instances (meaning direct === checks will fail), so what this benchmark does, is test what the fastest way is to convert a date to a primitive.
Here's the test data:
const data1 = Array.from({length: 1000}, () => new Date())
const data2 = Array.from({length: 1000}, () => new Date())
And here are the test cases (there's more in the link below):
// 1
data1.forEach((d1, i) => d1.getTime() === data2[i].getTime());
// 2
data1.forEach((d1, i) => d1.valueOf() === data2[i].valueOf());
// 3
data1.forEach((d1, i) => Number(d1) === Number(data2[i]));
// 4
data1.forEach((d1, i) => d1.toISOString() === data2[i].toISOString());
Result (use date.getTime())
Not a surprise that a date.getTime() conversion is much faster. It's around 25% faster than date.valueOf(), and between 10x and 100x faster than everything else (as far as I've checked).
Additionally, introducing optional chaining slowed the best case by almost 10% for me. Found that interesting. date.valueOf() also slowed down by 5% compared to its non optional chaining counterpart.
data1.forEach((d1, i) => d1?.getTime() === data2[i]?.getTime());
Benchmark link: here
Here's an image, in case the above link breaks at some point in the future.
You can also use the function valueOf()
var startDate1 = new Date("02/10/2012").valueOf();
var startDate2 = new Date("01/10/2012").valueOf();
var startDate3 = new Date("01/10/2012").valueOf();
alert(startDate1>startDate2); // 1326150000000 > 1328828400000 true
alert(startDate2==startDate3); // 1328828400000 > 1326150000000 false
One more way of comparing two dates would be converting dates to timestamps using "+" operator before the date.
So, let's say we have two dates:
const dateOne = new Date("10 January 1986")
const dateTwo = new Date("10 December 2020")
if(+dateOne == +dateTwo){
//do something
}
and so on.
This is really handy if you are sorting date objects too as you can use this in the sorting callback function.
Related
In a scenario, where the user can select a date ("from" date), along with the current date ("to" date), what is the best way to compare multiple (at least two) dates?
Assuming the incoming dates are a string with the format MM-DD-YYYY, consider the following comparison:
a = new Date("02-21-2018") // user "from" date
b = new Date() // current "to" date
b = b.setHours(0,0,0,0) // trim the time to compare just the dates
b = new Date(b) // converting back to the Date type
console.log("- :", a - b) // 0 (correct)
console.log("== :", a == b) // false (wrong)
console.log("<= :", a <= b) // true (correct)
console.log(">= :", a >= b) // true (correct)
console.log("value :", a.valueOf() == b.valueOf()) // true (correct)
Clearly there is a problem with comparing it directly using ==. So what is the best alternative? Would anything be different if we have several (not just two) dates?
Also when comparing two dates like new Date("02-21-2018") <= new Date() can a time zone affect the outcome?
You need to use the .getTime() method on your date objects.
Checking equality on the date objects doesn't work.
a = new Date("02-21-2018") // user "from" date
b = new Date() // current "to" date
b = b.setHours(0,0,0,0) // trim the time to compare just the dates
b = new Date(b) // converting back to the Date type
a = a.getTime();
b = b.getTime();
console.log("- :", a - b)
console.log("== :", a == b)
console.log("<= :", a <= b)
console.log(">= :", a >= b)
console.log("value :", a.valueOf() == b.valueOf())
Here is a similar subject:
Compare two dates with JavaScript
About the timezone,
I am not sure about what you want to do, but :
The method .getTimezoneOffset() can be used on your date objects to return their offsets.
As javascript runs in your browser on your computer, I guess the time zone of your new Date() will be affected by your "TimezoneOffset".
When comparing date objects in Javascript I found that even comparing the same date does not return true.
var startDate1 = new Date("02/10/2012");
var startDate2 = new Date("01/10/2012");
var startDate3 = new Date("01/10/2012");
alert(startDate1>startDate2); // true
alert(startDate2==startDate3); //false
How could I compare the equality of these dates? I am interested in utilizing the native Date object of JS and not any third party libraries since its not appropriate to use a third party JS just to compare the dates.
That is because in the second case, the actual date objects are compared, and two objects are never equal to each other. Coerce them to number:
alert( +startDate2 == +startDate3 ); // true
If you want a more explicity conversion to number, use either:
alert( startDate2.getTime() == startDate3.getTime() ); // true
or
alert( Number(startDate2) == Number(startDate3) ); // true
Oh, a reference to the spec: §11.9.3 The Abstract Equality Comparison Algorithm which basically says when comparing objects, obj1 == obj2 is true only if they refer to the same object, otherwise the result is false.
Compare dates using getTime() returning number of milliseconds from epoch (i.e. a number):
var startDate1 = new Date("02/10/2012");
var startDate2 = new Date("01/10/2012");
var startDate3 = new Date("01/10/2012");
alert(startDate1.getTime() > startDate2.getTime()); // true
alert(startDate2.getTime() == startDate3.getTime()); //true
Also consider using Date constructor taking explicit year/month/date number rather then relying on string representation (see: Date.parse()). And remember that dates in JavaScript are always represented using client (browser) timezone.
You do not need to use the getTime method- you can subtract a date object from another date object. It will return the milliseconds difference(negative, if the second is a later date)
var startDate1 = new Date("02/10/2012");
var startDate2 = new Date("01/10/2012");
var diff= (startDate1 -startDate2)
// evaluates to 0 if the dates have the same timestamp
you can compare the actual milliseconds :
alert(startDate2.getTime() === startDate3.getTime());
tl;dr
Use date.getTime() for comparisons.
Based on my testing, it was at least 25% than the next fastest alternative (date.valueOf()).
Details
Came across this in 2022. As others have already said, comparing like date1.getTime() === date2.getTime() is the way to go.
Someone else shared a jsperf link in an answer that seems broken for me right now, so decided to add some performance comparison of my own.
I created two arrays containing 1000 dates each. All dates will naturally be different instances (meaning direct === checks will fail), so what this benchmark does, is test what the fastest way is to convert a date to a primitive.
Here's the test data:
const data1 = Array.from({length: 1000}, () => new Date())
const data2 = Array.from({length: 1000}, () => new Date())
And here are the test cases (there's more in the link below):
// 1
data1.forEach((d1, i) => d1.getTime() === data2[i].getTime());
// 2
data1.forEach((d1, i) => d1.valueOf() === data2[i].valueOf());
// 3
data1.forEach((d1, i) => Number(d1) === Number(data2[i]));
// 4
data1.forEach((d1, i) => d1.toISOString() === data2[i].toISOString());
Result (use date.getTime())
Not a surprise that a date.getTime() conversion is much faster. It's around 25% faster than date.valueOf(), and between 10x and 100x faster than everything else (as far as I've checked).
Additionally, introducing optional chaining slowed the best case by almost 10% for me. Found that interesting. date.valueOf() also slowed down by 5% compared to its non optional chaining counterpart.
data1.forEach((d1, i) => d1?.getTime() === data2[i]?.getTime());
Benchmark link: here
Here's an image, in case the above link breaks at some point in the future.
You can also use the function valueOf()
var startDate1 = new Date("02/10/2012").valueOf();
var startDate2 = new Date("01/10/2012").valueOf();
var startDate3 = new Date("01/10/2012").valueOf();
alert(startDate1>startDate2); // 1326150000000 > 1328828400000 true
alert(startDate2==startDate3); // 1328828400000 > 1326150000000 false
One more way of comparing two dates would be converting dates to timestamps using "+" operator before the date.
So, let's say we have two dates:
const dateOne = new Date("10 January 1986")
const dateTwo = new Date("10 December 2020")
if(+dateOne == +dateTwo){
//do something
}
and so on.
This is really handy if you are sorting date objects too as you can use this in the sorting callback function.
This question already has answers here:
how to determine if 2 dates object equals each other? [duplicate]
(3 answers)
Closed 6 years ago.
I have been messing around with JSFiddle to solve this problem in FreeCodeCamp. When I use Date as a string (i.e., no "new"):
Case 1:
function isSameDay (dtFrom, dtTo) {
return dtFrom == dtTo
}
let today = Date()
let tomorrow = Date()
console.log(today)
console.log(tomorrow)
console.log(isSameDay(today, tomorrow))
isSameDay returns true. However when I use Date as a constructor (with "new"):
Case 2:
function isSameDay (dtFrom, dtTo) {
return dtFrom == dtTo
}
let today = new Date()
let tomorrow = new Date()
console.log(today)
console.log(tomorrow)
console.log(isSameDay(today, tomorrow))
isSameDay returns false. However(!), when I add the unary operator "+":
Case 3:
function isSameDay (dtFrom, dtTo) {
return dtFrom == dtTo
}
let today = + new Date()
let tomorrow = + new Date()
console.log(today)
console.log(tomorrow)
console.log(isSameDay(today, tomorrow))
isSameDay returns true. I understand case 1 and case 3 returning true because they are just the same strings and the same millisecond values.
Why does case 2 return false?
Using Date(), the JavaScript Date objects can only be instantiated by calling JavaScript Date as a constructor: calling it as a regular function (i.e. without the new operator) will return a string rather than a Date object. MDN Reference.
typeof Date() //"string"
Date() == Date() //true
Using instead a constructor as new Date(), each instance is unique (the two instances of the same constructor are still different to each-other), this is the reason why they are not equal when compared.
typeof new Date(); //"object"
new Date() === new Date() //false
Simply put, Case 2 returns false because you are comparing two different object references (even if both objects contain the exact same properties).
Whereas in the other cases you are comparing the toString() value of the dates.
Please see Note 3 in the official documentation for the == Abstract Equality Algorithm
NOTE 3
The equality operator is not always transitive. For example,
there might be two distinct String objects, each representing the same
String value.
Each String object would be considered equal to the
String value by the == operator, but the two String objects would not
be equal to each other. For Example:
new String("a") == "a" //true
"a" == new String("a") //true
but
new String("a") == new String("a") //false.
When I create two identical JavaScript Date objects and then compare them, it appears that they are not equal. How to I test if two JavaScript dates have the same value?
var date1 = new Date('Mon Mar 11 2013 00:00:00');
var date2 = new Date('Mon Mar 11 2013 00:00:00');
console.log(date1 == date2); //false?
JS Fiddle available here
It appears this has been addressed already.
To check whether dates are equal, they must be converted to their primitives:
date1.getTime()=== date2.getTime()
//true
First of all, you are making a sound mistake here in comparing the references. Have a look at this:
var x = {a:1};
var y = {a:1};
// Looks like the same example huh?
alert (x == y); // It says false
Here, although the objects look identical they hold different slots in memory. Reference stores only the address of the object. Hence both references (addresses) are different.
So now, we have to compare the values since you know reference comparison won't work here.
You can just do
if (date1 - date2 == 0) {
// Yep! Dates are equal
} else {
// Handle different dates
}
I compare many kinds of values in a for loop, so I wasn't able to evaluate them by substracting, instead I coverted values to string before comparing
var a = [string1, date1, number1]
var b = [string2, date2, number2]
for (var i in a){
if(a.toString() == b.toString()){
// some code here
}
}
Is there a way to take a date object from a HTML object in the format of ####-##-## and convert it to epoch time. For example, the user inputs the value of August 12, 2012 which shows as 2012-08-12 when I print out the .val() of it, and I need to get this in Epoch time.
EDIT
Code to date:
if (hvStartDate == "") {
hvStartDate = "start"
}
else {
console.log($("#hv-start-date").val()); // => 2012-08-20
hvStartDate = new Date($("#hv-start-date").val()).getTime(); // => NaN
}
if (hvEndDate == "") {
hvEndDate = "end"
}
else {
hvEndDate = new Date($("#hv-end-date").val()).getTime(); // => NaN
}
var myTmp = new Date("2012-08-20");
console.log(myTmp.getTime()); // => NaN
Javascript's Date built-in allows you to pass a date string into its constructor, giving you a Date based on that string. From there, calling getTime( ) will give you the epoch time.
new Date($('.user-value').val()).getTime(); // => epoch time
new Date('2012-08-12').getTime(); // 1344729600000
Caveat: Beware of locale strings and locale-specific date formatting (for example, the position of days and months switch depending on locale).
EDIT: Based on your code in the comment below, here's what you need to do. Notice that you have to instantiate a new Date Object before calling getTime():
if (hvStartDate == "") {
hvStartDate = "start"
}
else {
hvStartDate = new Date($("#hv-start-date").val()).getTime();
}
Simply use the getTime() function. It returns the number of milliseconds since Epoch :
var msSinceEpoch = myDate.getTime();
Complete Date reference at MDN : https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date
EDIT : if you have to parse it too, you may :
use new Date(theString) if it has the good format
set yourself the different date fields (see reference) after having parsed it
use a date parsing library. I use this one : http://www.datejs.com/ which is very powerful for all date parsing, computing and formating.