diff --git a/polyfill/test/validStrings.mjs b/polyfill/test/validStrings.mjs index ef9df639a..b5ca1af03 100644 --- a/polyfill/test/validStrings.mjs +++ b/polyfill/test/validStrings.mjs @@ -245,24 +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 = (plain) => - plain ? utcOffsetSubMinutePrecision : choice(utcDesignator, utcOffsetSubMinutePrecision); -const timeZoneUTCOffsetName = utcOffsetMinutePrecision; + plain ? withCode(utcOffset(true), saveOffset) : choice(utcDesignator, 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 63612967d..664bff068 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -1261,28 +1261,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[Plain] ::: [~Plain] UTCDesignator - UTCOffsetSubMinutePrecision + UTCOffset[+SubMinutePrecision] TimeZoneUTCOffsetName ::: - UTCOffsetMinutePrecision + UTCOffset[~SubMinutePrecision] TZLeadingChar ::: Alpha @@ -1604,8 +1598,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. Let _calendar_ be *undefined*. 1. Let _calendarWasCritical_ be *false*. diff --git a/spec/intl.html b/spec/intl.html index c0cd53d76..4dd3dc13d 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 f9b853f9e..00b527eb9 100644 --- a/spec/mainadditions.html +++ b/spec/mainadditions.html @@ -302,8 +302,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 . @@ -511,7 +511,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.