Date Time String Format: default time zone difference from ES5 not web-compatible #87

Closed
ajklein opened this Issue Oct 15, 2015 · 35 comments

Comments

Projects
None yet
8 participants
@ajklein
Contributor

ajklein commented Oct 15, 2015

In Chrome 46, we shipped a change to date formatting per ES2015 that a missing time zone should be treated as local time (where in ES5 it was treated as UTC). See https://code.google.com/p/chromium/issues/detail?id=543320 for details, in particular comment 5 (which lays out the exact difference).

Given the breakage, and that no other browsers seems to have shipped this change, it seems like the easiest thing to do would be to revert to the ES5 behavior. But I'm not sure what prompted the change in the first place, so it's hard to weigh such a change.

@anba

This comment has been minimized.

Show comment
Hide comment
@anba

anba Oct 15, 2015

Contributor

But I'm not sure what prompted the change in the first place, so it's hard to weigh such a change.

It was changed to local time to match ISO-8601 (https://bugs.ecmascript.org/show_bug.cgi?id=112).

Contributor

anba commented Oct 15, 2015

But I'm not sure what prompted the change in the first place, so it's hard to weigh such a change.

It was changed to local time to match ISO-8601 (https://bugs.ecmascript.org/show_bug.cgi?id=112).

@zloirock zloirock referenced this issue in zloirock/core-js Oct 15, 2015

Open

ES6 Date parsing #63

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 15, 2015

Member

Ugh, this is sad. On the one hand, not following ISO-8601 is super confusing and bad, but if we can't do it we can't do it.

@ajklein any way to quantify the breakage any more? Is it sufficient that you are reverting this change and going back to old (presumably interoperable) behavior?

Member

bterlson commented Oct 15, 2015

Ugh, this is sad. On the one hand, not following ISO-8601 is super confusing and bad, but if we can't do it we can't do it.

@ajklein any way to quantify the breakage any more? Is it sufficient that you are reverting this change and going back to old (presumably interoperable) behavior?

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 16, 2015

Also, please consider that there are good reasons for this change.

A major source of confusion amongst web developers (more StackOverflow posts than I can count) is:

new Date("2015-10-15")
// Wed Oct 14 2015 17:00:00 GMT-0700 (Pacific Daylight Time)

Why is the date not what I passed in? Even worse, calling functions like toDateString masks the time component, so it just looks like "Wed Oct 14 2015", even though you passed in 2015-10-14. Of course, this is only if I'm West of UTC. If I'm on the other side of the world it works. So apps get developed often in the Eastern hemisphere (positive offsets) and the bug is masked until users from the Western hemisphere (negative offsets) use it.

With the new spec in place, this problem goes away.

new Date("2015-10-15")
// Thu Oct 15 2015 00:00:00 GMT-0700 (Pacific Daylight Time)

ALSO consider HTML5 interaction. The datetime-local input type provides a value such as "2015-10-15T01:23:45". It is ISO8601 compliant, and is intended to be interpreted as local time - not as UTC.

I'm sure plenty of people are trying to use these together, as in:

<input type="datetime-local" id="foo">
var value = document.getElementById("foo").value;
var dt = new Date(value);

Without this change they'd have to do some string manipulation of the value first. Indeed, people get hung up on this all the time and either manipulate the string, or resort to a library (like moment.js).

mj1856 commented Oct 16, 2015

Also, please consider that there are good reasons for this change.

A major source of confusion amongst web developers (more StackOverflow posts than I can count) is:

new Date("2015-10-15")
// Wed Oct 14 2015 17:00:00 GMT-0700 (Pacific Daylight Time)

Why is the date not what I passed in? Even worse, calling functions like toDateString masks the time component, so it just looks like "Wed Oct 14 2015", even though you passed in 2015-10-14. Of course, this is only if I'm West of UTC. If I'm on the other side of the world it works. So apps get developed often in the Eastern hemisphere (positive offsets) and the bug is masked until users from the Western hemisphere (negative offsets) use it.

With the new spec in place, this problem goes away.

new Date("2015-10-15")
// Thu Oct 15 2015 00:00:00 GMT-0700 (Pacific Daylight Time)

ALSO consider HTML5 interaction. The datetime-local input type provides a value such as "2015-10-15T01:23:45". It is ISO8601 compliant, and is intended to be interpreted as local time - not as UTC.

I'm sure plenty of people are trying to use these together, as in:

<input type="datetime-local" id="foo">
var value = document.getElementById("foo").value;
var dt = new Date(value);

Without this change they'd have to do some string manipulation of the value first. Indeed, people get hung up on this all the time and either manipulate the string, or resort to a library (like moment.js).

@ajklein

This comment has been minimized.

Show comment
Hide comment
@ajklein

ajklein Oct 16, 2015

Contributor

Looping in @ulan, who's been handling the V8 implementation side of this.

Contributor

ajklein commented Oct 16, 2015

Looping in @ulan, who's been handling the V8 implementation side of this.

@ulan

This comment has been minimized.

Show comment
Hide comment
@ulan

ulan Oct 16, 2015

To clarify why we are reverting the change in V8:
the original change was landed under the assumption that Firefox and IE already default to local timezone (see https://code.google.com/p/v8/issues/detail?id=4242, http://crbug.com/543320), so the risk of breaking the web was considered low. Unfortunately, we checked parsing only for the "YYYY-MM-DDT00:00:00" and didn't know that Firefox and IE return different result for "YYYY-MM-DD".

We are reverting the change because it turned out to be much more riskier than we thought: Chrome 46 is inconsistent with Firefox, IE, and Safari in parsing of "YYYY-MM-DD", and we are getting bug reports about it.

Andreas and Adam will raise this issue in TC39.

ulan commented Oct 16, 2015

To clarify why we are reverting the change in V8:
the original change was landed under the assumption that Firefox and IE already default to local timezone (see https://code.google.com/p/v8/issues/detail?id=4242, http://crbug.com/543320), so the risk of breaking the web was considered low. Unfortunately, we checked parsing only for the "YYYY-MM-DDT00:00:00" and didn't know that Firefox and IE return different result for "YYYY-MM-DD".

We are reverting the change because it turned out to be much more riskier than we thought: Chrome 46 is inconsistent with Firefox, IE, and Safari in parsing of "YYYY-MM-DD", and we are getting bug reports about it.

Andreas and Adam will raise this issue in TC39.

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 16, 2015

@ulan - Thanks, I didn't realize that IE and FF had already switched to ES6 behavior for YYYY-MM-DDTHH:MM:SS. I hope that the parts being reverted do not undo this part. That at least addresses my concern about the datetime-local HTML5 type.

However - I still think it's the right ting to do to also switch YYYY-MM-DD representations to ES6 behavior. I'm really not sure why FF and IE have not done that. Perhaps they just haven't gotten around to it yet? I don't see why Chrome can't go first and have others follow suit.

Consider:

  • There's still the HTML5 date input type, which my above example still applies. (Users in the western hemisphere will get dates one day earlier than the one selected.)
  • ES6 § 20.3.1.16 is very clear that the format includes date-only forms, including the complete representation (YYYY-MM-DD) and incomplete representations (YYYY-MM and YYYY). The wording about using local time is part of this same section, so I don't understand why it should be selectively applied to YYYY-MM-DDTHH:MM:SS only.
  • ISO8601 is also very specific as to what it considers a "complete representation" vs implementations with "reduced accuracy". Examples in ISO8601:2004(E) § B1.1.1 show YYYY-MM-DD as a complete representation of a calendar date. Examples of complete date and time representations are in § B1.3. I bring this up because sometimes people mistakenly believe that if it doesn't contain a T that it's not ISO8601.

mj1856 commented Oct 16, 2015

@ulan - Thanks, I didn't realize that IE and FF had already switched to ES6 behavior for YYYY-MM-DDTHH:MM:SS. I hope that the parts being reverted do not undo this part. That at least addresses my concern about the datetime-local HTML5 type.

However - I still think it's the right ting to do to also switch YYYY-MM-DD representations to ES6 behavior. I'm really not sure why FF and IE have not done that. Perhaps they just haven't gotten around to it yet? I don't see why Chrome can't go first and have others follow suit.

Consider:

  • There's still the HTML5 date input type, which my above example still applies. (Users in the western hemisphere will get dates one day earlier than the one selected.)
  • ES6 § 20.3.1.16 is very clear that the format includes date-only forms, including the complete representation (YYYY-MM-DD) and incomplete representations (YYYY-MM and YYYY). The wording about using local time is part of this same section, so I don't understand why it should be selectively applied to YYYY-MM-DDTHH:MM:SS only.
  • ISO8601 is also very specific as to what it considers a "complete representation" vs implementations with "reduced accuracy". Examples in ISO8601:2004(E) § B1.1.1 show YYYY-MM-DD as a complete representation of a calendar date. Examples of complete date and time representations are in § B1.3. I bring this up because sometimes people mistakenly believe that if it doesn't contain a T that it's not ISO8601.
@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 16, 2015

Also consider that in in v8-4242, the reason the test failed was interpreted wrong in the discussion.

In the discussion, its thought that new Date(1970, 0, 1, 0, 0, 0, 0) was incorrectly switched from UTC to local interpretation, when actually passing by argument has always been interpreted as local time, and isn't part of the parsing behavior changes for ES6.

It's actually the other date object in the test new Date("1970") that was being interpreted differently. It would fall under the incomplete representations mentioned in both ES6 and ISO8601, and indeed should be interpreted as local time. Interpreting it as UTC again means that folks in the Western hemisphere are getting different values than those in the Eastern hemisphere.

Consider new Date("1970").getFullYear() which returns 1970 in all browsers for users in the Eastern hemisphere, but returns 1969 for browsers in the Western hemisphere under ES5 rules. Under ES6 rules, both would get 1970.

mj1856 commented Oct 16, 2015

Also consider that in in v8-4242, the reason the test failed was interpreted wrong in the discussion.

In the discussion, its thought that new Date(1970, 0, 1, 0, 0, 0, 0) was incorrectly switched from UTC to local interpretation, when actually passing by argument has always been interpreted as local time, and isn't part of the parsing behavior changes for ES6.

It's actually the other date object in the test new Date("1970") that was being interpreted differently. It would fall under the incomplete representations mentioned in both ES6 and ISO8601, and indeed should be interpreted as local time. Interpreting it as UTC again means that folks in the Western hemisphere are getting different values than those in the Eastern hemisphere.

Consider new Date("1970").getFullYear() which returns 1970 in all browsers for users in the Eastern hemisphere, but returns 1969 for browsers in the Western hemisphere under ES5 rules. Under ES6 rules, both would get 1970.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 16, 2015

Member

I don' think there's any doubt that following ISO8601 (and ES6) would be the ideal here. The problem is that browsers can't break huge swaths of the web as much as we'd like to.

I think the next step here is to see if we can quantify how many sites are at risk for being broken (and how many sites might actually have latent bugs fixed). This will be good information to share with the committee.

Member

bterlson commented Oct 16, 2015

I don' think there's any doubt that following ISO8601 (and ES6) would be the ideal here. The problem is that browsers can't break huge swaths of the web as much as we'd like to.

I think the next step here is to see if we can quantify how many sites are at risk for being broken (and how many sites might actually have latent bugs fixed). This will be good information to share with the committee.

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 16, 2015

Isn't the web already broken with this regard? Date parsing has long been a thorn in the side of JavaScript developers, and the advice for a long time now has been "don't rely on it to behave in any specific manner". I'm sure that's not practical from a spec perspective, but that's reality.

If it were to change as specified, the effect would be limited to those applications that have not already encountered the current behavior's adverse effects. In other words, if I'm using an app with new Date("2015-10-16") then if I have users in the Western hemisphere I will have already encountered the problem of it being interpreted as UTC, and likely found a workaround (such as parsing the string myself with regex or split, or using a library like moment.js.

If I don't have users in the Western hemisphere, and if I mistakenly believed I was getting local time before, then I will see no adverse effects. new Date("2015-01-01").getFullYear() === 2015.

It's only if I explicitly depended on the ambiguous input to be interpreted as UTC that I will see new breakage, and only for Eastern hemisphere users. new Date("2015-01-01").getUTCFullYear() === 2015 under ES5, new Date("2015-01-01").getUTCFullYear() === 2014 under ES6.

mj1856 commented Oct 16, 2015

Isn't the web already broken with this regard? Date parsing has long been a thorn in the side of JavaScript developers, and the advice for a long time now has been "don't rely on it to behave in any specific manner". I'm sure that's not practical from a spec perspective, but that's reality.

If it were to change as specified, the effect would be limited to those applications that have not already encountered the current behavior's adverse effects. In other words, if I'm using an app with new Date("2015-10-16") then if I have users in the Western hemisphere I will have already encountered the problem of it being interpreted as UTC, and likely found a workaround (such as parsing the string myself with regex or split, or using a library like moment.js.

If I don't have users in the Western hemisphere, and if I mistakenly believed I was getting local time before, then I will see no adverse effects. new Date("2015-01-01").getFullYear() === 2015.

It's only if I explicitly depended on the ambiguous input to be interpreted as UTC that I will see new breakage, and only for Eastern hemisphere users. new Date("2015-01-01").getUTCFullYear() === 2015 under ES5, new Date("2015-01-01").getUTCFullYear() === 2014 under ES6.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 16, 2015

Member

There may in fact be latent bugs in code like new Date("2015-01-01") that taking this change would fix, but we don't have evidence of that. What we do have evidence of is actual people who read the documentation, understood that 2015-01-01 would parse in UTC, and are using the API accordingly. That is why making this change in implementations seems risky and why v8 is (rightfully) worried about web compat.

Member

bterlson commented Oct 16, 2015

There may in fact be latent bugs in code like new Date("2015-01-01") that taking this change would fix, but we don't have evidence of that. What we do have evidence of is actual people who read the documentation, understood that 2015-01-01 would parse in UTC, and are using the API accordingly. That is why making this change in implementations seems risky and why v8 is (rightfully) worried about web compat.

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 16, 2015

Ok, I can respect that. In general, is ES5 to ES6 supposed to be non-breaking? Or is there a common way that breaking changes are supposed to be communicated to developers as they are implemented?

mj1856 commented Oct 16, 2015

Ok, I can respect that. In general, is ES5 to ES6 supposed to be non-breaking? Or is there a common way that breaking changes are supposed to be communicated to developers as they are implemented?

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 16, 2015

Member

ES5 to ES6 should not cause major breakage although some breakage is impossible to avoid. Breaking changes are tabulated in Annex E though I note this one is absent...

Member

bterlson commented Oct 16, 2015

ES5 to ES6 should not cause major breakage although some breakage is impossible to avoid. Breaking changes are tabulated in Annex E though I note this one is absent...

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 16, 2015

Looks like Annex D has it.

mj1856 commented Oct 16, 2015

Looks like Annex D has it.

@adamhaile

This comment has been minimized.

Show comment
Hide comment
@adamhaile

adamhaile Oct 17, 2015

I'm the original reporter to Chromium. @bterlson described exactly our situation. The app that was affected is a resource scheduling app with a global userbase. The resource being scheduled charges in the thousands USD per hour. We care a lot about timezones. We read the ES5.1 spec carefully and implemented accordingly.

We use the YYYY-MM-DD format plus the Olson timezone database to determine the exact start and end of day at a number of locations around the globe. When Chrome 46 started rolling out, we immediately started receiving reports from users that our schedule was off. We were unable to repro until one of our devs restarted Chrome, which triggered the autoupdate.

From the linked comments on bugs.ecmascript.org, it looks like the original plan was to clear up the behavior in a 5.1 Errata back in late 2011 or early '12. That didn't happen, and after four years browsers and unknown amounts of user code now follow the 5.1 behavior. I think TC39 missed their chance to change this one. The value of making Date a tad bit more conformant with ISO8601 seems merely pedantic when you compare it to breaking working code. I don't think TC39 should go full Linus (https://lkml.org/lkml/2012/12/23/75), but changes like this raise questions about the maturity of the platform and the spec process.

Incidentally, from our perspective, UTC is a far saner default than browser local. For any app trying to share dates between users in more than one timezone, which would be most of them, the browser local timezone is useless. If, as @mj1856 seems concerned, novice programmers are surprised by this behavior, it's only because they haven't learned how to think about time in a networked environment.

We would love (oh god yes) to have a better datetime system in Javascript. It seems that datetime handling in major systems has gone through three stages: an early one where datetime objects had no notion of timezone, an intermediate one where a bit flag was added to distinguish between UTC and an unspecified "local" timezone, and a modern one where all datetime objects specify an explicit timezone. Javascript is in the middle stage. We'd love to see a new datetime class added that fulfilled the last possibility. It would be able to conform to far more of the ISO8601 spec to boot.

I'm the original reporter to Chromium. @bterlson described exactly our situation. The app that was affected is a resource scheduling app with a global userbase. The resource being scheduled charges in the thousands USD per hour. We care a lot about timezones. We read the ES5.1 spec carefully and implemented accordingly.

We use the YYYY-MM-DD format plus the Olson timezone database to determine the exact start and end of day at a number of locations around the globe. When Chrome 46 started rolling out, we immediately started receiving reports from users that our schedule was off. We were unable to repro until one of our devs restarted Chrome, which triggered the autoupdate.

From the linked comments on bugs.ecmascript.org, it looks like the original plan was to clear up the behavior in a 5.1 Errata back in late 2011 or early '12. That didn't happen, and after four years browsers and unknown amounts of user code now follow the 5.1 behavior. I think TC39 missed their chance to change this one. The value of making Date a tad bit more conformant with ISO8601 seems merely pedantic when you compare it to breaking working code. I don't think TC39 should go full Linus (https://lkml.org/lkml/2012/12/23/75), but changes like this raise questions about the maturity of the platform and the spec process.

Incidentally, from our perspective, UTC is a far saner default than browser local. For any app trying to share dates between users in more than one timezone, which would be most of them, the browser local timezone is useless. If, as @mj1856 seems concerned, novice programmers are surprised by this behavior, it's only because they haven't learned how to think about time in a networked environment.

We would love (oh god yes) to have a better datetime system in Javascript. It seems that datetime handling in major systems has gone through three stages: an early one where datetime objects had no notion of timezone, an intermediate one where a bit flag was added to distinguish between UTC and an unspecified "local" timezone, and a modern one where all datetime objects specify an explicit timezone. Javascript is in the middle stage. We'd love to see a new datetime class added that fulfilled the last possibility. It would be able to conform to far more of the ISO8601 spec to boot.

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 17, 2015

@curveship - Understood, and thanks for the perspective. But why not address the problem within your app? If the issue is that you'd like the app to interpret a YYYY-MM-DD value as if it were midnight UTC on that date, then why not be explicit and use YYYY-MM-DDT00:00:00Z instead? It seems rather odd to me to take a dependency on the implied behavior.

mj1856 commented Oct 17, 2015

@curveship - Understood, and thanks for the perspective. But why not address the problem within your app? If the issue is that you'd like the app to interpret a YYYY-MM-DD value as if it were midnight UTC on that date, then why not be explicit and use YYYY-MM-DDT00:00:00Z instead? It seems rather odd to me to take a dependency on the implied behavior.

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 17, 2015

WRT the three stages, actually the EcmaScript Date object is in a strange limbo where it still seems to think that "one object to rule them all" is appropriate (SRP anyone?) Date is misnamed, it's really an instantaneous point in time backed by timestamp. It would be more accurate to call it a DateTime, or an Instant, however it also likes to trick us with the duality of pretending to be local when under the hood it's not. It has lied to us in the past about which set of DST rules are in effect (thankfully fixed in ES6 and ECMA-402). It has strange edge cases around DST transitions, which are also inconsistent across implementations. It still reeks of it's similarity to java.util.Date and it doesn't appear to be getting a whole lot better. And don't even get me started about it being mutable. To me, it's at stage 1.05. Not quite even close to stage 2. If a redesign were ever in the works, it should just deprecate the whole object and model itself after the new java.time package from Java 8. Now there is a well thought-out implementation. </rant>

mj1856 commented Oct 17, 2015

WRT the three stages, actually the EcmaScript Date object is in a strange limbo where it still seems to think that "one object to rule them all" is appropriate (SRP anyone?) Date is misnamed, it's really an instantaneous point in time backed by timestamp. It would be more accurate to call it a DateTime, or an Instant, however it also likes to trick us with the duality of pretending to be local when under the hood it's not. It has lied to us in the past about which set of DST rules are in effect (thankfully fixed in ES6 and ECMA-402). It has strange edge cases around DST transitions, which are also inconsistent across implementations. It still reeks of it's similarity to java.util.Date and it doesn't appear to be getting a whole lot better. And don't even get me started about it being mutable. To me, it's at stage 1.05. Not quite even close to stage 2. If a redesign were ever in the works, it should just deprecate the whole object and model itself after the new java.time package from Java 8. Now there is a well thought-out implementation. </rant>

@adamhaile

This comment has been minimized.

Show comment
Hide comment
@adamhaile

adamhaile Oct 17, 2015

@mj1856 If you're asking what we do now, yes, we had a workaround in prod before I posted the bug report. First things first! :) We now append "Z" to the YYYY-MM-DD dates before parsing.

There's lots of ambiguous situations with Date string parsing in JS, but in the ES5.1 spec, YYYY-MM-DD is given specific semantics. That's one of the reasons we selected it. We also validated at the time (I think this was about 2.5 years ago?) that those semantics were supported by browsers.

As for why we didn't use something like YYYY-MM-DDT00:00:00Z, our app actually uses YYYY-MM-DD plus an Olson timezone specifier to represent a "day" in a given location. It's only when we go to convert that tuple to specific start/end times that we relied upon the parsing behavior. Since YYYY-MM-DD was supported with specific semantics, there was no reason at the time to pad with T00:00:00Z.

@mj1856 If you're asking what we do now, yes, we had a workaround in prod before I posted the bug report. First things first! :) We now append "Z" to the YYYY-MM-DD dates before parsing.

There's lots of ambiguous situations with Date string parsing in JS, but in the ES5.1 spec, YYYY-MM-DD is given specific semantics. That's one of the reasons we selected it. We also validated at the time (I think this was about 2.5 years ago?) that those semantics were supported by browsers.

As for why we didn't use something like YYYY-MM-DDT00:00:00Z, our app actually uses YYYY-MM-DD plus an Olson timezone specifier to represent a "day" in a given location. It's only when we go to convert that tuple to specific start/end times that we relied upon the parsing behavior. Since YYYY-MM-DD was supported with specific semantics, there was no reason at the time to pad with T00:00:00Z.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 22, 2015

Member

I think it's clear we have to revert this change for now. Considering there wasn't much committee involvement in making this change in the first place, I'm just going to fix it rather than adding the "needs-consensus" label.

Member

bterlson commented Oct 22, 2015

I think it's clear we have to revert this change for now. Considering there wasn't much committee involvement in making this change in the first place, I'm just going to fix it rather than adding the "needs-consensus" label.

@anba

This comment has been minimized.

Show comment
Hide comment
@anba

anba Oct 22, 2015

Contributor

I think it's clear we have to revert this change for now.

Revert the change for date-only forms or also for date-time forms? The latter were always parsed as local time in Firefox (changeset, bugzilla), so reverting this to UTC as misspecified in ES5 could lead to extra churn for Firefox (+ Add-ons), FirefoxOS, etc.

Contributor

anba commented Oct 22, 2015

I think it's clear we have to revert this change for now.

Revert the change for date-only forms or also for date-time forms? The latter were always parsed as local time in Firefox (changeset, bugzilla), so reverting this to UTC as misspecified in ES5 could lead to extra churn for Firefox (+ Add-ons), FirefoxOS, etc.

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 22, 2015

I agree with @anba - if it's going to be reverted, it should be for the date-only forms as YYYY-MM-DDTHH:MM:SS forms have been interpreted as local time in many browsers for some time.

Though I do think its a mistake to revert it, considering HTM5 date input type and the Date object are often used in conjunction.

I've personally never encountered a situation where a YYYY-MM-DD value is actually intended to be interpreted as midnight UTC on that date.

mj1856 commented Oct 22, 2015

I agree with @anba - if it's going to be reverted, it should be for the date-only forms as YYYY-MM-DDTHH:MM:SS forms have been interpreted as local time in many browsers for some time.

Though I do think its a mistake to revert it, considering HTM5 date input type and the Date object are often used in conjunction.

I've personally never encountered a situation where a YYYY-MM-DD value is actually intended to be interpreted as midnight UTC on that date.

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Oct 22, 2015

Member

@bterlson I not so sure about your assertion about "committee involvement". As this was specifically reported 2011 as a 5.1 bug and subsequently marked as a 5.1errata item, I think it probably was discussed at a committee meeting in 2011. But it's hard to find reliable meeting notes going back that far.

Given that there already are deployed implementation differences, the long term pain, and the fact that it has already been identify as a specification error, I think it deserves discussion at a meeting.

Member

allenwb commented Oct 22, 2015

@bterlson I not so sure about your assertion about "committee involvement". As this was specifically reported 2011 as a 5.1 bug and subsequently marked as a 5.1errata item, I think it probably was discussed at a committee meeting in 2011. But it's hard to find reliable meeting notes going back that far.

Given that there already are deployed implementation differences, the long term pain, and the fact that it has already been identify as a specification error, I think it deserves discussion at a meeting.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 22, 2015

Member

Ahh ok, I did a search and came up dry, but sometimes I forget we didn't always have @rwaldron :-P I'm fine discussing at the committee meeting. Given that we seem to have evidence that changing the behavior of the date-only form will break the web, I can't imagine the committee would specify anything other than what browsers will implement, but I'll bring it up anyway.

To be clear, though, by revert I mean specifically for the date-only pattern and not the date-time pattern. Today afaict all browsers agree that the former is interpreted as UTC and the latter local time.

Member

bterlson commented Oct 22, 2015

Ahh ok, I did a search and came up dry, but sometimes I forget we didn't always have @rwaldron :-P I'm fine discussing at the committee meeting. Given that we seem to have evidence that changing the behavior of the date-only form will break the web, I can't imagine the committee would specify anything other than what browsers will implement, but I'll bring it up anyway.

To be clear, though, by revert I mean specifically for the date-only pattern and not the date-time pattern. Today afaict all browsers agree that the former is interpreted as UTC and the latter local time.

@bterlson bterlson added needs consensus and removed question labels Oct 22, 2015

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 22, 2015

Is this to apply to all date-only forms, including YYYY-MM-DD, YYYY-MM, and YYYY (as called out by 20.3.1.16). Are we talking about splitting that section into two such that all "date only forms" have UTC behavior while "all date-time forms" take local time behavior? If so, the section needs significant rewording.

Actually, if you read that section very literally, it's only stated that the offset-absent=local rule applies to date-time forms. It actually doesn't say anything at all about date-only forms without an offset - or that they can even have one.

Of course, all of this stems from trying to fit date-only data into a date-time data type.

BTW - Chrome reverted the change that kicked off this discussion, but in the process has switched the YYYY-MM-DDTHH:MM:SS to UTC behavior also...

mj1856 commented Oct 22, 2015

Is this to apply to all date-only forms, including YYYY-MM-DD, YYYY-MM, and YYYY (as called out by 20.3.1.16). Are we talking about splitting that section into two such that all "date only forms" have UTC behavior while "all date-time forms" take local time behavior? If so, the section needs significant rewording.

Actually, if you read that section very literally, it's only stated that the offset-absent=local rule applies to date-time forms. It actually doesn't say anything at all about date-only forms without an offset - or that they can even have one.

Of course, all of this stems from trying to fit date-only data into a date-time data type.

BTW - Chrome reverted the change that kicked off this discussion, but in the process has switched the YYYY-MM-DDTHH:MM:SS to UTC behavior also...

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 22, 2015

Member

All date-only forms are interoperably interpreted as UTC and all date-time forms are interoperably interpreted as local time. Or at least were, modulo Chrome's plans here. @ajklein can you comment?

Member

bterlson commented Oct 22, 2015

All date-only forms are interoperably interpreted as UTC and all date-time forms are interoperably interpreted as local time. Or at least were, modulo Chrome's plans here. @ajklein can you comment?

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 22, 2015

I'd also like to hear any use case for date-only as midnight UTC - other than, "that's how we had it before". Thanks.

mj1856 commented Oct 22, 2015

I'd also like to hear any use case for date-only as midnight UTC - other than, "that's how we had it before". Thanks.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 22, 2015

Member

And other than the aforementioned "running code on the internet without breaking" use case?

Member

bterlson commented Oct 22, 2015

And other than the aforementioned "running code on the internet without breaking" use case?

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 22, 2015

Looking back into history:

  • ES1 - ES3 did not mention YYYY-MM-DD format at all.
  • ES5 has this section, but does not specify anything about behavior when the offset is not present.
  • ES5.1 adds the wording about an absent offset being Z - but only for the date-time formats. This was interpreted wrong and implemented in all browsers as local time.
  • ES6 changes the behavior to local time, but again only for date-time formats. This aligns the spec to the implementations of date-time formats, but still doesn't say anything either way about date-only formats.

So, what we're looking for clarification and consensus on, is whether the behavior mentioned should apply to all formats in that section rather than just the date-time formats, or if there's differing behavior for the date-only types. There needs to be spec correction either way.

Also, just thought I'd spin up some VMs and test old browsers. IE9 RTM shipped without support for either format. new Date('2015-01-01') on IE9 RTM gives Invalid Date. Anecdotally, there's this chart pointed at often, which contradicts this, so it's possible an update to IE9 fixed it. I'm testing more to see if I can find out.

I know for sure it was in IE10, so at least for IE it was sometime in 2012 that this format was at all usable with the Date object.

If I can figure out where to get old FF and Chrome I'll test those too...

mj1856 commented Oct 22, 2015

Looking back into history:

  • ES1 - ES3 did not mention YYYY-MM-DD format at all.
  • ES5 has this section, but does not specify anything about behavior when the offset is not present.
  • ES5.1 adds the wording about an absent offset being Z - but only for the date-time formats. This was interpreted wrong and implemented in all browsers as local time.
  • ES6 changes the behavior to local time, but again only for date-time formats. This aligns the spec to the implementations of date-time formats, but still doesn't say anything either way about date-only formats.

So, what we're looking for clarification and consensus on, is whether the behavior mentioned should apply to all formats in that section rather than just the date-time formats, or if there's differing behavior for the date-only types. There needs to be spec correction either way.

Also, just thought I'd spin up some VMs and test old browsers. IE9 RTM shipped without support for either format. new Date('2015-01-01') on IE9 RTM gives Invalid Date. Anecdotally, there's this chart pointed at often, which contradicts this, so it's possible an update to IE9 fixed it. I'm testing more to see if I can find out.

I know for sure it was in IE10, so at least for IE it was sometime in 2012 that this format was at all usable with the Date object.

If I can figure out where to get old FF and Chrome I'll test those too...

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Oct 23, 2015

Member

ok @bterlson

To be clear, though, by revert I mean specifically for the date-only pattern and not the date-time pattern. Today afaict all browsers agree that the former is interpreted as UTC and the latter local time.

So while at first this sounded weird, I now think this sounds right. ISO 8601 does not have a time-zone relative date only format. It only has absolute dates. Using the ES internal time format, the most reasonable way to represent a date only value is with a 0 Zulu time. Both ES5.1, ES6, and ISO 8601 are explicit that a timezone offset field is part of a data-time and hence can not occur as part of a data-only. ISO 8601 says that a missing timezone offset is interpreted to mean local time. ES5.1 incorrectly stated that if the timezone offset field of a data-time is missing it is interpreted as if it was a "Z". Instead, it should have said the data-time is interpreted as a local time. This was noted in a ES5.1 bug ticket and fixed in the ES6 spec. So, if the above statement is correct the ES6 spec. seems to reflect what we want.

And even if there is actually lack of browser agreement upon the second part (date-time with time offset") it means we currently don't have cross browser interop and hence should be able to specify the "right answer".

In either case, it sounds like we need to clarify in Date.parse, that date-only ISO format is interpreted, for the purpose of generating a time value, is if it had a "T00Z" suffix.

Member

allenwb commented Oct 23, 2015

ok @bterlson

To be clear, though, by revert I mean specifically for the date-only pattern and not the date-time pattern. Today afaict all browsers agree that the former is interpreted as UTC and the latter local time.

So while at first this sounded weird, I now think this sounds right. ISO 8601 does not have a time-zone relative date only format. It only has absolute dates. Using the ES internal time format, the most reasonable way to represent a date only value is with a 0 Zulu time. Both ES5.1, ES6, and ISO 8601 are explicit that a timezone offset field is part of a data-time and hence can not occur as part of a data-only. ISO 8601 says that a missing timezone offset is interpreted to mean local time. ES5.1 incorrectly stated that if the timezone offset field of a data-time is missing it is interpreted as if it was a "Z". Instead, it should have said the data-time is interpreted as a local time. This was noted in a ES5.1 bug ticket and fixed in the ES6 spec. So, if the above statement is correct the ES6 spec. seems to reflect what we want.

And even if there is actually lack of browser agreement upon the second part (date-time with time offset") it means we currently don't have cross browser interop and hence should be able to specify the "right answer".

In either case, it sounds like we need to clarify in Date.parse, that date-only ISO format is interpreted, for the purpose of generating a time value, is if it had a "T00Z" suffix.

@ajklein

This comment has been minimized.

Show comment
Hide comment
@ajklein

ajklein Oct 26, 2015

Contributor

@bterlson Regarding Chrome's plans for the date-time version, I suspect we would be open to switching that to local time, as that sounds like it matches Firefox (and other browsers). The fact that we reverted the date-only and date-time changes together has more to do with our release process than anything else.

Contributor

ajklein commented Oct 26, 2015

@bterlson Regarding Chrome's plans for the date-time version, I suspect we would be open to switching that to local time, as that sounds like it matches Firefox (and other browsers). The fact that we reverted the date-only and date-time changes together has more to do with our release process than anything else.

@mj1856

This comment has been minimized.

Show comment
Hide comment
@mj1856

mj1856 Oct 26, 2015

@ajklein - That sounds like the right thing to do for now. The big realization is that even ES6 doesn't state how to interpret a date-only value. The defacto seems to be UTC, though local often makes more sense. Both ISO 8601 and the ES6 clarification only applies to date+time values.

So what we're needing from the TC is for clarification about how to interpret date-only values in a date+time context. Should they be interpreted at midnight UTC? Or should they be interpreted as the start-of-day in local time (which might not always be midnight)?

This all stems from having a single object type for all contexts, which is a bad practice unto itself, but alas the Date class is all we have.

mj1856 commented Oct 26, 2015

@ajklein - That sounds like the right thing to do for now. The big realization is that even ES6 doesn't state how to interpret a date-only value. The defacto seems to be UTC, though local often makes more sense. Both ISO 8601 and the ES6 clarification only applies to date+time values.

So what we're needing from the TC is for clarification about how to interpret date-only values in a date+time context. Should they be interpreted at midnight UTC? Or should they be interpreted as the start-of-day in local time (which might not always be midnight)?

This all stems from having a single object type for all contexts, which is a bad practice unto itself, but alas the Date class is all we have.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Oct 28, 2015

Member

#138 seems like a straight forward enough clarification to just take without committee meeting input.

Member

bterlson commented Oct 28, 2015

#138 seems like a straight forward enough clarification to just take without committee meeting input.

@GregMBS

This comment has been minimized.

Show comment
Hide comment
@GregMBS

GregMBS Nov 2, 2015

JavaScript does not exist in a vacuum. Has anyone bothered to consider how datetime objects are represented in data persistence layers (SQL for example) or does that get pushed into a Somebody Else's Problem field?

GregMBS commented Nov 2, 2015

JavaScript does not exist in a vacuum. Has anyone bothered to consider how datetime objects are represented in data persistence layers (SQL for example) or does that get pushed into a Somebody Else's Problem field?

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Nov 2, 2015

Member

@GregMBS The goal in this thread is not to come up with an ideal semantics for date parsing but to arrive at a semantics that can actually be implemented by runtimes and that reflects how to run existing JS code. If no implementation wants to take the breaking change suggested by ES6 (no one does), this clarification seems appropriate and brings the spec inline with what everyone already implements and, critically, inline with what is required to run real JS code in the wild.

If you want to consider a new design for Date or date parsing, please see CONTRIBUTING.md for more details on how to go about that.

Member

bterlson commented Nov 2, 2015

@GregMBS The goal in this thread is not to come up with an ideal semantics for date parsing but to arrive at a semantics that can actually be implemented by runtimes and that reflects how to run existing JS code. If no implementation wants to take the breaking change suggested by ES6 (no one does), this clarification seems appropriate and brings the spec inline with what everyone already implements and, critically, inline with what is required to run real JS code in the wild.

If you want to consider a new design for Date or date parsing, please see CONTRIBUTING.md for more details on how to go about that.

@bterlson

This comment has been minimized.

Show comment
Hide comment
@bterlson

bterlson Nov 13, 2015

Member

#138 is checked in, so closing this.

Member

bterlson commented Nov 13, 2015

#138 is checked in, so closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment