1

Can someone explain me the output http://jsfiddle.net/mark69_fnd/NhuLe/ produces?

new Date('2012-07-01') == Sat Jun 30 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-07-09') == Sun Jul 08 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-07-10') == Mon Jul 09 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-07-31') == Mon Jul 30 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-08-1') == Wed Aug 01 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-08-9') == Thu Aug 09 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-08-10') == Thu Aug 09 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-08-31') == Thu Aug 30 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-09-1') == Sat Sep 01 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-09-9') == Sun Sep 09 2012 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-09-10') == Sun Sep 09 2012 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2012-12-09') == Sat Dec 08 2012 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2012-12-31') == Sun Dec 30 2012 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-01-01') == Mon Dec 31 2012 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-01-09') == Tue Jan 08 2013 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-02-09') == Fri Feb 08 2013 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-03-09') == Fri Mar 08 2013 19:00:00 GMT-0500 (Eastern Standard Time)
new Date('2013-04-09') == Mon Apr 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-05-09') == Wed May 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-06-09') == Sat Jun 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-07-09') == Mon Jul 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-08-09') == Thu Aug 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2013-09-09') == Sun Sep 08 2013 20:00:00 GMT-0400 (Eastern Daylight Time)

I am interested to understand how it decides to compute the day. Please, note the difference between 2012-07-09, 2012-08-9 and 2013-08-09.

I ran it on Chrome.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
mark
  • 59,016
  • 79
  • 296
  • 580

2 Answers2

4

This is a very interesting, and subtle, question.

The reason is that some of your dates are in the ISO-8601-like format defined in the specification, and so are parsed as GMT, but others are not, and so they fall back on non-standard date parsing, which appears to be (in Chrome) using local time instead.

The date string 2012-07-01 conforms to the format specified in Section 15.9.1.15, and so according to the rules of that section, it is parsed in timezone Z (GMT). Then you output it and it's output in local time, four hours or so earlier, and so the date changes as the original value (having no time part) is at midnight.

The date string 2012-08-1 does not conform to that format (it needs a 0 before the 1). This takes us out of the land of specified behavior. The Date constructor, when given a string, follows the same rules as Date.parse, which are defined in Section 15.9.4.2, which says amongst other things:

The function first attempts to parse the format of the String according to the rules called out in Date Time String Format (15.9.1.15). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.

(My emphasis)

The moral of this story is: Stick to specified formats. :-)

But a side note on that: The date/time format defined in the spec is relatively new (as of ES5, about three years ago). Prior to that, there was no defined date/time format that the Date constructor (or Date parse) was required to parse. It just had to be able to parse whatever Date#toString spat out, but what that was was implementation-specific. And older browsers will indeed fail to parse 2012-08-01. Although it's not specified, nearly all browsers (every one I've ever tested) will parse 2012/08/01, though. Of course, now I want to go back and see what time zone they use (and check whether they all use the same one)...

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • @mark: Yeah. JavaScript's date stuff isn't great. It used to be even worse (see my edit), but it still has a ways to go... :-) – T.J. Crowder Dec 01 '12 at 12:05
  • Is there a library that makes working with dates a sane business? I see lots of references to datejs, but it was last updated 5 years ago, so I am not sure if it is still good. – mark Dec 01 '12 at 12:07
  • 1
    @mark: Yeah, DateJS is sadly quite out of date *(ugh, sorry, that was not intentional)* and has bugs parsing dates at midnight. There's [Moment.js](http://momentjs.com), which looks pretty good, though I haven't used it extensively. – T.J. Crowder Dec 01 '12 at 12:08
0

new Date('2012-07-01') means that you are providing date in *GMT 000*0 timezone.

But when it displays you the date it does the same in your browser timezone(which is GMT -400 in your case).

Thats is the reason that you see all the timings to be 20:00.

Ankur
  • 12,676
  • 7
  • 37
  • 67
  • I thought it was a GMT vs. timezone thing as well, but how do you explain `new Date('2012-08-1') == Wed Aug 01 2012 00:00:00 GMT-0400 (Eastern Daylight Time)`? Shouldn't that have ended up on July 31 as well? – T.J. Crowder Dec 01 '12 at 11:52
  • new Date('2013-04-09') == Tue Apr 09 2013 01:00:00 GMT+0100 (BST) new Date('2013-04-9') == Tue Apr 09 2013 00:00:00 GMT+0100 (BST) And why is that the first example above has an extra hour added to it? This is a bit confusing :/ – robertp Dec 01 '12 at 11:58