New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

20.3.3.2 Date.parse does not explicitly state out-of-range time values return NaN #1145

Closed
apaprocki opened this Issue Mar 21, 2018 · 6 comments

Comments

Projects
None yet
4 participants
@apaprocki
Contributor

apaprocki commented Mar 21, 2018

Section 20.3.3.2 currently states:

... it returns a Number, the UTC time value corresponding to the date and time.

Unrecognizable Strings or dates containing illegal element values in the format String shall cause Date.parse to return NaN.

A time value is spec'd to only be the range -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds since UTC epoch, inclusive.

Issue:

Firefox properly (IMO) returns NaN for values outside of the specified time value range:

Date.parse("-271821-04-20T00:00:00.000Z")
-8640000000000000
Date.parse("-271821-04-19T11:59:59.999Z")
NaN

Chrome allows any extended years value, even if the returned value loses precision due to Number not being able to represent it exactly:

Date.parse("-271821-04-20T00:00:00.000Z")
-8640000000000000
Date.parse("-271821-04-19T11:59:59.999Z")
-8640000043200001
Date.parse("-999999-01-01T00:00:00.000Z")
-31619087596800000
Date.parse("-999999-01-01T00:00:00.001Z")
-31619087596800000
Date.parse("-999999-01-01T00:00:00.002Z")
-31619087596800000
Date.parse("-1000000-01-01T00:00:00.000Z")
NaN

Safari has almost the same behavior as Chrome, returning Number values that exceed the maximum time value range, but it loses precision in a different manner for the last value used above. More troubling, Safari seems to accept extended years > 6 digits, while Firefox and Chrome do not.

> Date.parse("-999999-01-01T00:00:00.000Z")
< -31619087596800000
> Date.parse("-999999-01-01T00:00:00.001Z")
< -31619087596800000
> Date.parse("-999999-01-01T00:00:00.002Z")
< -31619087596799996
> Date.parse("-1000000-01-01T00:00:00.000Z")
< -31619119219200000

Resolution:

  • Three implementations differ in behavior. Is this a under-specification?
  • Should it be explicitly stated that extended year parsed values outside of the range of time value must return NaN?
  • Alternatively, is the specification clear enough and one or more implementation have bugs?
@apaprocki

This comment has been minimized.

Show comment
Hide comment
@apaprocki

apaprocki Mar 21, 2018

Contributor

Apparently the Safari implementation is accepting any year value from MIN_INT to MAX_INT - 1:

> Date.parse("-2147483648-01-01T00:00:00.000Z")
< NaN
> Date.parse("-2147483647-01-01T00:00:00.000Z")
< -67768100536348800000
...

> Date.parse("2147483646-01-01T00:00:00.000Z")
< 67767976170460800000
> Date.parse("2147483647-01-01T00:00:00.000Z")
< NaN
Contributor

apaprocki commented Mar 21, 2018

Apparently the Safari implementation is accepting any year value from MIN_INT to MAX_INT - 1:

> Date.parse("-2147483648-01-01T00:00:00.000Z")
< NaN
> Date.parse("-2147483647-01-01T00:00:00.000Z")
< -67768100536348800000
...

> Date.parse("2147483646-01-01T00:00:00.000Z")
< 67767976170460800000
> Date.parse("2147483647-01-01T00:00:00.000Z")
< NaN
@anba

This comment has been minimized.

Show comment
Hide comment
@anba

anba Mar 21, 2018

Contributor

Implementation-defined semantics seem to be allowed for out-of-bounds values.

https://tc39.github.io/ecma262/#sec-date-time-string-format

Illegal values (out-of-bounds as well as syntax errors) in a format string means that the format string is not a valid instance of this format.

https://tc39.github.io/ecma262/#sec-date.parse

The function first attempts to parse the format of the String according to the rules (including extended years) called out in Date Time String Format (20.3.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.

Contributor

anba commented Mar 21, 2018

Implementation-defined semantics seem to be allowed for out-of-bounds values.

https://tc39.github.io/ecma262/#sec-date-time-string-format

Illegal values (out-of-bounds as well as syntax errors) in a format string means that the format string is not a valid instance of this format.

https://tc39.github.io/ecma262/#sec-date.parse

The function first attempts to parse the format of the String according to the rules (including extended years) called out in Date Time String Format (20.3.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.

@apaprocki

This comment has been minimized.

Show comment
Hide comment
@apaprocki

apaprocki Mar 21, 2018

Contributor

To me, the purpose of that text is to allow implementations to have other overall different formats that implementations could support.

The strongest argument to me is that Date.parse() is defined to return:

parse interprets the resulting String as a date and time; it returns a Number, the UTC time value corresponding to the date and time.

and time value is defined to be -8,640,000,000,000,000 to 8,640,000,000,000,000.

It reads to me that implementations, while still allowing their own implementation-specific behavior, are still bound by returning a time value within the maximum range.

Contributor

apaprocki commented Mar 21, 2018

To me, the purpose of that text is to allow implementations to have other overall different formats that implementations could support.

The strongest argument to me is that Date.parse() is defined to return:

parse interprets the resulting String as a date and time; it returns a Number, the UTC time value corresponding to the date and time.

and time value is defined to be -8,640,000,000,000,000 to 8,640,000,000,000,000.

It reads to me that implementations, while still allowing their own implementation-specific behavior, are still bound by returning a time value within the maximum range.

@anba

This comment has been minimized.

Show comment
Hide comment
@anba

anba Mar 21, 2018

Contributor

It reads to me that implementations, while still allowing their own implementation-specific behavior, are still bound by returning a time value within the maximum range.

Agreed.

Contributor

anba commented Mar 21, 2018

It reads to me that implementations, while still allowing their own implementation-specific behavior, are still bound by returning a time value within the maximum range.

Agreed.

@littledan

This comment has been minimized.

Show comment
Hide comment
@littledan

littledan Apr 4, 2018

Member

Seems to me like just a tiny bit more more clarifying text in the "Extended Years" plus the test262 tests you wrote should be sufficient to reinforce this interpretation. (Maybe you were already thinking along those lines.)

Member

littledan commented Apr 4, 2018

Seems to me like just a tiny bit more more clarifying text in the "Extended Years" plus the test262 tests you wrote should be sufficient to reinforce this interpretation. (Maybe you were already thinking along those lines.)

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Aug 1, 2018

Member

Should this be closed, now that #1144 is merged?

Member

ljharb commented Aug 1, 2018

Should this be closed, now that #1144 is merged?

@littledan littledan closed this Sep 6, 2018

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