views:

395

answers:

2

I'm comparing dates with something like this:

var dt = new Date(); 

dt.setDate("17");    
dt.setMonth(06); 
dt.setYear("2009");

var date = new Date();

console.log("dt(%s) == date(%s) == (%s)", dt, date, (dt == date) );

if( now == dt ) {
    ....
}

The string values are dynamic of course.

In the logs I see:

dt(Fri Jul 17 2009 18:36:56 GMT-0500 (CST)) == date(Fri Jul 17 2009 18:36:56 GMT-0500 (CST) == (false)

I tried .equals() but it didn't work ( I was trying the Java part of JavaScript :P )

How can I compare these dates so they return true?

+3  A: 

The following code should solve your problem:

(myDate.getTime() == myOtherDate.getTime())

The problem is that when you write:

(myDate == myOtherDate)

...you're actually asking "Is myDate pointing to the same object that myOtherDate is pointing to?", not "Is myDate identical to myOtherDate?".

The solution is to use getTime to obtain a number representing the Date object (and since getTime returns the number of milliseconds since epoch time, this number will be an exact representation of the Date object) and then use this number for the comparison (comparing numbers will work as expected).

Steve

Steve Harrison
Should I consider that I might actually lose a few milliseconds in the process? ?
OscarRyz
Steve, it's incorrect what you said about == operator for date. This is not C# or JAVA. The problem is that each Date component has different time associated and the comparison gives false.
SolutionYogi
@Oscar Reyes: No, "getTime()" returns the exact number of milliseconds since epoch time, so everything should be spot on.
Steve Harrison
@Steve. It worked. What concerns me a bit it that , in my sample I have 3 lines between each new Date() invocation, but in my code I have some few tens more. It there a possibility that... bahhhh who cares!, It's working know , let's go home :) :) :)
OscarRyz
@SolutionYogi: What do you mean by "each Date component has a different time associated"? You can have two date objects that represent the exact same time (where "getTime()" returns the same number), and the == operator will return false.
Steve Harrison
Oscar, that's a valid concern and what you have done may not work every time. I will create sample code and show it.
SolutionYogi
@Oscar Reyes: Well, you can simplify your code quite a bit if you replace 'var dt = new Date(); dt.setDate("17"); dt.setMonth(06); dt.setYear("2009");' with 'var dt = new Date(2009, 06, 17);'... The latter is also much more accurate, and you're less likely to run into problems (mainly caused by months not having the same number of days).
Steve Harrison
Steve, if the user will do new Date(), the date component will take current time and associate with that date. Your code will work only when both, the date and the time part, are same for the variables.
SolutionYogi
@SolutionYogi: Correct, it will. My solution assumes you want to see whether two Date objects are *exactly* the same. If you only care whether the two Date objects are the same day, you'll have to try something else.
Steve Harrison
+3  A: 

The problem with your code is that you are comparing time/date part instead of only the date.

Try this code:

    var myDate = new Date();
    myDate.setDate(17);
    myDate.setMonth(7);
    myDate.setYear(2009);

    //Delay code - start
    var total = 0;
    for(var i=0; i<10000;i++)
        total += i;
    //Delay code - end

    var now = new Date();

    console.log(now.getTime() == myDate.getTime());

If you keep the for loop code (identified by 'Delay code -start'), console will show 'false' and if you remove the for loop code, console will log 'true' even though in both the cases myDate is 7/17/2009 and 'now' is 7/17/2009.

The problem is that JavaScript date object stores both date and time. If you only want to compare the date part, you have to write the code.

function areDatesEqual(date1, date2)
{
    return date1.getFullYear() == date2.getFullYear() 
            && date1.getMonth() == date2.getMonth()
            && date1.getDate() == date2.getDate();
}

This function will print 'true' if the two javascript 'date part' is equal ignoring the associated time part.

SolutionYogi
Never use "getYear()"—it's deprecated. Instead, use "getFullYear()".
Steve Harrison
You are right, my mistake. But I hope you do get my point about your original answer where you are saying that date compares 'references' and not the value.
SolutionYogi
Ohhh, I was afraid this to happen. Actually I knew it, but didn't want to face it :P So.. a function using what you shown + getHour() and getMinute and etc et is in order?
OscarRyz
@SolutionYogi: Try this: 'var a = { name: "Foo" }; var b = { name: "Foo" };'. These objects are identical, right? Now, compare them: '(a == b)'. The result will be 'false'. The reason for this is that although the objects are identical, they are two separate objects (variables 'a' and 'b' point to different objects)—this is what the "==" operator is checking. What is happening with the Date objects is the same. My solution is to use "getTime()" to obtain a number that represents the Date object and to compare the two numbers (which will work as expected, as there are no pointers involved).
Steve Harrison
@Oscar Reyes: It depends on what you want to compare. Do you want to see whether the dates are *exactly* the same (to the last millisecond)? If this is the case, use my solution. However, if you only want to see whether the dates are the same day (i.e. year, month, day are identical; hours, minutes, seconds, milliseconds my differ), use SolutionYogi's "areDatesEqual" function.
Steve Harrison