From dad87650e083cbfd08188c66360cb31bd294f0b1 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Thu, 1 Jun 2023 11:10:38 -0400 Subject: [PATCH 1/3] Normative: Allow implementations to report their time zone as a UTC offset This aligns with ECMA-262, and therefore removes the DefaultTimeZone override. --- spec/annexes.html | 3 --- spec/datetimeformat.html | 8 ++++++-- spec/locales-currencies-tz.html | 15 +-------------- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/spec/annexes.html b/spec/annexes.html index dc252267..e0c62492 100644 --- a/spec/annexes.html +++ b/spec/annexes.html @@ -15,9 +15,6 @@

Implementation Dependent Behaviour

  • The default locale ()
  • -
  • - The default time zone () -
  • The set of available locales for each constructor ()
  • diff --git a/spec/datetimeformat.html b/spec/datetimeformat.html index 24c70e7c..38c6c548 100644 --- a/spec/datetimeformat.html +++ b/spec/datetimeformat.html @@ -679,7 +679,7 @@

    Properties of Intl.DateTimeFormat Instances

  • [[Locale]] is a String value with the language tag of the locale whose localization is used for formatting.
  • [[Calendar]] is a String value representing the Unicode Calendar Identifier used for formatting.
  • [[NumberingSystem]] is a String value representing the Unicode Number System Identifier used for formatting.
  • -
  • [[TimeZone]] is a String value that is a time zone identifier from the IANA Time Zone Database used for formatting.
  • +
  • [[TimeZone]] is a String value used for formatting that is either a time zone identifier from the IANA Time Zone Database or a UTC offset in ISO 8601 extended format.
  • [[Weekday]], [[Era]], [[Year]], [[Month]], [[Day]], [[DayPeriod]], [[Hour]], [[Minute]], [[Second]], [[TimeZoneName]] are each either *undefined*, indicating that the component is not used for formatting, or one of the String values given in , indicating how the component should be presented in the formatted output.
  • [[FractionalSecondDigits]] is either *undefined* or a positive, non-zero integer Number value indicating the fraction digits to be used for fractional seconds. Numbers will be rounded or padded with trailing zeroes if necessary.
  • [[HourCycle]] is a String value indicating whether the 12-hour format (*"h11"*, *"h12"*) or the 24-hour format (*"h23"*, *"h24"*) should be used. *"h11"* and *"h23"* start with hour 0 and go up to 11 and 23 respectively. *"h12"* and *"h24"* start with hour 1 and go up to 12 and 24. [[HourCycle]] is only used when [[Hour]] is not *undefined*.
  • @@ -1150,7 +1150,11 @@

    - 1. Let _offsetNs_ be GetNamedTimeZoneOffsetNanoseconds(_timeZoneIdentifier_, _epochNs_). + 1. If IsTimeZoneOffsetString(_timeZoneIdentifier_) is *true*, then + 1. Let _offsetNs_ be ParseTimeZoneOffsetString(_timeZoneIdentifier_). + 1. Else, + 1. Assert: IsValidTimeZoneName(_timeZoneIdentifier_) is *true*. + 1. Let _offsetNs_ be GetNamedTimeZoneOffsetNanoseconds(_timeZoneIdentifier_, _epochNs_). 1. Let _tz_ be ℝ(_epochNs_) + _offsetNs_. 1. If _calendar_ is *"gregory"*, then 1. Return a record with fields calculated from _tz_ according to . diff --git a/spec/locales-currencies-tz.html b/spec/locales-currencies-tz.html index 4f2c86be..d204d858 100644 --- a/spec/locales-currencies-tz.html +++ b/spec/locales-currencies-tz.html @@ -182,7 +182,7 @@

    IsValidTimeZoneName ( _timeZone_ )

    - Any value returned from DefaultTimeZone must be recognized as valid. + Any value returned from DefaultTimeZone that is not recognized as valid by IsTimeZoneOffsetString must be recognized as valid by IsValidTimeZoneName. @@ -203,19 +203,6 @@

    - -

    DefaultTimeZone ( ): a String

    - -
    -
    description
    -
    It returns a String value representing the host environment's current time zone, which is a valid () and canonicalized () time zone name.
    -
    - -

    - This definition supersedes the definition provided in es2024, . -

    -
    -

    AvailableCanonicalTimeZones ( From c3517cda176a82533df2f4e101aa5c5bda0cd3ac Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Thu, 1 Jun 2023 11:14:39 -0400 Subject: [PATCH 2/3] Normative: Allow ECMAScript code to specify UTC offset time zones Fixes #683 --- spec/datetimeformat.html | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/spec/datetimeformat.html b/spec/datetimeformat.html index 38c6c548..546f7b79 100644 --- a/spec/datetimeformat.html +++ b/spec/datetimeformat.html @@ -94,9 +94,13 @@

    1. Set _timeZone_ to DefaultTimeZone(). 1. Else, 1. Set _timeZone_ to ? ToString(_timeZone_). - 1. If the result of IsValidTimeZoneName(_timeZone_) is *false*, then - 1. Throw a *RangeError* exception. + 1. If IsTimeZoneOffsetString(_timeZone_) is *true*, then + 1. Let _offsetNanoseconds_ be ParseTimeZoneOffsetString(_timeZone_). + 1. Set _timeZone_ to FormatTimeZoneOffsetString(_offsetNanoseconds_). + 1. Else if IsValidTimeZoneName(_timeZone_) is *true*, then 1. Set _timeZone_ to CanonicalizeTimeZoneName(_timeZone_). + 1. Else, + 1. Throw a *RangeError* exception. 1. Set _dateTimeFormat_.[[TimeZone]] to _timeZone_. 1. Let _formatOptions_ be a new Record. 1. Set _formatOptions_.[[hourCycle]] to _hc_. @@ -164,6 +168,31 @@

    1. Return _dateTimeFormat_. + + +

    FormatTimeZoneOffsetString ( _offsetNanoseconds_ )

    + + 1. Assert: _offsetNanoseconds_ is an integer. + 1. If _offsetNanoseconds_ ≥ 0, let _sign_ be the code unit 0x002B (PLUS SIGN); otherwise, let _sign_ be the code unit 0x002D (HYPHEN-MINUS). + 1. Set _offsetNanoseconds_ to abs(_offsetNanoseconds_). + 1. Let _nanoseconds_ be _offsetNanoseconds_ modulo 109. + 1. Let _seconds_ be floor(_offsetNanoseconds_ / 109) modulo 60. + 1. Let _minutes_ be floor(_offsetNanoseconds_ / (6 × 1010)) modulo 60. + 1. Let _hours_ be floor(_offsetNanoseconds_ / (3.6 × 1012)). + 1. Let _h_ be ToZeroPaddedDecimalString(_hours_, 2). + 1. Let _m_ be ToZeroPaddedDecimalString(_minutes_, 2). + 1. Let _s_ be ToZeroPaddedDecimalString(_seconds_, 2). + 1. If _nanoseconds_ ≠ 0, then + 1. Let _fraction_ be ToZeroPaddedDecimalString(_nanoseconds_, 9). + 1. Set _fraction_ to the longest possible substring of _fraction_ starting at position 0 and not ending with the code unit 0x0030 (DIGIT ZERO). + 1. Let _post_ be the string-concatenation of the code unit 0x003A (COLON), _s_, the code unit 0x002E (FULL STOP), and _fraction_. + 1. Else if seconds ≠ 0, then + 1. Let _post_ be the string-concatenation of the code unit 0x003A (COLON) and _s_. + 1. Else, + 1. Let _post_ be the empty String. + 1. Return the string-concatenation of _sign_, _h_, the code unit 0x003A (COLON), _m_, and _post_. + +
    From 26ba452fad22ce915d324ab503f2a10982b221ff Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Thu, 7 Sep 2023 15:43:19 -0400 Subject: [PATCH 3/3] Normative: Drop support for sub-minute UTC offsets --- spec/datetimeformat.html | 45 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/spec/datetimeformat.html b/spec/datetimeformat.html index 546f7b79..00b59308 100644 --- a/spec/datetimeformat.html +++ b/spec/datetimeformat.html @@ -95,8 +95,13 @@

    1. Else, 1. Set _timeZone_ to ? ToString(_timeZone_). 1. If IsTimeZoneOffsetString(_timeZone_) is *true*, then + 1. Let _parseResult_ be ParseText(StringToCodePoints(_timeZone_), |UTCOffset|). + 1. Assert: _parseResult_ is a Parse Node. + 1. If _parseResult_ contains more than one |MinuteSecond| Parse Node, throw a *RangeError* exception. 1. Let _offsetNanoseconds_ be ParseTimeZoneOffsetString(_timeZone_). - 1. Set _timeZone_ to FormatTimeZoneOffsetString(_offsetNanoseconds_). + 1. Let _offsetMinutes_ be _offsetNanoseconds_ / (6 × 1010). + 1. Assert: _offsetMinutes_ is an integer. + 1. Set _timeZone_ to FormatOffsetTimeZoneIdentifier(_offsetMinutes_). 1. Else if IsValidTimeZoneName(_timeZone_) is *true*, then 1. Set _timeZone_ to CanonicalizeTimeZoneName(_timeZone_). 1. Else, @@ -169,28 +174,24 @@

    - -

    FormatTimeZoneOffsetString ( _offsetNanoseconds_ )

    + +

    + FormatOffsetTimeZoneIdentifier ( + _offsetMinutes_: an integer, + ): a String +

    +
    +
    description
    +
    + It formats a UTC offset, in minutes, into a UTC offset string formatted like ±HH:MM. +
    +
    - 1. Assert: _offsetNanoseconds_ is an integer. - 1. If _offsetNanoseconds_ ≥ 0, let _sign_ be the code unit 0x002B (PLUS SIGN); otherwise, let _sign_ be the code unit 0x002D (HYPHEN-MINUS). - 1. Set _offsetNanoseconds_ to abs(_offsetNanoseconds_). - 1. Let _nanoseconds_ be _offsetNanoseconds_ modulo 109. - 1. Let _seconds_ be floor(_offsetNanoseconds_ / 109) modulo 60. - 1. Let _minutes_ be floor(_offsetNanoseconds_ / (6 × 1010)) modulo 60. - 1. Let _hours_ be floor(_offsetNanoseconds_ / (3.6 × 1012)). - 1. Let _h_ be ToZeroPaddedDecimalString(_hours_, 2). - 1. Let _m_ be ToZeroPaddedDecimalString(_minutes_, 2). - 1. Let _s_ be ToZeroPaddedDecimalString(_seconds_, 2). - 1. If _nanoseconds_ ≠ 0, then - 1. Let _fraction_ be ToZeroPaddedDecimalString(_nanoseconds_, 9). - 1. Set _fraction_ to the longest possible substring of _fraction_ starting at position 0 and not ending with the code unit 0x0030 (DIGIT ZERO). - 1. Let _post_ be the string-concatenation of the code unit 0x003A (COLON), _s_, the code unit 0x002E (FULL STOP), and _fraction_. - 1. Else if seconds ≠ 0, then - 1. Let _post_ be the string-concatenation of the code unit 0x003A (COLON) and _s_. - 1. Else, - 1. Let _post_ be the empty String. - 1. Return the string-concatenation of _sign_, _h_, the code unit 0x003A (COLON), _m_, and _post_. + 1. If _offsetMinutes_ ≥ 0, let _sign_ be the code unit 0x002B (PLUS SIGN); otherwise, let _sign_ be the code unit 0x002D (HYPHEN-MINUS). + 1. Let _absoluteMinutes_ be abs(_offsetMinutes_). + 1. Let _hours_ be floor(_absoluteMinutes_ / 60). + 1. Let _minutes_ be _absoluteMinutes_ modulo 60. + 1. Return the string-concatenation of _sign_, ToZeroPaddedDecimalString(_hours_, 2), the code unit 0x003A (COLON), and ToZeroPaddedDecimalString(_minutes_, 2).