Skip to content

Normative: Validate unit-valued options after all options are read #3130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 43 additions & 30 deletions spec/abstractops.html
Original file line number Diff line number Diff line change
Expand Up @@ -548,51 +548,58 @@ <h1>
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
</h1>
<dl class="header">
<dt>description</dt>
<dd>It attempts to read from the specified property of _options_ a Temporal unit that is <emu-not-ref>covered</emu-not-ref> by the union of _unitGroup_ and _extraValues_, substituting _default_ if the property value is *undefined*.</dd>
<dd>It attempts to read a Temporal unit from the specified property of _options_.</dd>
</dl>
<p>Both singular and plural unit names are accepted, but only the singular form is used internally.</p>
<emu-alg>
1. Let _allowedValues_ be a new empty List.
1. Let _allowedStrings_ be a new empty List.
1. Append *"auto"* to _allowedStrings_.
Comment on lines +560 to +561
Copy link
Collaborator

@gibson042 gibson042 Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested simplification:

Suggested change
1. Let _allowedStrings_ be a new empty List.
1. Append *"auto"* to _allowedStrings_.
1. Let _allowedStrings_ be « *"auto"* ».

1. For each row of <emu-xref href="#table-temporal-units"></emu-xref>, 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 <emu-xref href="#table-temporal-units"></emu-xref> 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 <emu-xref href="#table-temporal-units"></emu-xref> 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~.
1. Return the value in the "Value" column of <emu-xref href="#table-temporal-units"></emu-xref> corresponding to the row with _value_ in its "Singular property name" or "Plural property name" column.
</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-validatetemporalunitvaluedoption" type="abstract operation">
<h1>
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
</h1>
<dl class="header">
<dt>description</dt>
<dd>It validates that the result of GetTemporalUnitValuedOption is <emu-not-ref>covered</emu-not-ref> by the union of _unitGroup_ and _extraValues_.</dd>
</dl>
<emu-alg>
1. Let _allowedValues_ be a new empty List.
1. For each row of <emu-xref href="#table-temporal-units"></emu-xref>, 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. If _allowedValues_ does not contain _value_, throw a RangeError exception.
Comment on lines +592 to +599
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it makes sense to keep the allowedValues list at all.

Suggested change
1. Let _allowedValues_ be a new empty List.
1. For each row of <emu-xref href="#table-temporal-units"></emu-xref>, 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. If _allowedValues_ does not contain _value_, throw a RangeError exception.
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 <emu-xref href="#table-temporal-units"></emu-xref> 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.

</emu-alg>
</emu-clause>

<emu-clause id="sec-temporal-gettemporalrelativetooption" type="abstract operation">
<h1>
GetTemporalRelativeToOption (
Expand Down Expand Up @@ -1864,13 +1871,19 @@ <h1>
</dl>
<emu-alg>
1. NOTE: The following steps read options and perform independent validation in alphabetical order.
1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"largestUnit"*, _unitGroup_, ~auto~).
1. If _disallowedUnits_ contains _largestUnit_, throw a *RangeError* exception.
1. Let _largestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"largestUnit"*, ~unset~).
1. Let _roundingIncrement_ be ? GetRoundingIncrementOption(_options_).
1. Let _roundingMode_ be ? GetRoundingModeOption(_options_, ~trunc~).
1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"smallestUnit"*, ~unset~).
1. Perform ? ValidateTemporalUnitValue(_largestUnit_, _unitGroup_).
1. If _largestUnit_ is ~unset~, then
1. Set _largestUnit_ to ~auto~.
Comment on lines +1878 to +1880
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right to me... if largestUnit is ~unset~, wouldn't ValidateTemporalUnitValue(largestUnit, unitGroup) have already rejected it?

Suggested change
1. Perform ? ValidateTemporalUnitValue(_largestUnit_, _unitGroup_).
1. If _largestUnit_ is ~unset~, then
1. Set _largestUnit_ to ~auto~.
1. If _largestUnit_ is ~unset~ or ~auto~, set _largestUnit_ to ~auto~.
1. Else, perform ? ValidateTemporalUnitValue(_largestUnit_, _unitGroup_).

And likewise for the other call sites.

1. If _disallowedUnits_ contains _largestUnit_, throw a *RangeError* exception.
1. If _operation_ is ~since~, then
1. Set _roundingMode_ to NegateRoundingMode(_roundingMode_).
1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_options_, *"smallestUnit"*, _unitGroup_, _fallbackSmallestUnit_).
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_.
Expand Down
12 changes: 8 additions & 4 deletions spec/duration.html
Original file line number Diff line number Diff line change
Expand Up @@ -402,13 +402,15 @@ <h1>Temporal.Duration.prototype.round ( _roundTo_ )</h1>
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. 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(_largestUnit_, ~datetime~, « ~auto~ »).
1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~datetime~).
Comment on lines +412 to +413
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted above, it seems like these calls will reject ~unset~ values.

1. If _smallestUnit_ is ~unset~, then
1. Set _smallestUnitPresent_ to *false*.
1. Set _smallestUnit_ to ~nanosecond~.
Expand Down Expand Up @@ -476,7 +478,8 @@ <h1>Temporal.Duration.prototype.total ( _totalOf_ )</h1>
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]].
Expand Down Expand Up @@ -512,7 +515,8 @@ <h1>Temporal.Duration.prototype.toString ( [ _options_ ] )</h1>
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~).
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
Expand Down
8 changes: 5 additions & 3 deletions spec/instant.html
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ <h1>Temporal.Instant.prototype.round ( _roundTo_ )</h1>
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
Expand Down Expand Up @@ -235,9 +236,10 @@ <h1>Temporal.Instant.prototype.toString ( [ _options_ ] )</h1>
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. If _smallestUnit_ is ~hour~, throw a *RangeError* exception.
1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~).
1. Let _timeZone_ be ? Get(_resolvedOptions_, *"timeZone"*).
1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~).
1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception.
1. If _timeZone_ is not *undefined*, then
1. Set _timeZone_ to ? ToTemporalTimeZoneIdentifier(_timeZone_).
1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_).
Expand Down
6 changes: 4 additions & 2 deletions spec/plaindatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,8 @@ <h1>Temporal.PlainDateTime.prototype.round ( _roundTo_ )</h1>
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*.
Expand Down Expand Up @@ -541,7 +542,8 @@ <h1>Temporal.PlainDateTime.prototype.toString ( [ _options_ ] )</h1>
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~).
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_).
Expand Down
6 changes: 4 additions & 2 deletions spec/plaintime.html
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ <h1>Temporal.PlainTime.prototype.round ( _roundTo_ )</h1>
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*).
Expand Down Expand Up @@ -303,7 +304,8 @@ <h1>Temporal.PlainTime.prototype.toString ( [ _options_ ] )</h1>
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~).
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_).
Expand Down
8 changes: 5 additions & 3 deletions spec/zoneddatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,8 @@ <h1>Temporal.ZonedDateTime.prototype.round ( _roundTo_ )</h1>
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*.
Expand Down Expand Up @@ -692,9 +693,10 @@ <h1>Temporal.ZonedDateTime.prototype.toString ( [ _options_ ] )</h1>
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. If _smallestUnit_ is ~hour~, throw a *RangeError* exception.
1. Let _smallestUnit_ be ? GetTemporalUnitValuedOption(_resolvedOptions_, *"smallestUnit"*, ~unset~).
1. Let _showTimeZone_ be ? GetTemporalShowTimeZoneNameOption(_resolvedOptions_).
1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, ~time~).
1. If _smallestUnit_ is ~hour~, throw a *RangeError* exception.
1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_).
1. Return TemporalZonedDateTimeToString(_zonedDateTime_, _precision_.[[Precision]], _showCalendar_, _showTimeZone_, _showOffset_, _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_).
</emu-alg>
Expand Down