ecma262 icon indicating copy to clipboard operation
ecma262 copied to clipboard

Normative: Use DefaultTimeZone to get the local time zone for Date

Open ptomato opened this issue 2 years ago • 6 comments

Currently, it is technically possible for the following two operations to result in different local times and different time zones:

> date = new Date()
> date.toTimeString()
'13:43:47 GMT-0700 (Pacific Daylight Time)'
> new Intl.DateTimeFormat(undefined, {timeStyle: 'full'}).format(date)
'1:43:47 p.m. Pacific Daylight Time'

This is because Date gets its notion of the current system time zone from the operation LocalTZA, while Intl.DateTimeFormat uses the operation DefaultTimeZone from ECMA-402 to determine the current system time zone.

This is a normative change because there was previously no requirement for these to be linked. However, they should definitely be linked, and no implementation that includes ECMA-402 that I'm aware of has a discrepancy between the two. This patch adds this requirement.

This is accomplished by removing LocalTZA (which was actually two operations rolled into one, anyway) and redefining the LocalTime and UTC operations in terms of DefaultTimeZone, which moves into ECMA-262, as well as the two new operations GetNamedTimeZoneOffsetNanoseconds and GetNamedTimeZoneEpochNanoseconds.

It essentially pushes the "implementation-definedness" of LocalTZA into GetNamedTimeZoneOffsetNanoseconds, GetNamedTimeZoneEpochNanoseconds, and DefaultTimeZone.

Although it is a normative change because it adds the requirement for Date and Intl.DateTimeFormat to use the same default time zone, it should have no other effects. Despite specifying what LocalTZA used to do in terms of different operations, the observable effects are the same.

ptomato avatar May 20 '22 01:05 ptomato

@tc39/ecma262-editors This is the PR that we discussed in the editor call yesterday, arising from https://github.com/tc39/proposal-temporal/pull/2171

I put all the new AOs together into the Date section, let me know if they need to go anywhere else. The number of new AOs is not too bad but if needed I can cut it down a bit more:

  • RoundTowardsZero could instead be a mathematical function like floor
  • We could remove the "these are the steps if your implementation only has UTC" parts of the implementation-defined AOs (maybe their utility is questionable?) and that would allow removing GetEpochFromISOParts as well.

ptomato avatar May 20 '22 01:05 ptomato

This reached consensus. The promised followup details regarding DST transitions:

The requirements are described in GetNamedTimeZoneEpochNanoseconds (which returns a List of nanoseconds since epoch for a specific time zone name and local time) similar to the current text in LocalTZA: https://arai-a.github.io/ecma262-compare/?pr=2781#sec-getnamedtimezoneepochnanoseconds (emphasis mine)

When the input represents a local time occurring more than once because of a negative time zone transition (e.g. when daylight saving time ends or the time zone offset is decreased due to a time zone rule change), the returned List will have more than one element and will be sorted by ascending numerical value. When the input represents a local time skipped because of a positive time zone transition (e.g. when daylight saving time begins or the time zone offset is increased due to a time zone rule change), the returned List will be empty. Otherwise, the returned List will have one element.

And specified more precisely in UTC (which interprets its input as a number representing local time and returns a single milliseconds since epoch): https://arai-a.github.io/ecma262-compare/?pr=2781#sec-utc-t (emphasis mine)

If possibleInstants is not empty, then… Let disambiguatedInstant be possibleInstants[0]. [i.e., the chronologically first matching local time] Else [a local time skipped at a positive time zone transition], … Let possibleInstants be GetNamedTimeZoneEpochNanoseconds [corresponding with] tBefore is the largest integral Number < t for which possibleInstants is not empty (i.e., tBefore represents the last local time before the transition) … Let disambiguatedInstant be the last element of possibleInstants … t is interpreted using the time zone offset before the transition

gibson042 avatar Jun 06 '22 18:06 gibson042

I'm not sure there's really an effective test262 test possible for this; if I were to write one, it'd depend on implementation-defined date and time zone format strings. What else would be needed for merging this?

ptomato avatar Jun 14 '22 14:06 ptomato

@ptomato This does not require test262 tests to be merged. Waiting on 262 editor review.

michaelficarra avatar Jun 15 '22 22:06 michaelficarra

@michaelficarra Thanks for the review, I have kept the changes addressing your comments in a separate commit for ease of review, but I can squash them before merging if you prefer.

ptomato avatar Aug 04 '22 19:08 ptomato

@michaelficarra @ljharb Thanks for the quick response, new modifications are in another separate commit.

ptomato avatar Aug 05 '22 18:08 ptomato

It seems like at least the phrasing "in the inclusive interval from 1 to 12" is stable in #2848, although details are still being debated. I've updated this PR to use that phrasing and rebased it. Would it be possible to merge this, since it seems like the open discussions in #2848 are not going to change anything here? There are several things I need to do in Temporal that are waiting on this.

ptomato avatar Aug 31 '22 01:08 ptomato

If there's anything that I should join the editor call to discuss, that would help move this forward, please let me know - I'm available during that time today.

ptomato avatar Sep 14 '22 20:09 ptomato

@ptomato the editor call doesn't happen during TC39 weeks, so it'd be next week.

ljharb avatar Sep 14 '22 20:09 ljharb

Thanks, I've rebased this and made the changes in a separate commit so you can easily see what changed, and then squash before merging.

ptomato avatar Sep 20 '22 23:09 ptomato

I think this is good to go now but will wait to merge until other editors confirm.

bakkot avatar Sep 23 '22 21:09 bakkot

As usual, new changes are in a fixup commit.

ptomato avatar Sep 26 '22 16:09 ptomato

Rebased; added the changes that Richard requested in a fixup commit.

ptomato avatar Oct 06 '22 22:10 ptomato