From c3eb4cf9430a5dff9668a3e0fc4e925f73c8373f Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 23 Jan 2024 18:04:08 -0800 Subject: [PATCH] Editorial: Parameterize UTCOffset grammar Instead of two separate productions UTCOffsetSubMinutePrecision and UTCOffsetMinutePrecision, we can have one UTCOffset production with a SubMinutePrecision parameter. --- polyfill/test/validStrings.mjs | 31 ++++++++++++++++++------------- spec/abstractops.html | 20 +++++++------------- spec/intl.html | 2 +- spec/mainadditions.html | 6 +++--- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/polyfill/test/validStrings.mjs b/polyfill/test/validStrings.mjs index f494499023..7c5f1f6d9e 100644 --- a/polyfill/test/validStrings.mjs +++ b/polyfill/test/validStrings.mjs @@ -245,23 +245,28 @@ const timeFraction = withCode(temporalDecimalFraction, (data, result) => { data.microsecond = +fraction.slice(3, 6); data.nanosecond = +fraction.slice(6, 9); }); + function saveOffset(data, result) { data.offset = ES.ParseDateTimeUTCOffset(result); } - -const utcOffsetWithSubMinuteComponents = (extended) => - seq(temporalSign, hour, timeSeparator(extended), minuteSecond, timeSeparator(extended), minuteSecond, [ - temporalDecimalFraction +const utcOffset = (subMinutePrecision) => + seq(temporalSign, hour, [ + choice( + seq( + timeSeparator(true), + minuteSecond, + subMinutePrecision ? [timeSeparator(true), minuteSecond, [temporalDecimalFraction]] : empty + ), + seq( + timeSeparator(false), + minuteSecond, + subMinutePrecision ? [timeSeparator(false), minuteSecond, [temporalDecimalFraction]] : empty + ) + ) ]); -const utcOffsetMinutePrecision = seq(temporalSign, hour, [ - choice(seq(timeSeparator(true), minuteSecond), seq(timeSeparator(false), minuteSecond)) -]); -const utcOffsetSubMinutePrecision = withCode( - choice(utcOffsetMinutePrecision, utcOffsetWithSubMinuteComponents(true), utcOffsetWithSubMinuteComponents(false)), - saveOffset -); -const dateTimeUTCOffset = (z) => (z ? choice(utcDesignator, utcOffsetSubMinutePrecision) : utcOffsetSubMinutePrecision); -const timeZoneUTCOffsetName = utcOffsetMinutePrecision; +const dateTimeUTCOffset = (z) => + z ? choice(utcDesignator, withCode(utcOffset(true), saveOffset)) : withCode(utcOffset(true), saveOffset); +const timeZoneUTCOffsetName = utcOffset(false); const timeZoneIANAName = choice(...timezoneNames); const timeZoneIdentifier = withCode( choice(timeZoneUTCOffsetName, timeZoneIANAName), diff --git a/spec/abstractops.html b/spec/abstractops.html index 984476bf32..5ade797e0f 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -1278,28 +1278,22 @@

ISO 8601 grammar

TimeFraction ::: TemporalDecimalFraction - UTCOffsetWithSubMinuteComponents[Extended] ::: - TemporalSign Hour TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TemporalDecimalFraction? - NormalizedUTCOffset ::: ASCIISign Hour TimeSeparator[+Extended] MinuteSecond - UTCOffsetMinutePrecision ::: + UTCOffset[SubMinutePrecision] ::: TemporalSign Hour TemporalSign Hour TimeSeparator[+Extended] MinuteSecond TemporalSign Hour TimeSeparator[~Extended] MinuteSecond - - UTCOffsetSubMinutePrecision ::: - UTCOffsetMinutePrecision - UTCOffsetWithSubMinuteComponents[+Extended] - UTCOffsetWithSubMinuteComponents[~Extended] + [+SubMinutePrecision] TemporalSign Hour TimeSeparator[+Extended] MinuteSecond TimeSeparator[+Extended] MinuteSecond TemporalDecimalFraction? + [+SubMinutePrecision] TemporalSign Hour TimeSeparator[~Extended] MinuteSecond TimeSeparator[~Extended] MinuteSecond TemporalDecimalFraction? DateTimeUTCOffset[Z] ::: [+Z] UTCDesignator - UTCOffsetSubMinutePrecision + UTCOffset[+SubMinutePrecision] TimeZoneUTCOffsetName ::: - UTCOffsetMinutePrecision + UTCOffset[~SubMinutePrecision] TZLeadingChar ::: Alpha @@ -1631,8 +1625,8 @@

1. Set _timeZoneResult_.[[TimeZoneAnnotation]] to CodePointsToString(_identifier_). 1. If _parseResult_ contains a |UTCDesignator| Parse Node, then 1. Set _timeZoneResult_.[[Z]] to *true*. - 1. Else if _parseResult_ contains a |UTCOffsetSubMinutePrecision| Parse Node, then - 1. Let _offset_ be the source text matched by the |UTCOffsetSubMinutePrecision| Parse Node contained within _parseResult_. + 1. Else if _parseResult_ contains a |UTCOffset[+SubMinutePrecision]| Parse Node, then + 1. Let _offset_ be the source text matched by the |UTCOffset[+SubMinutePrecision]| Parse Node contained within _parseResult_. 1. Set _timeZoneResult_.[[OffsetString]] to CodePointsToString(_offset_). 1. Return the Record { [[Year]]: _yearMV_, diff --git a/spec/intl.html b/spec/intl.html index ba25a18dda..1650b79e0a 100644 --- a/spec/intl.html +++ b/spec/intl.html @@ -650,7 +650,7 @@

1. If _toLocaleStringTimeZone_ is present, throw a *TypeError* exception. 1. Set _timeZone_ to ? ToString(_timeZone_). 1. If IsTimeZoneOffsetString(_timeZone_) is *true*, then - 1. Let _parseResult_ be ParseText(StringToCodePoints(_timeZone_), |UTCOffset||UTCOffsetMinutePrecision|). + 1. Let _parseResult_ be ParseText(StringToCodePoints(_timeZone_), |UTCOffset||UTCOffset[~SubMinutePrecision]|). 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? ParseDateTimeUTCOffset(_timeZone_). diff --git a/spec/mainadditions.html b/spec/mainadditions.html index 977ce9b0aa..5f9f1d28d9 100644 --- a/spec/mainadditions.html +++ b/spec/mainadditions.html @@ -252,8 +252,8 @@

Time Zone Offset String FormatFormats

ECMAScript defines string interchange formats for UTC offsets, derived from ISO 8601. - UTC offsets that represent offset time zone identifiers, or that are intended for interoperability with ISO 8601, use only hours and minutes and are specified by |UTCOffsetMinutePrecision|. - UTC offsets that represent the offset of a named or custom time zone can be more precise, and are specified by |UTCOffsetSubMinutePrecision|. + UTC offsets that represent offset time zone identifiers, or that are intended for interoperability with ISO 8601, use only hours and minutes and are specified by |UTCOffset[~SubMinutePrecision]|. + UTC offsets that represent the offset of a named or custom time zone can be more precise, and are specified by |UTCOffset[+SubMinutePrecision]|.

These formats are described by the ISO String grammar in . @@ -461,7 +461,7 @@

- 1. Let _parseResult_ be ParseText(StringToCodePoints(_offsetString_), |UTCOffset||UTCOffsetSubMinutePrecision|). + 1. Let _parseResult_ be ParseText(StringToCodePoints(_offsetString_), |UTCOffset||UTCOffset[+SubMinutePrecision]|). 1. Assert: _parseResult_ is not a List of errors. 1. If _parseResult_ is a List of errors, throw a *RangeError* exception. 1. Assert: _parseResult_ contains a |TemporalSign| Parse Node.