From 67943e94441ac878aae30593d01455a58d4bed22 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Thu, 10 Jul 2025 17:47:49 -0700 Subject: [PATCH 1/4] Normative: Delay validation of unit-valued options --- spec/instant.html | 2 +- spec/zoneddatetime.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/instant.html b/spec/instant.html index 9009d6b2c..b2560dfad 100644 --- a/spec/instant.html +++ b/spec/instant.html @@ -237,9 +237,9 @@

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. Let _timeZone_ be ? Get(_resolvedOptions_, *"timeZone"*). 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 1. Set _timeZone_ to ? ToTemporalTimeZoneIdentifier(_timeZone_). 1. Let _precision_ be ToSecondsStringPrecisionRecord(_smallestUnit_, _digits_). diff --git a/spec/zoneddatetime.html b/spec/zoneddatetime.html index 8b93bc441..3c6bb5dc3 100644 --- a/spec/zoneddatetime.html +++ b/spec/zoneddatetime.html @@ -694,9 +694,9 @@

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. Let _showTimeZone_ be ? GetTemporalShowTimeZoneNameOption(_resolvedOptions_). 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_). 1. Return TemporalZonedDateTimeToString(_zonedDateTime_, _precision_.[[Precision]], _showCalendar_, _showTimeZone_, _showOffset_, _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). From 1cffc02916b9dc50e311fe4464b95cfd4bf8c9be Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Thu, 10 Jul 2025 18:04:10 -0700 Subject: [PATCH 2/4] Normative: Re-order operations in GetDifferenceSettings --- spec/abstractops.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/abstractops.html b/spec/abstractops.html index b0bbee058..816927763 100644 --- a/spec/abstractops.html +++ b/spec/abstractops.html @@ -1837,15 +1837,15 @@

1. NOTE: The following steps read options and perform independent validation in alphabetical order. 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_, « ~auto~ »). 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"*, ~unset~). 1. Perform ? ValidateTemporalUnitValue(_smallestUnit_, _unitGroup_). 1. If _smallestUnit_ is ~unset~, then 1. Set _smallestUnit_ to _fallbackSmallestUnit_. From 91e9e352e85d64c85333f0a932705ba6c7a06a1b Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Mon, 4 Aug 2025 08:07:27 -0700 Subject: [PATCH 3/4] Polyfill: Update reference code to reflect normative change --- polyfill/lib/ecmascript.mjs | 8 ++++---- polyfill/lib/instant.mjs | 2 +- polyfill/lib/zoneddatetime.mjs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index e55c3d94a..f4ba5cff1 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -3623,6 +3623,10 @@ export function GetDifferenceSettings(op, options, group, disallowed, fallbackSm ]); let largestUnit = GetTemporalUnitValuedOption(options, 'largestUnit'); + const roundingIncrement = GetRoundingIncrementOption(options); + let roundingMode = GetRoundingModeOption(options, 'trunc'); + let smallestUnit = GetTemporalUnitValuedOption(options, 'smallestUnit'); + ValidateTemporalUnitValue(largestUnit, group, ['auto']); if (!largestUnit) largestUnit = 'auto'; if (Call(ArrayPrototypeIncludes, disallowed, [largestUnit])) { @@ -3631,12 +3635,8 @@ export function GetDifferenceSettings(op, options, group, disallowed, fallbackSm ); } - const roundingIncrement = GetRoundingIncrementOption(options); - - let roundingMode = GetRoundingModeOption(options, 'trunc'); if (op === 'since') roundingMode = NegateRoundingMode(roundingMode); - let smallestUnit = GetTemporalUnitValuedOption(options, 'smallestUnit'); ValidateTemporalUnitValue(smallestUnit, group); if (!smallestUnit) smallestUnit = fallbackSmallest; if (Call(ArrayPrototypeIncludes, disallowed, [smallestUnit])) { diff --git a/polyfill/lib/instant.mjs b/polyfill/lib/instant.mjs index 0e63d276f..8198643a8 100644 --- a/polyfill/lib/instant.mjs +++ b/polyfill/lib/instant.mjs @@ -109,9 +109,9 @@ export class Instant { const digits = ES.GetTemporalFractionalSecondDigitsOption(resolvedOptions); const roundingMode = ES.GetRoundingModeOption(resolvedOptions, 'trunc'); const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit'); + let timeZone = resolvedOptions.timeZone; ES.ValidateTemporalUnitValue(smallestUnit, 'time'); if (smallestUnit === 'hour') throw new RangeErrorCtor('smallestUnit must be a time unit other than "hour"'); - let timeZone = resolvedOptions.timeZone; if (timeZone !== undefined) timeZone = ES.ToTemporalTimeZoneIdentifier(timeZone); const { precision, unit, increment } = ES.ToSecondsStringPrecisionRecord(smallestUnit, digits); const ns = GetSlot(this, EPOCHNANOSECONDS); diff --git a/polyfill/lib/zoneddatetime.mjs b/polyfill/lib/zoneddatetime.mjs index ea38f5f9a..a1a236976 100644 --- a/polyfill/lib/zoneddatetime.mjs +++ b/polyfill/lib/zoneddatetime.mjs @@ -349,9 +349,9 @@ export class ZonedDateTime { const showOffset = ES.GetTemporalShowOffsetOption(resolvedOptions); const roundingMode = ES.GetRoundingModeOption(resolvedOptions, 'trunc'); const smallestUnit = ES.GetTemporalUnitValuedOption(resolvedOptions, 'smallestUnit'); + const showTimeZone = ES.GetTemporalShowTimeZoneNameOption(resolvedOptions); ES.ValidateTemporalUnitValue(smallestUnit, 'time'); if (smallestUnit === 'hour') throw new RangeErrorCtor('smallestUnit must be a time unit other than "hour"'); - const showTimeZone = ES.GetTemporalShowTimeZoneNameOption(resolvedOptions); const { precision, unit, increment } = ES.ToSecondsStringPrecisionRecord(smallestUnit, digits); return ES.TemporalZonedDateTimeToString(this, precision, showCalendar, showTimeZone, showOffset, { unit, From 93d7c246b555ebf01d6725e71783e262b8cd9464 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 22 Aug 2025 12:35:21 -0700 Subject: [PATCH 4/4] Update test262 --- polyfill/test262 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polyfill/test262 b/polyfill/test262 index a9ac87d31..b947715fd 160000 --- a/polyfill/test262 +++ b/polyfill/test262 @@ -1 +1 @@ -Subproject commit a9ac87d3175a05bba8482c621062f905ed30f3a4 +Subproject commit b947715fdda79a420b253821c1cc52272a77222d