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

Inconsistencies and errors in the time range supported by Date #1176

Open
ediosyncratic opened this Issue Apr 18, 2018 · 1 comment

Comments

Projects
None yet
2 participants
@ediosyncratic

ediosyncratic commented Apr 18, 2018

Let's start with 20.3.1.1 Time Values and Time Range,

The second paragraph tells me:

ECMAScript Number values can represent all integers from -9,007,199,254,740,992 to 9,007,199,254,740,992; this range suffices to measure times to millisecond precision for any instant that is within approximately 285,616 years, either forward or backward, from 01 January, 1970 UTC.

Now, 9,007,199,254,740,992 is just an obfuscated way to write 2^{53}; that many milliseconds make up 104249991 days (and a bit over eight hours) which comprise 285426.78 Gregorian years. Dividing that number of days by 285,616, I find the above text is assuming every year is 365 days. This is somewhat inaccurate, but kinda bearable - since it doesn't really matter (or, at least, shouldn't - see below), it's only a preamble to the next paragraph, which opens with:

The actual range of times supported by ECMAScript Date objects is slightly smaller: exactly -100,000,000 days to 100,000,000 days measured relative to midnight at the beginning of 01 January, 1970 UTC.

(... and I'll note, in passing, that specifying the epoch as "at the beginning of 01 January 1970 UTC" is both a funny phrasing - it'd make more sense to call it "the UTC beginning of ..." - and redundant; it's entirely specific enough to say "at the UTC beginning of 1970"; going into the detail of which day it began on (something I assure you I knew at the time, even though I was only six) prompts the reader to wonder why you didn't specify also the hour, minute, second and, indeed, millisecond.)

OK, so the actual date range is 1e8 days. Fine. Now let's look at 20.3.1.16.1 Extended Years,

ECMAScript requires the ability to specify 6 digit years (extended years); approximately 285,426 years, either forward or backward, from 01 January, 1970 UTC.

So where does this 285,426 year figure fit in ? It's the number of whole years in 2^{53} milliseconds. (At least they're Gregorian years, this time; there's nine and a part months left over.) Which lead me to think one of the tests in the test-suite was misguided, since it's more than 1e8 days, so a Date on the 1e8th day before the epoch seemed like it should be representable. But, of course, the Date range is 1e8 days, not 2^{53} milliseconds, as @anba patiently explained to me. So claiming ES is OK with years out to 2^{53} ms ago is misleading: an attempt to parse a date 285,426 before the epoch should in fact fail - I'm not sure whether it should produce a NaN or raise an exception, but the date it purports to represent is out of range for Date (and your test-suite has tests to verify that the Date constructor actually rejects dates outside its range).

In 20.3.1.1, I don't think it's actually worth mentioning the number of years in 2^{53} ms; it would be better to leave it out there and instead tell us the number of years in 1e8 days, as part of the later paragraph actually specifying the true range of Date. However, if you do chose to keep the mention of how many years there are in 2^{53} ms, please get it right. If you want to use the sidereal or tropical year, feel free; but please use something more accurate than 365 days (over a hundred million days, the errors in that add up quite a bit); and the Gregorian year is probably the best choice, given that it's what Date assumes.

In 20.3.1.16.1, I recommend giving a number of years that's actually consistent with Date's range, rather than the range of 2^{53} ms. You might want to round up, to 285,427 rather than 285,426 years (since a date in the later months of 283,458 BC is valid), and it'd probably be worth referring to 20.3.1.1 and maybe even re-iterating that 1e8 days is the definitive cut-off. Likewise, of course, the examples section needs to adjust its first and last entries to the start and end of the 1e8th day, rather than of the 2^{53}rd millisecond, before and after the start of 1970.

@anba

This comment has been minimized.

Show comment
Hide comment
@anba

anba Apr 18, 2018

Contributor

I think #1144 attempts to reword this section to be more consistent.

Contributor

anba commented Apr 18, 2018

I think #1144 attempts to reword this section to be more consistent.

qtprojectorg pushed a commit to qt/qtdeclarative-testsuites that referenced this issue Jun 12, 2018

Revert "Change number of days in test to make date actually out of ra…
…nge"

This reverts commit 40b4f28.
The test was correct, after all: the ES Date() range is 1e8 days, not 1<<53 ms.
See tc39/ecma262#1176 for the gory details.

Change-Id: Iff84ed9519b86d24a4051e904140740de973969c
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment