From a99ee44a06fa9546ff04fe76bafac310f1e98f7a Mon Sep 17 00:00:00 2001 From: Justin Grant Date: Thu, 29 Jun 2023 01:19:25 -0700 Subject: [PATCH] Catch up with upstream proposal-temporal Align with upstream refactoring of offset time zone parsing and formatting. --- polyfill/polyfill.diff | 33 +++++++++++++++++---------------- spec/intl.html | 2 +- spec/temporal-biblio.json | 19 +++++++++++++++++-- spec/timezone.html | 30 ++++++++++++++++++++++-------- temporal | 2 +- 5 files changed, 58 insertions(+), 28 deletions(-) diff --git a/polyfill/polyfill.diff b/polyfill/polyfill.diff index 7c40dd88..ca858732 100644 --- a/polyfill/polyfill.diff +++ b/polyfill/polyfill.diff @@ -9,7 +9,7 @@ index 1c6831c7..73008e46 100644 + url = https://github.com/justingrant/test262 + branch = proposal-canonical-tz-tests diff --git a/polyfill/index.d.ts b/polyfill/index.d.ts -index 244067cb..d4b6f741 100644 +index 784677c9..b11758ea 100644 --- a/polyfill/index.d.ts +++ b/polyfill/index.d.ts @@ -1138,6 +1138,7 @@ export namespace Temporal { @@ -21,11 +21,11 @@ index 244067cb..d4b6f741 100644 getOffsetStringFor(instant: Temporal.Instant | string): string; getPlainDateTimeFor(instant: Temporal.Instant | string, calendar?: CalendarLike): Temporal.PlainDateTime; diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs -index 25d54d96..8359e4a0 100644 +index e7f04c0b..53d5ed81 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs -@@ -371,7 +371,7 @@ export function ParseTemporalTimeZone(stringIdent) { - if (IsTimeZoneOffsetString(tzName)) return CanonicalizeTimeZoneOffsetString(tzName); +@@ -2101,7 +2101,7 @@ export function ToTemporalTimeZoneSlotValue(temporalTimeZoneLike) { + const record = GetAvailableNamedTimeZoneIdentifier(tzName); if (!record) throw new RangeError(`Unrecognized time zone ${tzName}`); - return record.primaryIdentifier; @@ -33,15 +33,16 @@ index 25d54d96..8359e4a0 100644 } if (z) return 'UTC'; // if !tzName && !z then offset must be present -@@ -2119,7 +2119,16 @@ export function TimeZoneEquals(one, two) { +@@ -2126,7 +2126,17 @@ export function TimeZoneEquals(one, two) { if (one === two) return true; const tz1 = ToTemporalTimeZoneIdentifier(one); const tz2 = ToTemporalTimeZoneIdentifier(two); - return tz1 === tz2; + if (tz1 === tz2) return true; -+ if (IsTimeZoneOffsetString(tz1)) { -+ if (!IsTimeZoneOffsetString(tz2)) return false; -+ return CanonicalizeTimeZoneOffsetString(tz1) === CanonicalizeTimeZoneOffsetString(tz2); ++ const offsetNanoseconds1 = ParseTimeZoneIdentifier(tz1).offsetNanoseconds; ++ const offsetNanoseconds2 = ParseTimeZoneIdentifier(tz2).offsetNanoseconds; ++ if (offsetNanoseconds1 !== undefined || offsetNanoseconds2 !== undefined) { ++ return offsetNanoseconds1 === offsetNanoseconds2; + } + const idRecord1 = GetAvailableNamedTimeZoneIdentifier(tz1); + if (!idRecord1) return false; @@ -52,7 +53,7 @@ index 25d54d96..8359e4a0 100644 export function TemporalDateTimeToDate(dateTime) { diff --git a/polyfill/lib/intl.mjs b/polyfill/lib/intl.mjs -index e3c6a403..4870d3d1 100644 +index 9d78ee43..d86269a5 100644 --- a/polyfill/lib/intl.mjs +++ b/polyfill/lib/intl.mjs @@ -139,7 +139,7 @@ Object.defineProperty(DateTimeFormat, 'prototype', { @@ -65,10 +66,10 @@ index e3c6a403..4870d3d1 100644 } diff --git a/polyfill/lib/timezone.mjs b/polyfill/lib/timezone.mjs -index 9796e980..eb957267 100644 +index 7c6c8a2e..857385ad 100644 --- a/polyfill/lib/timezone.mjs +++ b/polyfill/lib/timezone.mjs -@@ -32,7 +32,7 @@ export class TimeZone { +@@ -33,7 +33,7 @@ export class TimeZone { } else { const record = ES.GetAvailableNamedTimeZoneIdentifier(stringIdentifier); if (!record) throw new RangeError(`Invalid time zone identifier: ${stringIdentifier}`); @@ -77,7 +78,7 @@ index 9796e980..eb957267 100644 } CreateSlots(this); SetSlot(this, TIMEZONE_ID, stringIdentifier); -@@ -50,6 +50,11 @@ export class TimeZone { +@@ -51,6 +51,11 @@ export class TimeZone { if (!ES.IsTemporalTimeZone(this)) throw new TypeError('invalid receiver'); return GetSlot(this, TIMEZONE_ID); } @@ -90,7 +91,7 @@ index 9796e980..eb957267 100644 if (!ES.IsTemporalTimeZone(this)) throw new TypeError('invalid receiver'); instant = ES.ToTemporalInstant(instant); diff --git a/polyfill/lib/zoneddatetime.mjs b/polyfill/lib/zoneddatetime.mjs -index 1a593c7f..06de9d5f 100644 +index cbd4f8c8..ed1a4143 100644 --- a/polyfill/lib/zoneddatetime.mjs +++ b/polyfill/lib/zoneddatetime.mjs @@ -478,7 +478,7 @@ export class ZonedDateTime { @@ -103,9 +104,9 @@ index 1a593c7f..06de9d5f 100644 const formatter = new DateTimeFormat(locales, optionsCopy); diff --git a/polyfill/test262 b/polyfill/test262 -index 3e858ef0..041e65e3 160000 +index c5b24c64..e7d9edfe 160000 --- a/polyfill/test262 +++ b/polyfill/test262 @@ -1 +1 @@ --Subproject commit 3e858ef02d2eda1e1e7eeff89ad7deeaf99d2766 -+Subproject commit 041e65e336e35f1989ec5f0fcf8b2ac745837ab0 +-Subproject commit c5b24c64c3c27544f15e1c18ef274924cff1e32c ++Subproject commit e7d9edfe3866bac9eb4be01619b99748cc0209b2 diff --git a/spec/intl.html b/spec/intl.html index 58037deb..0cfa23d0 100644 --- a/spec/intl.html +++ b/spec/intl.html @@ -73,7 +73,7 @@

Temporal.ZonedDateTime.prototype.toLocaleString ( [ _locales_ [ , _options_ 1. Perform ? RequireInternalSlot(_zonedDateTime_, [[InitializedTemporalZonedDateTime]]). 1. Let _dateTimeFormat_ be ! OrdinaryCreateFromConstructor(%DateTimeFormat%, %DateTimeFormat.prototype%, « [[InitializedDateTimeFormat]], [[Locale]], [[Calendar]], [[NumberingSystem]], [[TimeZone]], [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[FractionalSecondDigits]], [[TimeZoneName]], [[HourCycle]], [[Pattern]], [[BoundFormat]] »). 1. Let _timeZone_ be ? ToTemporalTimeZoneIdentifier(_zonedDateTime_.[[TimeZone]]). - 1. If IsTimeZoneOffsetString(_timeZone_) is *true*, throw a *RangeError* exception. + 1. If IsOffsetTimeZoneIdentifier(_timeZone_) is *true*, throw a *RangeError* exception. 1. Let _timeZoneIdentifierRecord_ be GetAvailableNamedTimeZoneIdentifier(_timeZone_). 1. If _timeZoneIdentifierRecord_ is ~empty~, throw a *RangeError* exception. 1. Set _timeZone_ to _timeZoneIdentifierRecord_.[[PrimaryIdentifierIdentifier]]. diff --git a/spec/temporal-biblio.json b/spec/temporal-biblio.json index c5217697..1fd28ff0 100644 --- a/spec/temporal-biblio.json +++ b/spec/temporal-biblio.json @@ -9,8 +9,23 @@ }, { "type": "op", - "aoid": "CanonicalizeTimeZoneOffsetString", - "id": "sec-temporal-canonicalizetimezoneoffsetstring" + "aoid": "IsOffsetTimeZoneIdentifier", + "id": "sec-temporal-isoffsettimezoneidentifier" + }, + { + "type": "op", + "aoid": "FormatOffsetTimeZoneIdentifier", + "id": "sec-temporal-formatoffsettimezoneidentifier" + }, + { + "type": "op", + "aoid": "ParseDateTimeUTCOffset", + "id": "sec-temporal-parsedatetimeutcoffset" + }, + { + "type": "op", + "aoid": "ParseTimeZoneIdentifier", + "id": "sec-temporal-parsetimezoneidentifier" }, { "type": "op", diff --git a/spec/timezone.html b/spec/timezone.html index 1483917e..97b2e20e 100644 --- a/spec/timezone.html +++ b/spec/timezone.html @@ -22,14 +22,15 @@

SystemTimeZoneIdentifier ( ): a String

description
- It returns a String representing the host environment's current time zone, which is either a String representing a UTC offset for which IsTimeZoneOffsetString returns *true*, or a primary time zone identifier. + It returns a String representing the host environment's current time zone, which is either a primary time zone identifier or an offset time zone identifier.
1. If the implementation only supports the UTC time zone, return *"UTC"*. 1. Let _systemTimeZoneString_ be the String representing the host environment's current time zone, either a primary time zone identifier or an offset time zone identifier. - 1. If IsTimeZoneOffsetString(_systemTimeZoneString_) is *true*, return CanonicalizeTimeZoneOffsetString(_systemTimeZoneString_). + 1. Let _offsetNanoseconds_ be ! ParseTimeZoneIdentifier(_systemTimeZoneString_). + 1. If _offsetNanoseconds_ is not ~empty~, return FormatOffsetTimeZoneIdentifier(_offsetNanoseconds_, ~separated~). 1. Return _systemTimeZoneString_. @@ -47,8 +48,10 @@

Temporal.TimeZone ( _identifier_ )

1. If NewTarget is *undefined*, then 1. Throw a *TypeError* exception. - 1. Set _identifier_ to ? ToString(_identifier_). - 1. If IsTimeZoneOffsetString(_identifier_) is *false*, then + 1. Let _parseResult_ be ? ParseTimeZoneIdentifier(_identifier_). + 1. If _parseResult_.[[OffsetNanoseconds]] is not ~empty~, then + 1. Set _identifier_ to FormatOffsetTimeZoneIdentifier(_parseResult_.[[OffsetNanoseconds]], ~separated~). + 1. Else, 1. Let _timeZoneIdentifierRecord_ be GetAvailableNamedTimeZoneIdentifier(_identifier_). 1. If _timeZoneIdentifierRecord_ is ~empty~, throw a *RangeError* exception. 1. Set _identifier_ to _timeZoneIdentifierRecord_.[[PrimaryIdentifierIdentifier]]. @@ -87,10 +90,13 @@

1. If _newTarget_ is not present, set _newTarget_ to %Temporal.TimeZone%. 1. Let _object_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%Temporal.TimeZone.prototype%"*, « [[InitializedTemporalTimeZone]], [[Identifier]], [[OffsetNanoseconds]] »). - 1. If IsTimeZoneOffsetString(_identifier_) is *true*, then + 1. Assert: _identifier_ is an available named time zone identifier or an offset time zone identifier. + 1. Let _parseResult_ be ! ParseTimeZoneIdentifier(_identifier_). + 1. If _parseResult_.[[OffsetNanoseconds]] is not ~empty~, then 1. Set _object_.[[Identifier]] to ~empty~. - 1. Set _object_.[[OffsetNanoseconds]] to ParseTimeZoneOffsetString(_identifier_). + 1. Set _object_.[[OffsetNanoseconds]] to _parseResult_.[[OffsetNanoseconds]]. 1. Else, + 1. Assert: _parseResult_.[[Name]] is not ~empty~. 1. Assert: GetAvailableNamedTimeZoneIdentifier(_identifier_).[[PrimaryIdentifierIdentifier]] is _identifier_. 1. Set _object_.[[Identifier]] to _identifier_. 1. Set _object_.[[OffsetNanoseconds]] to ~empty~. @@ -118,12 +124,15 @@

1. Let _parseResult_ be ? ParseTemporalTimeZoneString(_identifier_). 1. If _parseResult_.[[Name]] is not *undefined*, then 1. Let _name_ be _parseResult_.[[Name]]. - 1. If IsTimeZoneOffsetString(_name_) is *true*, return CanonicalizeTimeZoneOffsetString(_name_). + 1. Let _offsetNanoseconds_ be ? ParseTimeZoneIdentifier(_name_).[[OffsetNanoseconds]]. + 1. If _offsetNanoseconds_ is not ~empty~, return FormatOffsetTimeZoneIdentifier(_offsetNanoseconds_, ~separated~). 1. Let _timeZoneIdentifierRecord_ be GetAvailableNamedTimeZoneIdentifier(_name_). 1. If _timeZoneIdentifierRecord_ is ~empty~, throw a *RangeError* exception. 1. Return _timeZoneIdentifierRecord_.[[PrimaryIdentifierIdentifier]]. 1. If _parseResult_.[[Z]] is *true*, return *"UTC"*. - 1. Return CanonicalizeTimeZoneOffsetString(_parseResult_.[[OffsetString]]). + 1. Let _offsetParseResult_ be ! ParseDateTimeUTCOffset(_parseResult_.[[OffsetString]]). + 1. If _offsetParseResult_.[[HasSubMinutePrecision]] is *true*, throw a *RangeError* exception. + 1. Return FormatOffsetTimeZoneIdentifier(_offsetParseResult_.[[OffsetNanoseconds]], ~separated~). @@ -143,6 +152,11 @@

1. Let _timeZoneOne_ be ? ToTemporalTimeZoneIdentifier(_one_). 1. Let _timeZoneTwo_ be ? ToTemporalTimeZoneIdentifier(_two_). 1. If _timeZoneOne_ is _timeZoneTwo_, return *true*. + 1. Let _offsetNanosecondsOne_ be ParseTimeZoneIdentifier(_timeZoneOne_).[[OffsetNanoseconds]]. + 1. Let _offsetNanosecondsTwo_ be ParseTimeZoneIdentifier(_timeZoneTwo_).[[OffsetNanoseconds]]. + 1. If _offsetNanosecondsOne_ is not ~empty~ or _offsetNanosecondsTwo_ is not ~empty~, then + 1. If _offsetNanosecondsOne_ is not ~empty~ and _offsetNanosecondsTwo_ is not ~empty~ and _offsetNanosecondsOne_ = _offsetNanosecondsTwo_, return *true*. + 1. Return *false*. 1. Let _recordOne_ be GetAvailableNamedTimeZoneIdentifier(_timeZoneOne_). 1. Let _recordTwo_ be GetAvailableNamedTimeZoneIdentifier(_timeZoneTwo_). 1. If _recordOne_ is not ~empty~ and _recordTwo_ is not ~empty~ and _recordOne_.[[PrimaryIdentifier]] is _recordTwo_.[[PrimaryIdentifier]], return *true*. diff --git a/temporal b/temporal index 667e4a25..6d6d2313 160000 --- a/temporal +++ b/temporal @@ -1 +1 @@ -Subproject commit 667e4a25dfc24b44c2f721eb0668b0ac7cc01c5c +Subproject commit 6d6d231309450260956613ee39a24f695597d0f0