views:

516

answers:

4

I'm in javascript, running this in the console

d = new Date();    
d.setMonth(1);
d.setFullYear(2009);
d.setDate(15);          
d.toString();

outputs this:

"Sun Mar 15 2009 18:05:46 GMT-0400 (EDT)"

Why would this be happening? It seems like a browser bug.

+1  A: 
d = new Date();
d.setDate(15);                    
d.setMonth(1);
d.setFullYear(2009);                                                                 
d.toString();

This works.

Issac Kelly
In your original question, setting the Month first was causing a problem because today is the 30th and Feb 30th doesn't exist so Javascript adjusted the date for you. Think about it, if you had written this code a couple of days ago, it probably would have worked fine. Lucky you worked on it today!
BoltBait
why not do it in one step as Jason W mentioned.
Omar Kooheji
Doing it in one step is what I ended up doing, I just posted this as soon as I figured out what the problem was.
Issac Kelly
+28  A: 

That's because when you initialize a new Date, it comes with today's date, so today is Oct 30 2008, then you set the month to February, so there is no February 30, so set first the day, then the month, and then the year:

d = new Date();
d.setDate(15);                    
d.setMonth(1);
d.setFullYear(2009);

But as @Jason W, says it's better to use the Date constructor:

new Date(year, month, date [, hour, minute, second, millisecond ]);
CMS
What if it's currently February and you call d.setDate(30)?
Greg Hewgill
Everything's fine as long as it's a double-plus leap year.
Michael Burr
If the year is not leap, so February has 28 days, should give you March 02, if the year is leap, March 01
CMS
CMS: I think you're missing the point. If d.setDate(30) were to set the date to March 2 (or 1, whatever), and then d.setMonth(0) for January, then you'd end up with January 2 and not January 30 as intended.
Greg Hewgill
Yes I noticed, I think it's better to initialize the date using the constructor as Jason says, new Date(year, month, day [, hour, minute, second, millisecond])
CMS
You should probably update your answer to mention this. While your solution works for the 15th, it won't work for the 29th or later in every case.
Greg Hewgill
+24  A: 

It's probably best to construct a Date object in one step to avoid the Date object being in an ambiguous or invalid state:

d = new Date(2009, 1, 15);
Jason Weathered
A: 

After a bunch of testing in FF3 on XP with Firebug, here are the things I can tell you

  • Calling Date.setDate() after calling Date.setMonth() will generate this odd behavior.
  • Date.setMonth() forces the timezone to be CST (or, some non DST-aware zone)
  • Date.setDate() forces the timezone to be CDT (or, some DST-aware zone)

So, there's definitely something wonky going on with setMonth() and setDate() in respect to the timezone.

The only solution I can offer is this: Set the date before you set the month.

Peter Bailey