8

tl;dr - When I try to create a new Date object with a YYYY-MM-DD format date string, it gives me an incorrect date (yesterday). Why?

I've written the following test code to help me demonstrate the problem I'm perceiving:

var dateConfig = {weekday: "long", year: "numeric", month: "long", day: "numeric"},
    dates = [
        "01/21/2014",
        "01-21-2014",
        "2014/01/21",
        "2014-01-21"
    ];

for (var i = 0; i < dates.length; ++ i) {
    var date = new Date(dates[i]);
    console.log(date.toLocaleDateString("en-US", dateConfig));
}

Link to see for yourself: http://s.codepen.io/AdrianTP/fullpage/prKyf

Chrome 31.0.1650.63 m returns the following in the console:

Tuesday, January 21, 2014
Tuesday, January 21, 2014
Tuesday, January 21, 2014
Monday, January 20, 2014 

Firefox 26.0 returns the following in the console:

"Tuesday, January 21, 2014"
"Invalid Date"
"Tuesday, January 21, 2014"
"Monday, January 20, 2014"

Even Internet Explorer 8 gets most of it right, returning the following in the console:

"Tuesday, January 21, 2014"
"Tuesday, January 21, 2014"
"Tuesday, January 21, 2014"
"NaN"

In short, I am aware that date handling between browsers is inconsistent (dates[2] in Chrome and Firefox differ, and dates[3] just outright breaks in IE 8), but that is not my question.

My question is:

Why would Chrome and Firefox return yesterday's date for a YYYY-MM-DD formatted date string specifying today's date, when it works fine with slashes?

Another question:

Is this a known issue?

I have not encountered it before, and was unable to find any documentation of the issue, nor documentation of the Date() object which would indicate to me that such string-transformation would occur so regularly-irregular. Does anyone out there have experience with this and maybe an explanation or a link to one that I haven't found? I could just be using the wrong search terms here...

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Adrian
  • 727
  • 1
  • 9
  • 17
  • other related topics: https://stackoverflow.com/questions/35448343/why-isnt-2016-02-16-equal-to-2016-02-16-0000 https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results – V. Rubinetti Dec 22 '18 at 20:22

1 Answers1

6

The JavaScript standard stipulates that the "official" supported format is ISO 8601, which looks like YYYY-MM-DDTHH:mm:ss.sssZ. (Z is the time zone offset specified as “Z” (for UTC) or either “+” or “-” followed by a time expression HH:mm.) Though the format does include a time zone offset, Firefox and Chrome (and I think IE) don't pay attention, and always interpret ISO 8601 dates as UTC.

Any implementation can accept other formats too, and the browsers aren't in sync at present. Firefox will accept RFC 2822 dates, other browsers don't.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 4
    Thanks for the ISO/RFC numbers. They spurred additional research on my part, which brought me to an understanding that it's assuming I'm entering the date in the expanded ISO-8601 format, which means when I enter `new Date("2014-01-23")` I'm actually entering `new Date("2014-01-23T00:00:00")` which gets converted to my computer's time zone (GMT-0600), thus causing me to actually be referring to yesterday's date. `2014-01-23T00:00:00` in GMT is equivalent to `2014-01-22T18:00:00` in CST (GMT-0600). Because no time zone was specified for the date string I entered, it assumed GMT. Thank you! – Adrian Jan 23 '14 at 22:20
  • @Adrian yup, that's exactly right! I should have added that info but I was in a hurry when I was answering that :) – Pointy Jan 23 '14 at 22:21
  • @Adrian—I think you assume too much. ;-) ECMA-262 as of ed 5.1 (2011) says that "2014-01-23" should be treated as UTC (contrary to ISO 8601), I think all the majors at least do that now. However, 2014-01-01T00:00:00 should be treated as local (except Safari treats it as UTC). Just don't use the built–in parser, it will get you into trouble. – RobG Apr 21 '20 at 00:45