tags:

views:

102

answers:

2

Why on earth does this code:

var a = new Date();                             
var b = new Date();     

a.setDate(31);
a.setMonth(11);
a.setFullYear(2009);

b.setFullYear(2009);
b.setMonth(11);
b.setDate(31);

ouputs correctly 31 december 2009 for b and 3 december 2009 :-O for a? Not in browser MyHorribleScrap version 6.6.6 but BOTH on FF 3.6 AND IE 8.06.6001

+13  A: 

That's why is recommended to use the Date constructor with arguments.

What is happening is when you instantiate the Date object, it gets the current date (today, February 26), and February has only 28 days, when you set the date by setDate(31), it jumps to the March 3.

The recommended way:

var a = new Date(2009, 11, 31);
// new Date(year, month, date [, hour, minute, second, millisecond ]);
CMS
+1 .. damn, you are fast... :p
Gaby
Well, I agree, february is an evil month, but I was setting a date in december ... anyway, thanks
Daniel
Good answer. Just wanted to add `Date()` returns todays date, which is why it's currently February. If you had done this in March, the error wouldn't have shown up . . . until you got to a shorter month. Yikes.
Tim Goodman
@Daniel: Hopefully my comment clarifies that for you. You start with Date() which is todays date in February . . . then you set the day to 31, which actual is March 3rd, then you change the month so now it's Dec. 3rd, 2010, and lastly you change the year to get Dec. 3rd 2009
Tim Goodman
Got it. Yes, you're right. I missed to think about the fact that setting a single field must anyway leave the object in a consistent state as date. This means theat specifying *always* first the year then month then the date prevent such possible mismatches?
Daniel
@Daniel: Yes, it would be safer to do it in that order, but if you know all three numbers it is still simpler to just specify it all at once in the constructor, as CMS suggests.
Tim Goodman
@Daniel: Setting the Year, then the month and then the date will not prevent that mismatches in some cases, e.g., suppose today is Dec 31 2009, and you want to set the date to Feb 01 2010, you change the Year, every thing Ok, you have now Dec 31 2010, now you change the month you end up with Feb 31 2010, which will yield to March 3, and you end up with Mar 01 2010
CMS
You are perfectly right. Many thanks for clarifying this to me. I understand that there are no alternatives to setting immediately the date. The problem was due to the fact that the code instantiating the Date object was placed in a declarative section just at the start and the date value was known only in a sub triggered by a late event. I'll change that
Daniel
A: 

i was practicly writing Tim´s answer =/

First set the year(because it could be a leap year) , then the month, and finally de date, but the best practice is using the constructor Date(year,month,date) but not always want to do that way.

gonxalo
As I said a to Daniel, setting the Year, then the month and then the date will not prevent that mismatches in some cases, e.g., suppose today is Dec 31 2009, and you want to set the date to Feb 01 2010, you change the Year, every thing Ok, you have now Dec 31 2010, now you change the month you end up with Feb 31 2010, which will yield to March 3, and you end up with Mar 01 2010
CMS
you are right, the constructor is the "safest" way. In all cases.
gonxalo