Skip to content

Commit

Permalink
Editorial: Define IsValidTimeZoneName in terms of AvailableTimeZones
Browse files Browse the repository at this point in the history
AvailableTimeZones is an abstract operation defined in the
Intl.Enumeration proposal (though there is a small difference, see below.)
Sharing AvailableTimeZones between ECMA-262 and ECMA-402 should allow us
to stipulate that if an implementation supports any time zone for
formatting in Intl.DateTimeFormat, it must support it for Temporal as
well.

This change means IsValidTimeZoneName is no longer implementation-defined,
and does not need to exist in ECMA-402, only in 262.

Note, this requires a slightly different algorithm for AvailableTimeZones
than the one in the Intl.Enumeration proposal. I have opened an issue for
resolving whether AvailableTimeZones should return only canonicalized
names or also backzone names:
tc39/proposal-intl-enumeration#37

See: #541
See: #519
  • Loading branch information
ptomato committed May 4, 2022
1 parent 8f33158 commit 39f890b
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 27 deletions.
2 changes: 1 addition & 1 deletion spec/abstractops.html
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ <h1>ToRelativeTemporalObject ( _options_ )</h1>
1. Let _timeZoneName_ be _result_.[[TimeZoneIANAName]].
1. If _timeZoneName_ is not *undefined*, then
1. If ParseText(StringToCodePoints(_timeZoneName_), |TimeZoneNumericUTCOffset|) is a List of errors, then
1. If ! IsValidTimeZoneName(_timeZoneName_) is *false*, throw a *RangeError* exception.
1. If IsValidTimeZoneName(_timeZoneName_) is *false*, throw a *RangeError* exception.
1. Set _timeZoneName_ to ! CanonicalizeTimeZoneName(_timeZoneName_).
1. Let _timeZone_ be ! CreateTemporalTimeZone(_timeZoneName_).
1. Else,
Expand Down
51 changes: 36 additions & 15 deletions spec/intl.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,21 @@ <h1><a href="https://tc39.es/ecma402/#sec-time-zone-names">Time Zone Names</a></
A conforming implementation must recognize *"UTC"* and all other Zone and Link names (and <strong>only</strong> such names), and use best available current and historical information about their offsets from UTC and their daylight saving time rules in calculations. However, the set of combinations of time zone name and language tag for which localized time zone names are available is implementation dependent.
</p>

<emu-clause id="sup-isvalidtimezonename">
<h1><a href="https://tc39.es/ecma402/#sec-isvalidtimezonename">IsValidTimeZoneName</a> ( _timeZone_ )</h1>
<del class="block">
<emu-clause id="sup-isvalidtimezonename">
<h1><a href="https://tc39.es/ecma402/#sec-isvalidtimezonename">IsValidTimeZoneName</a> ( _timeZone_ )</h1>

<ins class="block">
<p>This definition supersedes the definition provided in <emu-xref href="#sec-isvalidtimezonename"></emu-xref>.</p>
</ins>
<p>
The abstract operation IsValidTimeZoneName takes argument _timeZone_, a String value, and verifies that it represents a valid Zone or Link name of the IANA Time Zone Database.
</p>
<p>
The abstract operation IsValidTimeZoneName takes argument _timeZone_, a String value, and verifies that it represents a valid Zone or Link name of the IANA Time Zone Database.
</p>

<emu-alg>
1. If one of the Zone or Link names of the IANA Time Zone Database is an ASCII-case-insensitive match of _timeZone_, return *true*.
1. If _timeZone_ is an ASCII-case-insensitive match of *"UTC"*, return *true*.
1. Return *false*.
</emu-alg>
</emu-clause>
<emu-alg>
1. If one of the Zone or Link names of the IANA Time Zone Database is an ASCII-case-insensitive match of _timeZone_, return *true*.
1. If _timeZone_ is an ASCII-case-insensitive match of *"UTC"*, return *true*.
1. Return *false*.
</emu-alg>
</emu-clause>
</del>

<emu-clause id="sup-canonicalizetimezonename" type="abstract operation">
<h1>
Expand Down Expand Up @@ -85,6 +84,28 @@ <h1><a href="https://tc39.es/ecma402/#sec-defaulttimezone">DefaultTimeZone</a> (
</p>
</emu-clause>

<ins class="block">
<emu-clause id="sup-availabletimezones" type="abstract operation">
<h1>
AvailableTimeZones (
): a List of Strings
</h1>
<dl class="header">
<dt>description</dt>
<dd>The returned List is a sorted List of supported Zone and Link names in the IANA Time Zone Database.</dd>
<dt>redefinition</dt>
<dd>true</dd>
</dl>
<emu-alg>
1. Let _result_ be a List of all supported Zone and Link names in the IANA Time Zone Database.
1. Sort _result_ in order as if an Array of the same values had been sorted using %Array.prototype.sort% using *undefined* as _comparefn_.
1. Return _result_.
</emu-alg>

<p>This definition supersedes the definition provided in <emu-xref href="#sec-availabletimezones"></emu-xref>.</p>
</emu-clause>
</ins>

<ins class="block">
<emu-clause id="sup-calendar-types">
<h1>Calendar Types</h1>
Expand Down Expand Up @@ -193,7 +214,7 @@ <h1>InitializeDateTimeFormat ( _dateTimeFormat_, _locales_, _options_ )</h1>
1. Set _timeZone_ to ! DefaultTimeZone().
1. Else,
1. Set _timeZone_ to ? ToString(_timeZone_).
1. If the result of ! IsValidTimeZoneName(_timeZone_) is *false*, then
1. If the result of IsValidTimeZoneName(_timeZone_) is *false*, then
1. Throw a *RangeError* exception.
1. Set _timeZone_ to ! CanonicalizeTimeZoneName(_timeZone_).
1. Set _dateTimeFormat_.[[TimeZone]] to _timeZone_.
Expand Down
39 changes: 29 additions & 10 deletions spec/timezone.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,23 @@ <h1>Time Zone Names</h1>
<h1>
IsValidTimeZoneName (
_timeZone_: a String,
)
): a Boolean
</h1>
<dl class="header">
<dt>description</dt>
<dd>It returns *true* if _timeZone_ is an ASCII-case-insensitive match for a built-in time zone name and *false* otherwise.</dd>
<dd>The returned value is *true* if _timeZone_ is an ASCII-case-insensitive match for a built-in time zone name, and *false* otherwise.</dd>
</dl>
<p>
An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the IsValidTimeZoneName abstract operation as specified in the ECMA-402 specification.
</p>
<p>
Once IsValidTimeZoneName(_timeZone_) has returned *true*, for the lifetime of the surrounding agent, IsValidTimeZoneName(_variant_) must return *true* if _variant_ is an ASCII-case-insensitive match for either _timeZone_ or CanonicalizeTimeZoneName(_timeZone_).
</p>
<p>
For the purposes of this section, a String value _A_ is an ASCII-case-insensitive match for String value _B_ if the String value derived from _A_ by replacing each occurrence of a lowercase ASCII letter code unit (0x0061 through 0x007A, inclusive) with the corresponding uppercase ASCII letter code unit (0x0041 through 0x005A, inclusive) while preserving all other code units is exactly the same sequence of code units as the String value that is derived from _B_ in the same way.
</p>
<p>The minimum implementation of IsValidTimeZoneName for ECMAScript implementations that do not include the ECMA-402 API, supporting only the *"UTC"* time zone, performs the following steps when called:
</p>

<emu-alg>
1. If _timeZone_ is an ASCII-case-insensitive match for *"UTC"*, return *true*.
1. Let _timeZones_ be AvailableTimeZones().
1. For each String _candidate_ in _timeZones_, do
1. If _timeZone_ is an ASCII-case-insensitive match for _candidate_, return *true*.
1. Return *false*.
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -106,6 +103,28 @@ <h1>
1. Return *"UTC"*.
</emu-alg>
</emu-clause>

<emu-clause id="sec-availabletimezones" type="abstract operation">
<h1>
AvailableTimeZones (
): a List of Strings
</h1>
<dl class="header">
<dt>description</dt>
<dd>The returned List is a sorted List of supported Zone and Link names in the IANA Time Zone Database.</dd>
</dl>

<p>
An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the AvailableTimeZones abstract operation as specified in the ECMA-402 specification.
</p>
<p>
The minimum implementation of AvailableTimeZones for ECMAScript implementations that do not include local political rules for any time zones, performs the following steps when called:
</p>

<emu-alg>
1. Return « *"UTC"* ».
</emu-alg>
</emu-clause>
</emu-clause>

<emu-clause id="sec-temporal-timezone-constructor">
Expand Down Expand Up @@ -137,7 +156,7 @@ <h1>Temporal.TimeZone ( _identifier_ )</h1>
1. Set _identifier_ to ? ToString(_identifier_).
1. Let _parseResult_ be ParseText(StringToCodePoints(_identifier_), |TimeZoneNumericUTCOffset|).
1. If _parseResult_ is a List of errors, then
1. If ! IsValidTimeZoneName(_identifier_) is *false*, then
1. If IsValidTimeZoneName(_identifier_) is *false*, then
1. Throw a *RangeError* exception.
1. Set _identifier_ to ! CanonicalizeTimeZoneName(_identifier_).
1. Return ? CreateTemporalTimeZone(_identifier_, NewTarget).
Expand Down Expand Up @@ -623,7 +642,7 @@ <h1>ToTemporalTimeZone ( _temporalTimeZoneLike_ )</h1>
1. If ParseText(StringToCodePoints(_parseResult_.[[Name]], |TimeZoneNumericUTCOffset|)) is not a List of errors, then
1. If _parseResult_.[[OffsetString]] is not *undefined*, and ! ParseTimeZoneOffsetString(_parseResult_.[[OffsetString]]) &ne; ! ParseTimeZoneOffsetString(_parseResult_.[[Name]]), throw a *RangeError* exception.
1. Else,
1. If ! IsValidTimeZoneName(_parseResult_.[[Name]]) is *false*, throw a *RangeError* exception.
1. If IsValidTimeZoneName(_parseResult_.[[Name]]) is *false*, throw a *RangeError* exception.
1. Return ! CreateTemporalTimeZone(! CanonicalizeTimeZoneName(_parseResult_.[[Name]])).
1. If _parseResult_.[[Z]] is *true*, return ! CreateTemporalTimeZone(*"UTC"*).
1. Return ! CreateTemporalTimeZone(_parseResult_.[[OffsetString]]).
Expand Down
2 changes: 1 addition & 1 deletion spec/zoneddatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -1178,7 +1178,7 @@ <h1>
1. Let _timeZoneName_ be _result_.[[TimeZoneName]].
1. Assert: _timeZoneName_ is not *undefined*.
1. If ParseText(StringToCodePoints(_timeZoneName_), |TimeZoneNumericUTCOffset|) is a List of errors, then
1. If ! IsValidTimeZoneName(_timeZoneName_) is *false*, throw a *RangeError* exception.
1. If IsValidTimeZoneName(_timeZoneName_) is *false*, throw a *RangeError* exception.
1. Set _timeZoneName_ to ! CanonicalizeTimeZoneName(_timeZoneName_).
1. Let _offsetString_ be _result_.[[TimeZoneOffsetString]].
1. If _result_.[[TimeZoneZ]] is *true*, then
Expand Down

0 comments on commit 39f890b

Please sign in to comment.