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.