From a5571764f670d4259371295a481e1a3eab1b7c38 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Thu, 10 Jul 2025 18:20:18 -0700 Subject: [PATCH 1/7] Editorial: Split GetTemporalUnitValuedOption with ValidateTemporalUnitValue --- spec/abstractops.html | 67 +++++++++++++++++++++++------------------ spec/duration.html | 12 +++++--- spec/instant.html | 6 ++-- spec/plaindatetime.html | 6 ++-- spec/plaintime.html | 6 ++-- spec/zoneddatetime.html | 6 ++-- 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index 2ae3fadbd..55cf3952d 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -548,44 +548,26 @@

GetTemporalUnitValuedOption ( _options_: an Object, _key_: a property key, - _unitGroup_: ~date~, ~time~, or ~datetime~, - _default_: ~required~, ~unset~, ~auto~, or a Temporal unit, - optional _extraValues_: a List of either Temporal units or ~auto~, + _default_: ~required~ or ~unset~, ): either a normal completion containing either a Temporal unit, ~unset~, or ~auto~, or a throw completion

description
-
It attempts to read from the specified property of _options_ a Temporal unit that is covered by the union of _unitGroup_ and _extraValues_, substituting _default_ if the property value is *undefined*.
+
It attempts to read a Temporal unit from the specified property of _options_.

Both singular and plural unit names are accepted, but only the singular form is used internally.

- 1. Let _allowedValues_ be a new empty List. + 1. Let _allowedStrings_ be « *"auto"* ». 1. For each row of , except the header row, in table order, do - 1. Let _unit_ be the value in the "Value" column of the row. - 1. If the "Category" column of the row is ~date~ and _unitGroup_ is ~date~ or ~datetime~, append _unit_ to _allowedValues_. - 1. Else if the "Category" column of the row is ~time~ and _unitGroup_ is ~time~ or ~datetime~, append _unit_ to _allowedValues_. - 1. If _extraValues_ is present, then - 1. Set _allowedValues_ to the list-concatenation of _allowedValues_ and _extraValues_. + 1. Let _singularName_ be the value in the "Singular property name" column of the row. + 1. Append _singularName_ to _allowedStrings_. + 1. Let _pluralName_ be the value in the "Plural property name" column of the row. + 1. Append _pluralName_ to _allowedStrings_. + 1. NOTE: For each singular Temporal unit name that is contained within _allowedStrings_, the corresponding plural name is also contained within it. 1. If _default_ is ~unset~, then 1. Let _defaultValue_ be *undefined*. - 1. Else if _default_ is ~required~, then - 1. Let _defaultValue_ be ~required~. - 1. Else if _default_ is ~auto~, then - 1. Append _default_ to _allowedValues_. - 1. Let _defaultValue_ be *"auto"*. 1. Else, - 1. Assert: _allowedValues_ contains _default_. - 1. Let _defaultValue_ be the value in the "Singular property name" column of corresponding to the row with _default_ in the "Value" column. - 1. Let _allowedStrings_ be a new empty List. - 1. For each element _value_ of _allowedValues_, do - 1. If _value_ is ~auto~, then - 1. Append *"auto"* to _allowedStrings_. - 1. Else, - 1. Let _singularName_ be the value in the "Singular property name" column of corresponding to the row with _value_ in the "Value" column. - 1. Append _singularName_ to _allowedStrings_. - 1. Let _pluralName_ be the value in the "Plural property name" column of the corresponding row. - 1. Append _pluralName_ to _allowedStrings_. - 1. NOTE: For each singular Temporal unit name that is contained within _allowedStrings_, the corresponding plural name is also contained within it. + 1. Let _defaultValue_ be _default_. 1. Let _value_ be ? GetOption(_options_, _key_, ~string~, _allowedStrings_, _defaultValue_). 1. If _value_ is *undefined*, return ~unset~. 1. If _value_ is *"auto"*, return ~auto~. @@ -593,6 +575,27 @@

+ +

+ ValidateTemporalUnitValue ( + _value_: a Temporal unit, ~unset~, or ~auto~, + _unitGroup_: ~date~, ~time~, or ~datetime~, + optional _extraValues_: a List of either Temporal units or ~auto~, + ): either a normal completion containing ~unused~ or a throw completion +

+
+
description
+
It validates that the result of GetTemporalUnitValuedOption is covered by the union of _unitGroup_ and _extraValues_.
+
+ + 1. If _extraValues_ is present and _extraValues_ contains _value_, return ~unused~. + 1. Let _category_ be the value in the “Category” column of the row of whose “Value” column contains _value_. If there is no such row, throw a RangeError exception. + 1. If _category_ is ~date~ and _unitGroup_ is ~date~ or ~datetime~, return ~unused~. + 1. If _category_ is ~time~ and _unitGroup_ is ~time~ or ~datetime~, return ~unused~. + 1. Throw a RangeError exception. + +
+

GetTemporalRelativeToOption ( @@ -1864,13 +1867,19 @@

1. NOTE: The following steps read options and perform independent validation in alphabetical order. - 1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"largestUnit"*, _unitGroup_, ~auto~). + 1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"largestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_largestUnit_, _unitGroup_). + 1. If _largestUnit_ is ~unset~, then + 1. Set _largestUnit_ to ~auto~. 1. If _disallowedUnits_ contains _largestUnit_, throw a *RangeError* exception. 1. Let _roundingIncrement_ be ? GetRoundingIncrementOption(_options_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_options_, ~trunc~). 1. If _operation_ is ~since~, then 1. Set _roundingMode_ to NegateRoundingMode(_roundingMode_). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"smallestUnit"*, _unitGroup_, _fallbackSmallestUnit_). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"smallestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, _unitGroup_). + 1. If _smallestUnit_ is ~unset~, then + 1. Set _smallestUnit_ to _fallbackSmallestUnit_. 1. If _disallowedUnits_ contains _smallestUnit_, throw a *RangeError* exception. 1. Let _defaultLargestUnit_ be LargerOfTwoTemporalUnits(_smallestLargestDefaultUnit_, _smallestUnit_). 1. If _largestUnit_ is ~auto~, set _largestUnit_ to _defaultLargestUnit_. diff --git a/spec/duration.html b/spec/duration.html index 728e420c9..bb6d6b4e6 100644 --- a/spec/duration.html +++ b/spec/duration.html @@ -402,13 +402,15 @@

Temporal.Duration.prototype.round ( _roundTo_ )

1. Let _smallestUnitPresent_ be *true*. 1. Let _largestUnitPresent_ be *true*. 1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetTemporalRelativeToOption reads *"relativeTo"*, GetRoundingIncrementOption reads *"roundingIncrement"* and GetRoundingModeOption reads *"roundingMode"*). - 1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"largestUnit"*, ~datetime~, ~unset~, « ~auto~ »). + 1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"largestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_largestUnit_, ~datetime~, « ~auto~, ~unset~ »). 1. Let _relativeToRecord_ be ? GetTemporalRelativeToOption(_roundTo_). 1. Let _zonedRelativeTo_ be _relativeToRecord_.[[ZonedRelativeTo]]. 1. Let _plainRelativeTo_ be _relativeToRecord_.[[PlainRelativeTo]]. 1. Let _roundingIncrement_ be ? GetRoundingIncrementOption(_roundTo_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_roundTo_, ~half-expand~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~datetime~, ~unset~). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~datetime~, « ~unset~ »). 1. If _smallestUnit_ is ~unset~, then 1. Set _smallestUnitPresent_ to *false*. 1. Set _smallestUnit_ to ~nanosecond~. @@ -476,7 +478,8 @@

Temporal.Duration.prototype.total ( _totalOf_ )

1. Let _relativeToRecord_ be ? GetTemporalRelativeToOption(_totalOf_). 1. Let _zonedRelativeTo_ be _relativeToRecord_.[[ZonedRelativeTo]]. 1. Let _plainRelativeTo_ be _relativeToRecord_.[[PlainRelativeTo]]. - 1. Let _unit_ be ? GetTemporalUnitValuedOption(_totalOf_, *"unit"*, ~datetime~, ~required~). + 1. Let _unit_ be ? GetTemporalUnitValuedOption(_totalOf_, *"unit"*, ~required~). + 1. Perform ? ValidateTemporalUnitValue(_unit_, ~datetime~). 1. If _zonedRelativeTo_ is not *undefined*, then 1. Let _internalDuration_ be ToInternalDurationRecord(_duration_). 1. Let _timeZone_ be _zonedRelativeTo_.[[TimeZone]]. @@ -512,7 +515,8 @@

Temporal.Duration.prototype.toString ( [ _options_ ] )

1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetTemporalFractionalSecondDigitsOption reads *"fractionalSecondDigits"* and GetRoundingModeOption reads *"roundingMode"*). 1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~time~, ~unset~). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). 1. If _smallestUnit_ is ~hour~ or ~minute~, throw a *RangeError* exception. 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). 1. If _precision_.[[Unit]] is ~nanosecond~ and _precision_.[[Increment]] = 1, then diff --git a/spec/instant.html b/spec/instant.html index 07aab1c72..e74ec7dc8 100644 --- a/spec/instant.html +++ b/spec/instant.html @@ -193,7 +193,8 @@

Temporal.Instant.prototype.round ( _roundTo_ )

1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetRoundingIncrementOption reads *"roundingIncrement"* and GetRoundingModeOption reads *"roundingMode"*). 1. Let _roundingIncrement_ be ? GetRoundingIncrementOption(_roundTo_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_roundTo_, ~half-expand~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~time~, ~required~). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~required~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~). 1. If _smallestUnit_ is ~hour~, then 1. Let _maximum_ be HoursPerDay. 1. Else if _smallestUnit_ is ~minute~, then @@ -235,7 +236,8 @@

Temporal.Instant.prototype.toString ( [ _options_ ] )

1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetTemporalFractionalSecondDigitsOption reads *"fractionalSecondDigits"* and GetRoundingModeOption reads *"roundingMode"*). 1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~time~, ~unset~). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). 1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception. 1. Let _timeZone_ be ? Get(_resolvedOptions_, *"timeZone"*). 1. If _timeZone_ is not *undefined*, then diff --git a/spec/plaindatetime.html b/spec/plaindatetime.html index e561f2808..fb851d5b8 100644 --- a/spec/plaindatetime.html +++ b/spec/plaindatetime.html @@ -502,7 +502,8 @@

Temporal.PlainDateTime.prototype.round ( _roundTo_ )

1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetRoundingIncrementOption reads *"roundingIncrement"* and GetRoundingModeOption reads *"roundingMode"*). 1. Let _roundingIncrement_ be ? GetRoundingIncrementOption(_roundTo_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_roundTo_, ~half-expand~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~time~, ~required~, « ~day~ »). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~required~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~day~ »). 1. If _smallestUnit_ is ~day~, then 1. Let _maximum_ be 1. 1. Let _inclusive_ be *true*. @@ -541,7 +542,8 @@

Temporal.PlainDateTime.prototype.toString ( [ _options_ ] )

1. Let _showCalendar_ be ? GetTemporalShowCalendarNameOption(_resolvedOptions_). 1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~time~, ~unset~). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). 1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception. 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). 1. Let _result_ be RoundISODateTime(_plainDateTime_.[[ISODateTime]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). diff --git a/spec/plaintime.html b/spec/plaintime.html index 3078a4871..c0716186b 100644 --- a/spec/plaintime.html +++ b/spec/plaintime.html @@ -272,7 +272,8 @@

Temporal.PlainTime.prototype.round ( _roundTo_ )

1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetRoundingIncrementOption reads *"roundingIncrement"* and GetRoundingModeOption reads *"roundingMode"*). 1. Let _roundingIncrement_ be ? GetRoundingIncrementOption(_roundTo_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_roundTo_, ~half-expand~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~time~, ~required~). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~required~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~). 1. Let _maximum_ be MaximumTemporalDurationRoundingIncrement(_smallestUnit_). 1. Assert: _maximum_ is not ~unset~. 1. Perform ? ValidateTemporalRoundingIncrement(_roundingIncrement_, _maximum_, *false*). @@ -303,7 +304,8 @@

Temporal.PlainTime.prototype.toString ( [ _options_ ] )

1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetTemporalFractionalSecondDigitsOption reads *"fractionalSecondDigits"* and GetRoundingModeOption reads *"roundingMode"*). 1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~time~, ~unset~). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). 1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception. 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). 1. Let _roundResult_ be RoundTime(_plainTime_.[[Time]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). diff --git a/spec/zoneddatetime.html b/spec/zoneddatetime.html index 493a7754b..fd432f54d 100644 --- a/spec/zoneddatetime.html +++ b/spec/zoneddatetime.html @@ -633,7 +633,8 @@

Temporal.ZonedDateTime.prototype.round ( _roundTo_ )

1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetRoundingIncrementOption reads *"roundingIncrement"* and GetRoundingModeOption reads *"roundingMode"*). 1. Let _roundingIncrement_ be ? GetRoundingIncrementOption(_roundTo_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_roundTo_, ~half-expand~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~time~, ~required~, « ~day~ »). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~required~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~day~ »). 1. If _smallestUnit_ is ~day~, then 1. Let _maximum_ be 1. 1. Let _inclusive_ be *true*. @@ -692,7 +693,8 @@

Temporal.ZonedDateTime.prototype.toString ( [ _options_ ] )

1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _showOffset_ be ? GetTemporalShowOffsetOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). - 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~time~, ~unset~). + 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). 1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception. 1. Let _showTimeZone_ be ? GetTemporalShowTimeZoneNameOption(_resolvedOptions_). 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). From 0826805b67a253a36f4ac235b551752f74bd6c60 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 18 Jul 2025 16:30:40 -0700 Subject: [PATCH 2/7] Apply suggestions from code review Co-authored-by: Philip Chimento --- spec/abstractops.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index 55cf3952d..7a2ae2cc4 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -580,7 +580,7 @@

ValidateTemporalUnitValue ( _value_: a Temporal unit, ~unset~, or ~auto~, _unitGroup_: ~date~, ~time~, or ~datetime~, - optional _extraValues_: a List of either Temporal units or ~auto~, + optional _extraValues_: a List of either Temporal units or ~auto~ or ~unset~, ): either a normal completion containing ~unused~ or a throw completion

@@ -589,10 +589,10 @@

1. If _extraValues_ is present and _extraValues_ contains _value_, return ~unused~. - 1. Let _category_ be the value in the “Category” column of the row of whose “Value” column contains _value_. If there is no such row, throw a RangeError exception. + 1. Let _category_ be the value in the “Category” column of the row of whose “Value” column contains _value_. If there is no such row, throw a *RangeError* exception. 1. If _category_ is ~date~ and _unitGroup_ is ~date~ or ~datetime~, return ~unused~. 1. If _category_ is ~time~ and _unitGroup_ is ~time~ or ~datetime~, return ~unused~. - 1. Throw a RangeError exception. + 1. Throw a *RangeError* exception. From 9e0e9f1fe9066fc34705c4d09bf369d0e5a30743 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 18 Jul 2025 16:34:44 -0700 Subject: [PATCH 3/7] Review feedback in GetTemporalUnitValuedOption --- spec/abstractops.html | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index 7a2ae2cc4..a05ef21f6 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -557,12 +557,8 @@

Both singular and plural unit names are accepted, but only the singular form is used internally.

- 1. Let _allowedStrings_ be « *"auto"* ». - 1. For each row of , except the header row, in table order, do - 1. Let _singularName_ be the value in the "Singular property name" column of the row. - 1. Append _singularName_ to _allowedStrings_. - 1. Let _pluralName_ be the value in the "Plural property name" column of the row. - 1. Append _pluralName_ to _allowedStrings_. + 1. Let _allowedStrings_ be a List containing all values in the "Singular property name" and "Plural property name" columns of , except the header row. + 1. Append *"auto"* to _allowedStrings_. 1. NOTE: For each singular Temporal unit name that is contained within _allowedStrings_, the corresponding plural name is also contained within it. 1. If _default_ is ~unset~, then 1. Let _defaultValue_ be *undefined*. From 59508b69a13ea8d7966b1a84cd1fbd81153b00ac Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 18 Jul 2025 16:37:18 -0700 Subject: [PATCH 4/7] Add `~unset~` to allowed values --- spec/abstractops.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index a05ef21f6..364dc1a39 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -1864,7 +1864,7 @@

1. NOTE: The following steps read options and perform independent validation in alphabetical order. 1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"largestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_largestUnit_, _unitGroup_). + 1. Perform ? ValidateTemporalUnitValue(_largestUnit_, _unitGroup_, « ~unset~ »). 1. If _largestUnit_ is ~unset~, then 1. Set _largestUnit_ to ~auto~. 1. If _disallowedUnits_ contains _largestUnit_, throw a *RangeError* exception. @@ -1873,7 +1873,7 @@

1. If _operation_ is ~since~, then 1. Set _roundingMode_ to NegateRoundingMode(_roundingMode_). 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"smallestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, _unitGroup_). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, _unitGroup_, « ~unset~ »). 1. If _smallestUnit_ is ~unset~, then 1. Set _smallestUnit_ to _fallbackSmallestUnit_. 1. If _disallowedUnits_ contains _smallestUnit_, throw a *RangeError* exception. From c3bfb6ea1ac1fd3f3cfe0e11e7926593a1d9cdb9 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 18 Jul 2025 16:46:14 -0700 Subject: [PATCH 5/7] Always allow `~unset~` in the AO --- spec/abstractops.html | 5 +++-- spec/duration.html | 6 +++--- spec/instant.html | 2 +- spec/plaindatetime.html | 2 +- spec/plaintime.html | 2 +- spec/zoneddatetime.html | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index 364dc1a39..97d0d144b 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -584,6 +584,7 @@

It validates that the result of GetTemporalUnitValuedOption is covered by the union of _unitGroup_ and _extraValues_.
+ 1. If _value_ is ~unset~, return ~unused~. 1. If _extraValues_ is present and _extraValues_ contains _value_, return ~unused~. 1. Let _category_ be the value in the “Category” column of the row of whose “Value” column contains _value_. If there is no such row, throw a *RangeError* exception. 1. If _category_ is ~date~ and _unitGroup_ is ~date~ or ~datetime~, return ~unused~. @@ -1864,7 +1865,7 @@

1. NOTE: The following steps read options and perform independent validation in alphabetical order. 1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"largestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_largestUnit_, _unitGroup_, « ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_largestUnit_, _unitGroup_). 1. If _largestUnit_ is ~unset~, then 1. Set _largestUnit_ to ~auto~. 1. If _disallowedUnits_ contains _largestUnit_, throw a *RangeError* exception. @@ -1873,7 +1874,7 @@

1. If _operation_ is ~since~, then 1. Set _roundingMode_ to NegateRoundingMode(_roundingMode_). 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"smallestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, _unitGroup_, « ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, _unitGroup_). 1. If _smallestUnit_ is ~unset~, then 1. Set _smallestUnit_ to _fallbackSmallestUnit_. 1. If _disallowedUnits_ contains _smallestUnit_, throw a *RangeError* exception. diff --git a/spec/duration.html b/spec/duration.html index bb6d6b4e6..9400a4619 100644 --- a/spec/duration.html +++ b/spec/duration.html @@ -403,14 +403,14 @@

Temporal.Duration.prototype.round ( _roundTo_ )

1. Let _largestUnitPresent_ be *true*. 1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetTemporalRelativeToOption reads *"relativeTo"*, GetRoundingIncrementOption reads *"roundingIncrement"* and GetRoundingModeOption reads *"roundingMode"*). 1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"largestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_largestUnit_, ~datetime~, « ~auto~, ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_largestUnit_, ~datetime~, « ~auto~ »). 1. Let _relativeToRecord_ be ? GetTemporalRelativeToOption(_roundTo_). 1. Let _zonedRelativeTo_ be _relativeToRecord_.[[ZonedRelativeTo]]. 1. Let _plainRelativeTo_ be _relativeToRecord_.[[PlainRelativeTo]]. 1. Let _roundingIncrement_ be ? GetRoundingIncrementOption(_roundTo_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_roundTo_, ~half-expand~). 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_roundTo_, *"smallestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~datetime~, « ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~datetime~). 1. If _smallestUnit_ is ~unset~, then 1. Set _smallestUnitPresent_ to *false*. 1. Set _smallestUnit_ to ~nanosecond~. @@ -516,7 +516,7 @@

Temporal.Duration.prototype.toString ( [ _options_ ] )

1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~). 1. If _smallestUnit_ is ~hour~ or ~minute~, throw a *RangeError* exception. 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). 1. If _precision_.[[Unit]] is ~nanosecond~ and _precision_.[[Increment]] = 1, then diff --git a/spec/instant.html b/spec/instant.html index e74ec7dc8..9009d6b2c 100644 --- a/spec/instant.html +++ b/spec/instant.html @@ -237,7 +237,7 @@

Temporal.Instant.prototype.toString ( [ _options_ ] )

1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~). 1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception. 1. Let _timeZone_ be ? Get(_resolvedOptions_, *"timeZone"*). 1. If _timeZone_ is not *undefined*, then diff --git a/spec/plaindatetime.html b/spec/plaindatetime.html index fb851d5b8..5c35ccb10 100644 --- a/spec/plaindatetime.html +++ b/spec/plaindatetime.html @@ -543,7 +543,7 @@

Temporal.PlainDateTime.prototype.toString ( [ _options_ ] )

1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~). 1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception. 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). 1. Let _result_ be RoundISODateTime(_plainDateTime_.[[ISODateTime]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). diff --git a/spec/plaintime.html b/spec/plaintime.html index c0716186b..8982c6324 100644 --- a/spec/plaintime.html +++ b/spec/plaintime.html @@ -305,7 +305,7 @@

Temporal.PlainTime.prototype.toString ( [ _options_ ] )

1. Let _digits_ be ? GetTemporalFractionalSecondDigitsOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~). 1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception. 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). 1. Let _roundResult_ be RoundTime(_plainTime_.[[Time]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). diff --git a/spec/zoneddatetime.html b/spec/zoneddatetime.html index fd432f54d..6a7cbe5c6 100644 --- a/spec/zoneddatetime.html +++ b/spec/zoneddatetime.html @@ -694,7 +694,7 @@

Temporal.ZonedDateTime.prototype.toString ( [ _options_ ] )

1. Let _showOffset_ be ? GetTemporalShowOffsetOption(_resolvedOptions_). 1. Let _roundingMode_ be ? GetRoundingModeOption(_resolvedOptions_, ~trunc~). 1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~). - 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~, « ~unset~ »). + 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~). 1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception. 1. Let _showTimeZone_ be ? GetTemporalShowTimeZoneNameOption(_resolvedOptions_). 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). From 4529d02bccb2f64ed835b90831354b55b67ae18a Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 18 Jul 2025 16:47:01 -0700 Subject: [PATCH 6/7] Fix prose --- spec/abstractops.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index 97d0d144b..d61ab4484 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -581,7 +581,7 @@

description
-
It validates that the result of GetTemporalUnitValuedOption is covered by the union of _unitGroup_ and _extraValues_.
+
It validates that the result of GetTemporalUnitValuedOption is covered by the union of _unitGroup_, _extraValues_, and « ~unset~ ».
1. If _value_ is ~unset~, return ~unused~. From 78949941b6bd23adc709f9301b4328a30bb75bff Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Fri, 18 Jul 2025 16:49:01 -0700 Subject: [PATCH 7/7] Fix lint --- spec/abstractops.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index d61ab4484..56aa9e8a5 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -576,7 +576,7 @@

ValidateTemporalUnitValue ( _value_: a Temporal unit, ~unset~, or ~auto~, _unitGroup_: ~date~, ~time~, or ~datetime~, - optional _extraValues_: a List of either Temporal units or ~auto~ or ~unset~, + optional _extraValues_: a List of either Temporal units or ~auto~, ): either a normal completion containing ~unused~ or a throw completion