A Temporal.Duration object describes the difference in elapsed time between
two other Temporal objects of the same type: Instant, PlainDate,
PlainDateTime, PlainTime, PlainYearMonth, or ZonedDateTime. Objects of this
type are only created via the .since() and .until() methods of
these objects.
Properties of the Temporal.Duration Constructor
The value of the [[Prototype]] internal slot of the Temporal.Duration
constructor is the intrinsic object %Function.prototype%.
The Temporal.Duration constructor has the following properties:
Temporal.Duration.prototype
The initial value of `Temporal.Duration.prototype` is
%Temporal.Duration.prototype%.
This property has the attributes { [[Writable]]: *false*, [[Enumerable]]:
*false*, [[Configurable]]: *false* }.
Temporal.Duration.from ( _item_ )
The `Temporal.Duration.from` function performs the following steps when called:
1. Return ? ToTemporalDuration(_item_).
Temporal.Duration.compare ( _one_, _two_ [ , _options_ ] )
The `Temporal.Duration.compare` function performs the following steps when called:
1. Set _one_ to ? ToTemporalDuration(_one_).
1. Set _two_ to ? ToTemporalDuration(_two_).
1. Let _resolvedOptions_ be ? GetOptionsObject(_options_).
1. Let _relativeToRecord_ be ? GetTemporalRelativeToOption(_resolvedOptions_).
1. If _one_.[[Years]] = _two_.[[Years]], and _one_.[[Months]] = _two_.[[Months]], and _one_.[[Weeks]] = _two_.[[Weeks]], and _one_.[[Days]] = _two_.[[Days]], and _one_.[[Hours]] = _two_.[[Hours]], and _one_.[[Minutes]] = _two_.[[Minutes]], and _one_.[[Seconds]] = _two_.[[Seconds]], and _one_.[[Milliseconds]] = _two_.[[Milliseconds]], and _one_.[[Microseconds]] = _two_.[[Microseconds]], and _one_.[[Nanoseconds]] = _two_.[[Nanoseconds]], then
1. Return *+0*๐ฝ.
1. Let _zonedRelativeTo_ be _relativeToRecord_.[[ZonedRelativeTo]].
1. Let _plainRelativeTo_ be _relativeToRecord_.[[PlainRelativeTo]].
1. Let _largestUnit1_ be DefaultTemporalLargestUnit(_one_).
1. Let _largestUnit2_ be DefaultTemporalLargestUnit(_two_).
1. Let _duration1_ be ToInternalDurationRecord(_one_).
1. Let _duration2_ be ToInternalDurationRecord(_two_).
1. If _zonedRelativeTo_ is not *undefined*, and either TemporalUnitCategory(_largestUnit1_) or TemporalUnitCategory(_largestUnit2_) is ~date~, then
1. Let _timeZone_ be _zonedRelativeTo_.[[TimeZone]].
1. Let _calendar_ be _zonedRelativeTo_.[[Calendar]].
1. Let _after1_ be ? AddZonedDateTime(_zonedRelativeTo_.[[EpochNanoseconds]], _timeZone_, _calendar_, _duration1_, ~constrain~).
1. Let _after2_ be ? AddZonedDateTime(_zonedRelativeTo_.[[EpochNanoseconds]], _timeZone_, _calendar_, _duration2_, ~constrain~).
1. If _after1_ > _after2_, return *1*๐ฝ.
1. If _after1_ < _after2_, return *-1*๐ฝ.
1. Return *+0*๐ฝ.
1. If IsCalendarUnit(_largestUnit1_) is *true* or IsCalendarUnit(_largestUnit2_) is *true*, then
1. If _plainRelativeTo_ is *undefined*, throw a *RangeError* exception.
1. Let _days1_ be ? DateDurationDays(_duration1_.[[Date]], _plainRelativeTo_).
1. Let _days2_ be ? DateDurationDays(_duration2_.[[Date]], _plainRelativeTo_).
1. Else,
1. Let _days1_ be _one_.[[Days]].
1. Let _days2_ be _two_.[[Days]].
1. Let _timeDuration1_ be ? Add24HourDaysToTimeDuration(_duration1_.[[Time]], _days1_).
1. Let _timeDuration2_ be ? Add24HourDaysToTimeDuration(_duration2_.[[Time]], _days2_).
1. Return ๐ฝ(CompareTimeDuration(_timeDuration1_, _timeDuration2_)).
Properties of the Temporal.Duration Prototype Object
The Temporal.Duration prototype object
- is itself an ordinary object.
- is not a Temporal.Duration instance and doesn't have an [[InitializedTemporalDuration]] internal slot.
- has a [[Prototype]] internal slot whose value is %Object.prototype%.
Temporal.Duration.prototype.constructor
The initial value of `Temporal.Duration.prototype.constructor` is %Temporal.Duration%.
Temporal.Duration.prototype[ %Symbol.toStringTag% ]
The initial value of the %Symbol.toStringTag% property is the String value *"Temporal.Duration"*.
This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
get Temporal.Duration.prototype.years
`Temporal.Duration.prototype.years` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Years]]).
get Temporal.Duration.prototype.months
`Temporal.Duration.prototype.months` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Months]]).
get Temporal.Duration.prototype.weeks
`Temporal.Duration.prototype.weeks` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Weeks]]).
get Temporal.Duration.prototype.days
`Temporal.Duration.prototype.days` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Days]]).
get Temporal.Duration.prototype.hours
`Temporal.Duration.prototype.hours` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Hours]]).
get Temporal.Duration.prototype.minutes
`Temporal.Duration.prototype.minutes` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Minutes]]).
get Temporal.Duration.prototype.seconds
`Temporal.Duration.prototype.seconds` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Seconds]]).
get Temporal.Duration.prototype.milliseconds
`Temporal.Duration.prototype.milliseconds` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Milliseconds]]).
get Temporal.Duration.prototype.microseconds
`Temporal.Duration.prototype.microseconds` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Microseconds]]).
get Temporal.Duration.prototype.nanoseconds
`Temporal.Duration.prototype.nanoseconds` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(_duration_.[[Nanoseconds]]).
get Temporal.Duration.prototype.sign
`Temporal.Duration.prototype.sign` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ๐ฝ(DurationSign(_duration_)).
get Temporal.Duration.prototype.blank
`Temporal.Duration.prototype.blank` is an accessor property whose set accessor function is *undefined*.
Its get accessor function performs the following steps:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. If DurationSign(_duration_) = 0, return *true*.
1. Return *false*.
Temporal.Duration.prototype.with ( _temporalDurationLike_ )
The `Temporal.Duration.prototype.with` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Let _temporalDurationLike_ be ? ToTemporalPartialDurationRecord(_temporalDurationLike_).
1. If _temporalDurationLike_.[[Years]] is not *undefined*, then
1. Let _years_ be _temporalDurationLike_.[[Years]].
1. Else,
1. Let _years_ be _duration_.[[Years]].
1. If _temporalDurationLike_.[[Months]] is not *undefined*, then
1. Let _months_ be _temporalDurationLike_.[[Months]].
1. Else,
1. Let _months_ be _duration_.[[Months]].
1. If _temporalDurationLike_.[[Weeks]] is not *undefined*, then
1. Let _weeks_ be _temporalDurationLike_.[[Weeks]].
1. Else,
1. Let _weeks_ be _duration_.[[Weeks]].
1. If _temporalDurationLike_.[[Days]] is not *undefined*, then
1. Let _days_ be _temporalDurationLike_.[[Days]].
1. Else,
1. Let _days_ be _duration_.[[Days]].
1. If _temporalDurationLike_.[[Hours]] is not *undefined*, then
1. Let _hours_ be _temporalDurationLike_.[[Hours]].
1. Else,
1. Let _hours_ be _duration_.[[Hours]].
1. If _temporalDurationLike_.[[Minutes]] is not *undefined*, then
1. Let _minutes_ be _temporalDurationLike_.[[Minutes]].
1. Else,
1. Let _minutes_ be _duration_.[[Minutes]].
1. If _temporalDurationLike_.[[Seconds]] is not *undefined*, then
1. Let _seconds_ be _temporalDurationLike_.[[Seconds]].
1. Else,
1. Let _seconds_ be _duration_.[[Seconds]].
1. If _temporalDurationLike_.[[Milliseconds]] is not *undefined*, then
1. Let _milliseconds_ be _temporalDurationLike_.[[Milliseconds]].
1. Else,
1. Let _milliseconds_ be _duration_.[[Milliseconds]].
1. If _temporalDurationLike_.[[Microseconds]] is not *undefined*, then
1. Let _microseconds_ be _temporalDurationLike_.[[Microseconds]].
1. Else,
1. Let _microseconds_ be _duration_.[[Microseconds]].
1. If _temporalDurationLike_.[[Nanoseconds]] is not *undefined*, then
1. Let _nanoseconds_ be _temporalDurationLike_.[[Nanoseconds]].
1. Else,
1. Let _nanoseconds_ be _duration_.[[Nanoseconds]].
1. Return ? CreateTemporalDuration(_years_, _months_, _weeks_, _days_, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_).
Temporal.Duration.prototype.negated ( )
The `Temporal.Duration.prototype.negated` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return CreateNegatedTemporalDuration(_duration_).
Temporal.Duration.prototype.abs ( )
The `Temporal.Duration.prototype.abs` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ! CreateTemporalDuration(abs(_duration_.[[Years]]), abs(_duration_.[[Months]]), abs(_duration_.[[Weeks]]), abs(_duration_.[[Days]]), abs(_duration_.[[Hours]]), abs(_duration_.[[Minutes]]), abs(_duration_.[[Seconds]]), abs(_duration_.[[Milliseconds]]), abs(_duration_.[[Microseconds]]), abs(_duration_.[[Nanoseconds]])).
Temporal.Duration.prototype.add ( _other_ )
The `Temporal.Duration.prototype.add` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ? AddDurations(~add~, _duration_, _other_).
Temporal.Duration.prototype.subtract ( _other_ )
The `Temporal.Duration.prototype.subtract` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return ? AddDurations(~subtract~, _duration_, _other_).
Temporal.Duration.prototype.round ( _roundTo_ )
The `Temporal.Duration.prototype.round` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. If _roundTo_ is *undefined*, then
1. Throw a *TypeError* exception.
1. If _roundTo_ is a String, then
1. Let _paramString_ be _roundTo_.
1. Set _roundTo_ to OrdinaryObjectCreate(*null*).
1. Perform ! CreateDataPropertyOrThrow(_roundTo_, *"smallestUnit"*, _paramString_).
1. Else,
1. Set _roundTo_ to ? GetOptionsObject(_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 _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. If _smallestUnit_ is ~unset~, then
1. Set _smallestUnitPresent_ to *false*.
1. Set _smallestUnit_ to ~nanosecond~.
1. Let _existingLargestUnit_ be DefaultTemporalLargestUnit(_duration_).
1. Let _defaultLargestUnit_ be LargerOfTwoTemporalUnits(_existingLargestUnit_, _smallestUnit_).
1. If _largestUnit_ is ~unset~, then
1. Set _largestUnitPresent_ to *false*.
1. Set _largestUnit_ to _defaultLargestUnit_.
1. Else if _largestUnit_ is ~auto~, then
1. Set _largestUnit_ to _defaultLargestUnit_.
1. If _smallestUnitPresent_ is *false* and _largestUnitPresent_ is *false*, then
1. Throw a *RangeError* exception.
1. If LargerOfTwoTemporalUnits(_largestUnit_, _smallestUnit_) is not _largestUnit_, throw a *RangeError* exception.
1. Let _maximum_ be MaximumTemporalDurationRoundingIncrement(_smallestUnit_).
1. If _maximum_ is not ~unset~, perform ? ValidateTemporalRoundingIncrement(_roundingIncrement_, _maximum_, *false*).
1. If _roundingIncrement_ > 1, and _largestUnit_ is not _smallestUnit_, and TemporalUnitCategory(_smallestUnit_) is ~date~, throw a *RangeError* exception.
1. If _zonedRelativeTo_ is not *undefined*, then
1. Let _internalDuration_ be ToInternalDurationRecord(_duration_).
1. Let _timeZone_ be _zonedRelativeTo_.[[TimeZone]].
1. Let _calendar_ be _zonedRelativeTo_.[[Calendar]].
1. Let _relativeEpochNs_ be _zonedRelativeTo_.[[EpochNanoseconds]].
1. Let _targetEpochNs_ be ? AddZonedDateTime(_relativeEpochNs_, _timeZone_, _calendar_, _internalDuration_, ~constrain~).
1. Set _internalDuration_ to ? DifferenceZonedDateTimeWithRounding(_relativeEpochNs_, _targetEpochNs_, _timeZone_, _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_).
1. If TemporalUnitCategory(_largestUnit_) is ~date~, set _largestUnit_ to ~hour~.
1. Return ? TemporalDurationFromInternal(_internalDuration_, _largestUnit_).
1. If _plainRelativeTo_ is not *undefined*, then
1. Let _internalDuration_ be ToInternalDurationRecordWith24HourDays(_duration_).
1. Let _targetTime_ be AddTime(MidnightTimeRecord(), _internalDuration_.[[Time]]).
1. Let _calendar_ be _plainRelativeTo_.[[Calendar]].
1. Let _dateDuration_ be ! AdjustDateDurationRecord(_internalDuration_.[[Date]], _targetTime_.[[Days]]).
1. Let _targetDate_ be ? CalendarDateAdd(_calendar_, _plainRelativeTo_.[[ISODate]], _dateDuration_, ~constrain~).
1. Let _isoDateTime_ be CombineISODateAndTimeRecord(_plainRelativeTo_.[[ISODate]], MidnightTimeRecord()).
1. Let _targetDateTime_ be CombineISODateAndTimeRecord(_targetDate_, _targetTime_).
1. Set _internalDuration_ to ? DifferencePlainDateTimeWithRounding(_isoDateTime_, _targetDateTime_, _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_).
1. Return ? TemporalDurationFromInternal(_internalDuration_, _largestUnit_).
1. If IsCalendarUnit(_existingLargestUnit_) is *true*, or IsCalendarUnit(_largestUnit_) is *true*, throw a *RangeError* exception.
1. Assert: IsCalendarUnit(_smallestUnit_) is *false*.
1. Let _internalDuration_ be ToInternalDurationRecordWith24HourDays(_duration_).
1. If _smallestUnit_ is ~day~, then
1. Let _fractionalDays_ be TotalTimeDuration(_internalDuration_.[[Time]], ~day~).
1. Let _days_ be RoundNumberToIncrement(_fractionalDays_, _roundingIncrement_, _roundingMode_).
1. Let _dateDuration_ be ? CreateDateDurationRecord(0, 0, 0, _days_).
1. Set _internalDuration_ to CombineDateAndTimeDuration(_dateDuration_, 0).
1. Else,
1. Let _timeDuration_ be ? RoundTimeDuration(_internalDuration_.[[Time]], _roundingIncrement_, _smallestUnit_, _roundingMode_).
1. Set _internalDuration_ to CombineDateAndTimeDuration(ZeroDateDuration(), _timeDuration_).
1. Return ? TemporalDurationFromInternal(_internalDuration_, _largestUnit_).
Temporal.Duration.prototype.total ( _totalOf_ )
The `Temporal.Duration.prototype.total` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. If _totalOf_ is *undefined*, throw a *TypeError* exception.
1. If _totalOf_ is a String, then
1. Let _paramString_ be _totalOf_.
1. Set _totalOf_ to OrdinaryObjectCreate(*null*).
1. Perform ! CreateDataPropertyOrThrow(_totalOf_, *"unit"*, _paramString_).
1. Else,
1. Set _totalOf_ to ? GetOptionsObject(_totalOf_).
1. NOTE: The following steps read options and perform independent validation in alphabetical order (GetTemporalRelativeToOption reads *"relativeTo"*).
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. If _zonedRelativeTo_ is not *undefined*, then
1. Let _internalDuration_ be ToInternalDurationRecord(_duration_).
1. Let _timeZone_ be _zonedRelativeTo_.[[TimeZone]].
1. Let _calendar_ be _zonedRelativeTo_.[[Calendar]].
1. Let _relativeEpochNs_ be _zonedRelativeTo_.[[EpochNanoseconds]].
1. Let _targetEpochNs_ be ? AddZonedDateTime(_relativeEpochNs_, _timeZone_, _calendar_, _internalDuration_, ~constrain~).
1. Let _total_ be ? DifferenceZonedDateTimeWithTotal(_relativeEpochNs_, _targetEpochNs_, _timeZone_, _calendar_, _unit_).
1. Else if _plainRelativeTo_ is not *undefined*, then
1. Let _internalDuration_ be ToInternalDurationRecordWith24HourDays(_duration_).
1. Let _targetTime_ be AddTime(MidnightTimeRecord(), _internalDuration_.[[Time]]).
1. Let _calendar_ be _plainRelativeTo_.[[Calendar]].
1. Let _dateDuration_ be ! AdjustDateDurationRecord(_internalDuration_.[[Date]], _targetTime_.[[Days]]).
1. Let _targetDate_ be ? CalendarDateAdd(_calendar_, _plainRelativeTo_.[[ISODate]], _dateDuration_, ~constrain~).
1. Let _isoDateTime_ be CombineISODateAndTimeRecord(_plainRelativeTo_.[[ISODate]], MidnightTimeRecord()).
1. Let _targetDateTime_ be CombineISODateAndTimeRecord(_targetDate_, _targetTime_).
1. Let _total_ be ? DifferencePlainDateTimeWithTotal(_isoDateTime_, _targetDateTime_, _calendar_, _unit_).
1. Else,
1. Let _largestUnit_ be DefaultTemporalLargestUnit(_duration_).
1. If IsCalendarUnit(_largestUnit_) is *true*, or IsCalendarUnit(_unit_) is *true*, throw a *RangeError* exception.
1. Let _internalDuration_ be ToInternalDurationRecordWith24HourDays(_duration_).
1. Let _total_ be TotalTimeDuration(_internalDuration_.[[Time]], _unit_).
1. Return ๐ฝ(_total_).
Temporal.Duration.prototype.toString ( [ _options_ ] )
The `Temporal.Duration.prototype.toString` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Let _resolvedOptions_ be ? GetOptionsObject(_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. 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
1. Return TemporalDurationToString(_duration_, _precision_.[[Precision]]).
1. Let _largestUnit_ be DefaultTemporalLargestUnit(_duration_).
1. Let _internalDuration_ be ToInternalDurationRecord(_duration_).
1. Let _timeDuration_ be ? RoundTimeDuration(_internalDuration_.[[Time]], _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_).
1. Set _internalDuration_ to CombineDateAndTimeDuration(_internalDuration_.[[Date]], _timeDuration_).
1. Let _roundedLargestUnit_ be LargerOfTwoTemporalUnits(_largestUnit_, ~second~).
1. Let _roundedDuration_ be ? TemporalDurationFromInternal(_internalDuration_, _roundedLargestUnit_).
1. Return TemporalDurationToString(_roundedDuration_, _precision_.[[Precision]]).
Temporal.Duration.prototype.toJSON ( )
The `Temporal.Duration.prototype.toJSON` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return TemporalDurationToString(_duration_, ~auto~).
Temporal.Duration.prototype.toLocaleString ( [ _locales_ [ , _options_ ] ] )
An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement the `Temporal.Duration.prototype.toLocaleString` method as specified in the ECMA-402 specification.
If an ECMAScript implementation does not include the ECMA-402 API the following specification of the `Temporal.Duration.prototype.toLocaleString` method is used.
The `Temporal.Duration.prototype.toLocaleString` method performs the following steps when called:
1. Let _duration_ be the *this* value.
1. Perform ? RequireInternalSlot(_duration_, [[InitializedTemporalDuration]]).
1. Return TemporalDurationToString(_duration_, ~auto~).
Temporal.Duration.prototype.valueOf ( )
The `Temporal.Duration.prototype.valueOf` method performs the following steps when called:
1. Throw a *TypeError* exception.
This method always throws, because in the absence of `valueOf()`, expressions with arithmetic operators such as `duration1 > duration2` would fall back to being equivalent to `duration1.toString() > duration2.toString()`.
Lexicographical comparison of serialized strings might not seem obviously wrong, because the result would sometimes be correct.
Implementations are encouraged to phrase the error message to point users to `Temporal.Duration.compare()` and/or `Temporal.Duration.prototype.toString()`.
Properties of Temporal.Duration Instances
Temporal.Duration instances are ordinary objects that inherit properties from the %Temporal.Duration.prototype% intrinsic object.
Temporal.Duration instances are initially created with the internal slots described in .
A float64-representable integer is an integer that is exactly representable as a Number value.
That is, for a float64-representable integer _x_, it must hold that โ(๐ฝ(_x_)) = _x_.
The use of float64-representable integers here is intended so that implementations can store and do arithmetic on Duration fields using 64-bit floating-point values.
|
Internal Slot
|
Description
|
|
[[InitializedTemporalDuration]]
|
The only specified use of this slot is for distinguishing Temporal.Duration instances from other objects.
|
|
[[Years]]
|
A float64-representable integer representing the number of years in the duration.
|
|
[[Months]]
|
A float64-representable integer representing the number of months in the duration.
|
|
[[Weeks]]
|
A float64-representable integer representing the number of weeks in the duration.
|
|
[[Days]]
|
A float64-representable integer representing the number of days in the duration.
|
|
[[Hours]]
|
A float64-representable integer representing the number of hours in the duration.
|
|
[[Minutes]]
|
A float64-representable integer representing the number of minutes in the duration.
|
|
[[Seconds]]
|
A float64-representable integer representing the number of seconds in the duration.
|
|
[[Milliseconds]]
|
A float64-representable integer representing the number of milliseconds in the duration.
|
|
[[Microseconds]]
|
A float64-representable integer representing the number of microseconds in the duration.
|
|
[[Nanoseconds]]
|
A float64-representable integer representing the number of nanoseconds in the duration.
|
Abstract Operations
Date Duration Records
A Date Duration Record is a Record value used to represent the portion of a Temporal.Duration object that deals with calendar date units.
Date Duration Records are produced by the abstract operation CreateDateDurationRecord, among others.
Date Duration Records have the fields listed in .
| Field Name |
Value |
Meaning |
| [[Years]] |
a float64-representable integer |
The number of years in the duration.
|
| [[Months]] |
a float64-representable integer |
The number of months in the duration.
|
| [[Weeks]] |
a float64-representable integer |
The number of weeks in the duration.
|
| [[Days]] |
a float64-representable integer |
The number of days in the duration.
|
Partial Duration Records
A partial Duration Record is a Record value used to represent a portion of a Temporal.Duration object, in which it is not required that all the fields be specified.
Partial Duration Records have the fields listed in .
Additionally, Partial Duration Records must have at least one field that is not *undefined*.
| Field Name |
Value |
Meaning |
| [[Years]] |
a float64-representable integer or *undefined* |
The number of years in the duration.
|
| [[Months]] |
a float64-representable integer or *undefined* |
The number of months in the duration.
|
| [[Weeks]] |
a float64-representable integer or *undefined* |
The number of weeks in the duration.
|
| [[Days]] |
a float64-representable integer or *undefined* |
The number of days in the duration.
|
| [[Hours]] |
a float64-representable integer or *undefined* |
The number of hours in the duration.
|
| [[Minutes]] |
a float64-representable integer or *undefined* |
The number of minutes in the duration.
|
| [[Seconds]] |
a float64-representable integer or *undefined* |
The number of seconds in the duration.
|
| [[Milliseconds]] |
a float64-representable integer or *undefined* |
The number of milliseconds in the duration.
|
| [[Microseconds]] |
a float64-representable integer or *undefined* |
The number of microseconds in the duration.
|
| [[Nanoseconds]] |
a float64-representable integer or *undefined* |
The number of nanoseconds in the duration.
|
Internal Duration Records
A Internal Duration Record is a Record value used to represent the combination of a Date Duration Record with a time duration.
Such Records are used by operations that deal with both date and time portions of durations, such as RoundTimeDuration.
A time duration is an integer in the inclusive interval from -maxTimeDuration to maxTimeDuration, where
maxTimeDuration = 253 ร 109 - 1 = 9,007,199,254,740,991,999,999,999
It represents the portion of a Temporal.Duration object that deals with time units, but as a combined value of total nanoseconds.
Internal Duration Records have the fields listed in .
| Field Name |
Value |
Meaning |
| [[Date]] |
a Date Duration Record |
The date portion of the duration.
|
| [[Time]] |
a time duration |
The time portion of the duration.
|
ZeroDateDuration ( ): a Date Duration Record
1. Return ! CreateDateDurationRecord(0, 0, 0, 0).
ToInternalDurationRecord (
_duration_: a Temporal.Duration,
): an Internal Duration Record
1. Let _dateDuration_ be ! CreateDateDurationRecord(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]]).
1. Let _timeDuration_ be TimeDurationFromComponents(_duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]).
1. Return CombineDateAndTimeDuration(_dateDuration_, _timeDuration_).
ToInternalDurationRecordWith24HourDays (
_duration_: a Temporal.Duration,
): an Internal Duration Record
1. Let _timeDuration_ be TimeDurationFromComponents(_duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]).
1. Set _timeDuration_ to ! Add24HourDaysToTimeDuration(_timeDuration_, _duration_.[[Days]]).
1. Let _dateDuration_ be ! CreateDateDurationRecord(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], 0).
1. Return CombineDateAndTimeDuration(_dateDuration_, _timeDuration_).
ToDateDurationRecordWithoutTime (
_duration_: a Temporal.Duration,
): a Date Duration Record
1. Let _internalDuration_ be ToInternalDurationRecordWith24HourDays(_duration_).
1. Let _days_ be truncate(_internalDuration_.[[Time]] / nsPerDay).
1. Return ! CreateDateDurationRecord(_internalDuration_.[[Date]].[[Years]], _internalDuration_.[[Date]].[[Months]], _internalDuration_.[[Date]].[[Weeks]], _days_).
TemporalDurationFromInternal (
_internalDuration_: an Internal Duration Record,
_largestUnit_: a Temporal unit,
): either a normal completion containing a Temporal.Duration, or a throw completion
1. Let _days_, _hours_, _minutes_, _seconds_, _milliseconds_, and _microseconds_ be 0.
1. Let _sign_ be TimeDurationSign(_internalDuration_.[[Time]]).
1. Let _nanoseconds_ be abs(_internalDuration_.[[Time]]).
1. If TemporalUnitCategory(_largestUnit_) is ~date~, then
1. Set _microseconds_ to floor(_nanoseconds_ / 1000).
1. Set _nanoseconds_ to _nanoseconds_ modulo 1000.
1. Set _milliseconds_ to floor(_microseconds_ / 1000).
1. Set _microseconds_ to _microseconds_ modulo 1000.
1. Set _seconds_ to floor(_milliseconds_ / 1000).
1. Set _milliseconds_ to _milliseconds_ modulo 1000.
1. Set _minutes_ to floor(_seconds_ / 60).
1. Set _seconds_ to _seconds_ modulo 60.
1. Set _hours_ to floor(_minutes_ / 60).
1. Set _minutes_ to _minutes_ modulo 60.
1. Set _days_ to floor(_hours_ / 24).
1. Set _hours_ to _hours_ modulo 24.
1. Else if _largestUnit_ is ~hour~, then
1. Set _microseconds_ to floor(_nanoseconds_ / 1000).
1. Set _nanoseconds_ to _nanoseconds_ modulo 1000.
1. Set _milliseconds_ to floor(_microseconds_ / 1000).
1. Set _microseconds_ to _microseconds_ modulo 1000.
1. Set _seconds_ to floor(_milliseconds_ / 1000).
1. Set _milliseconds_ to _milliseconds_ modulo 1000.
1. Set _minutes_ to floor(_seconds_ / 60).
1. Set _seconds_ to _seconds_ modulo 60.
1. Set _hours_ to floor(_minutes_ / 60).
1. Set _minutes_ to _minutes_ modulo 60.
1. Else if _largestUnit_ is ~minute~, then
1. Set _microseconds_ to floor(_nanoseconds_ / 1000).
1. Set _nanoseconds_ to _nanoseconds_ modulo 1000.
1. Set _milliseconds_ to floor(_microseconds_ / 1000).
1. Set _microseconds_ to _microseconds_ modulo 1000.
1. Set _seconds_ to floor(_milliseconds_ / 1000).
1. Set _milliseconds_ to _milliseconds_ modulo 1000.
1. Set _minutes_ to floor(_seconds_ / 60).
1. Set _seconds_ to _seconds_ modulo 60.
1. Else if _largestUnit_ is ~second~, then
1. Set _microseconds_ to floor(_nanoseconds_ / 1000).
1. Set _nanoseconds_ to _nanoseconds_ modulo 1000.
1. Set _milliseconds_ to floor(_microseconds_ / 1000).
1. Set _microseconds_ to _microseconds_ modulo 1000.
1. Set _seconds_ to floor(_milliseconds_ / 1000).
1. Set _milliseconds_ to _milliseconds_ modulo 1000.
1. Else if _largestUnit_ is ~millisecond~, then
1. Set _microseconds_ to floor(_nanoseconds_ / 1000).
1. Set _nanoseconds_ to _nanoseconds_ modulo 1000.
1. Set _milliseconds_ to floor(_microseconds_ / 1000).
1. Set _microseconds_ to _microseconds_ modulo 1000.
1. Else if _largestUnit_ is ~microsecond~, then
1. Set _microseconds_ to floor(_nanoseconds_ / 1000).
1. Set _nanoseconds_ to _nanoseconds_ modulo 1000.
1. Else,
1. Assert: _largestUnit_ is ~nanosecond~.
1. NOTE: When _largestUnit_ is ~millisecond~, ~microsecond~, or ~nanosecond~, _milliseconds_, _microseconds_, or _nanoseconds_ may be an unsafe integer. In this case, care must be taken when implementing the calculation using floating point arithmetic. It can be implemented in C++ using `std::fma()`. String manipulation will also give an exact result, since the multiplication is by a power of 10.
1. Return ? CreateTemporalDuration(_internalDuration_.[[Date]].[[Years]], _internalDuration_.[[Date]].[[Months]], _internalDuration_.[[Date]].[[Weeks]], _internalDuration_.[[Date]].[[Days]] + _days_ ร _sign_, _hours_ ร _sign_, _minutes_ ร _sign_, _seconds_ ร _sign_, _milliseconds_ ร _sign_, _microseconds_ ร _sign_, _nanoseconds_ ร _sign_).
CreateDateDurationRecord (
_years_: an integer,
_months_: an integer,
_weeks_: an integer,
_days_: an integer,
): either a normal completion containing a Date Duration Record or a throw completion
1. If IsValidDuration(_years_, _months_, _weeks_, _days_, 0, 0, 0, 0, 0, 0) is *false*, throw a *RangeError* exception.
1. Return Date Duration Record {
[[Years]]: โ(๐ฝ(_years_)),
[[Months]]: โ(๐ฝ(_months_)),
[[Weeks]]: โ(๐ฝ(_weeks_)),
[[Days]]: โ(๐ฝ(_days_))
}.
AdjustDateDurationRecord (
_dateDuration_: a Date Duration Record,
_days_: an integer,
optional _weeks_: an integer,
optional _months_: an integer,
): either a normal completion containing a Date Duration Record or a throw completion
1. If _weeks_ is not present, set _weeks_ to _dateDuration_.[[Weeks]].
1. If _months_ is not present, set _months_ to _dateDuration_.[[Months]].
1. Return ? CreateDateDurationRecord(_dateDuration_.[[Years]], _months_, _weeks_, _days_).
CombineDateAndTimeDuration (
_dateDuration_: a Date Duration Record,
_timeDuration_: a time duration,
): an Internal Duration Record
1. Let _dateSign_ be DateDurationSign(_dateDuration_).
1. Let _timeSign_ be TimeDurationSign(_timeDuration_).
1. Assert: If _dateSign_ โ 0 and _timeSign_ โ 0, _dateSign_ = _timeSign_.
1. Return Internal Duration Record {
[[Date]]: _dateDuration_,
[[Time]]: _timeDuration_
}.
ToTemporalDuration (
_item_: an ECMAScript language value,
): either a normal completion containing a Temporal.Duration or a throw completion
1. If _item_ is an Object and _item_ has an [[InitializedTemporalDuration]] internal slot, then
1. Return ! CreateTemporalDuration(_item_.[[Years]], _item_.[[Months]], _item_.[[Weeks]], _item_.[[Days]], _item_.[[Hours]], _item_.[[Minutes]], _item_.[[Seconds]], _item_.[[Milliseconds]], _item_.[[Microseconds]], _item_.[[Nanoseconds]]).
1. If _item_ is not an Object, then
1. If _item_ is not a String, throw a *TypeError* exception.
1. Return ? ParseTemporalDurationString(_item_).
1. Let _result_ be a new Partial Duration Record with each field set to 0.
1. Let _partial_ be ? ToTemporalPartialDurationRecord(_item_).
1. If _partial_.[[Years]] is not *undefined*, set _result_.[[Years]] to _partial_.[[Years]].
1. If _partial_.[[Months]] is not *undefined*, set _result_.[[Months]] to _partial_.[[Months]].
1. If _partial_.[[Weeks]] is not *undefined*, set _result_.[[Weeks]] to _partial_.[[Weeks]].
1. If _partial_.[[Days]] is not *undefined*, set _result_.[[Days]] to _partial_.[[Days]].
1. If _partial_.[[Hours]] is not *undefined*, set _result_.[[Hours]] to _partial_.[[Hours]].
1. If _partial_.[[Minutes]] is not *undefined*, set _result_.[[Minutes]] to _partial_.[[Minutes]].
1. If _partial_.[[Seconds]] is not *undefined*, set _result_.[[Seconds]] to _partial_.[[Seconds]].
1. If _partial_.[[Milliseconds]] is not *undefined*, set _result_.[[Milliseconds]] to _partial_.[[Milliseconds]].
1. If _partial_.[[Microseconds]] is not *undefined*, set _result_.[[Microseconds]] to _partial_.[[Microseconds]].
1. If _partial_.[[Nanoseconds]] is not *undefined*, set _result_.[[Nanoseconds]] to _partial_.[[Nanoseconds]].
1. Return ? CreateTemporalDuration(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], _result_.[[Hours]], _result_.[[Minutes]], _result_.[[Seconds]], _result_.[[Milliseconds]], _result_.[[Microseconds]], _result_.[[Nanoseconds]]).
DurationSign (
_duration_: a Temporal.Duration,
): -1, 0, or 1
1. For each value _v_ of ยซ _duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]] ยป, do
1. If _v_ < 0, return -1.
1. If _v_ > 0, return 1.
1. Return 0.
DateDurationSign (
_dateDuration_: a Date Duration Record,
): -1, 0, or 1
1. For each value _v_ of ยซ _dateDuration_.[[Years]], _dateDuration_.[[Months]], _dateDuration_.[[Weeks]], _dateDuration_.[[Days]] ยป, do
1. If _v_ < 0, return -1.
1. If _v_ > 0, return 1.
1. Return 0.
InternalDurationSign (
_internalDuration_: an Internal Duration Record,
): -1, 0, or 1
1. Let _dateSign_ be DateDurationSign(_internalDuration_.[[Date]]).
1. If _dateSign_ โ 0, return _dateSign_.
1. Return TimeDurationSign(_internalDuration_.[[Time]]).
IsValidDuration (
_years_: an integer,
_months_: an integer,
_weeks_: an integer,
_days_: an integer,
_hours_: an integer,
_minutes_: an integer,
_seconds_: an integer,
_milliseconds_: an integer,
_microseconds_: an integer,
_nanoseconds_: an integer,
): a Boolean
1. Let _sign_ be 0.
1. For each value _v_ of ยซ _years_, _months_, _weeks_, _days_, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_ ยป, do
1. If ๐ฝ(_v_) is not finite, return *false*.
1. If _v_ < 0, then
1. If _sign_ > 0, return *false*.
1. Set _sign_ to -1.
1. Else if _v_ > 0, then
1. If _sign_ < 0, return *false*.
1. Set _sign_ to 1.
1. If abs(_years_) โฅ 232, return *false*.
1. If abs(_months_) โฅ 232, return *false*.
1. If abs(_weeks_) โฅ 232, return *false*.
1. Let _totalFractionalSeconds_ be _days_ ร 86,400 + _hours_ ร 3600 + _minutes_ ร 60 + _seconds_ + โ(๐ฝ(_milliseconds_)) ร 10-3 + โ(๐ฝ(_microseconds_)) ร 10-6 + โ(๐ฝ(_nanoseconds_)) ร 10-9.
1. NOTE: The above step cannot be implemented directly using floating-point arithmetic. Multiplying by 10-3, 10-6, and 10-9 respectively may be imprecise when _milliseconds_, _microseconds_, or _nanoseconds_ is an unsafe integer. This multiplication can be implemented in C++ with an implementation of `std::remquo()` with sufficient bits in the quotient. String manipulation will also give an exact result, since the multiplication is by a power of 10.
1. If abs(_totalFractionalSeconds_) โฅ 253, return *false*.
1. Return *true*.
DefaultTemporalLargestUnit (
_duration_: a Temporal.Duration,
): a Temporal unit
1. If _duration_.[[Years]] โ 0, return ~year~.
1. If _duration_.[[Months]] โ 0, return ~month~.
1. If _duration_.[[Weeks]] โ 0, return ~week~.
1. If _duration_.[[Days]] โ 0, return ~day~.
1. If _duration_.[[Hours]] โ 0, return ~hour~.
1. If _duration_.[[Minutes]] โ 0, return ~minute~.
1. If _duration_.[[Seconds]] โ 0, return ~second~.
1. If _duration_.[[Milliseconds]] โ 0, return ~millisecond~.
1. If _duration_.[[Microseconds]] โ 0, return ~microsecond~.
1. Return ~nanosecond~.
ToTemporalPartialDurationRecord (
_temporalDurationLike_: an ECMAScript language value,
): either a normal completion containing a partial Duration Record or a throw completion
1. If _temporalDurationLike_ is not an Object, then
1. Throw a *TypeError* exception.
1. Let _result_ be a new partial Duration Record with each field set to *undefined*.
1. NOTE: The following steps read properties and perform independent validation in alphabetical order.
1. Let _days_ be ? Get(_temporalDurationLike_, *"days"*).
1. If _days_ is not *undefined*, set _result_.[[Days]] to ? ToIntegerIfIntegral(_days_).
1. Let _hours_ be ? Get(_temporalDurationLike_, *"hours"*).
1. If _hours_ is not *undefined*, set _result_.[[Hours]] to ? ToIntegerIfIntegral(_hours_).
1. Let _microseconds_ be ? Get(_temporalDurationLike_, *"microseconds"*).
1. If _microseconds_ is not *undefined*, set _result_.[[Microseconds]] to ? ToIntegerIfIntegral(_microseconds_).
1. Let _milliseconds_ be ? Get(_temporalDurationLike_, *"milliseconds"*).
1. If _milliseconds_ is not *undefined*, set _result_.[[Milliseconds]] to ? ToIntegerIfIntegral(_milliseconds_).
1. Let _minutes_ be ? Get(_temporalDurationLike_, *"minutes"*).
1. If _minutes_ is not *undefined*, set _result_.[[Minutes]] to ? ToIntegerIfIntegral(_minutes_).
1. Let _months_ be ? Get(_temporalDurationLike_, *"months"*).
1. If _months_ is not *undefined*, set _result_.[[Months]] to ? ToIntegerIfIntegral(_months_).
1. Let _nanoseconds_ be ? Get(_temporalDurationLike_, *"nanoseconds"*).
1. If _nanoseconds_ is not *undefined*, set _result_.[[Nanoseconds]] to ? ToIntegerIfIntegral(_nanoseconds_).
1. Let _seconds_ be ? Get(_temporalDurationLike_, *"seconds"*).
1. If _seconds_ is not *undefined*, set _result_.[[Seconds]] to ? ToIntegerIfIntegral(_seconds_).
1. Let _weeks_ be ? Get(_temporalDurationLike_, *"weeks"*).
1. If _weeks_ is not *undefined*, set _result_.[[Weeks]] to ? ToIntegerIfIntegral(_weeks_).
1. Let _years_ be ? Get(_temporalDurationLike_, *"years"*).
1. If _years_ is not *undefined*, set _result_.[[Years]] to ? ToIntegerIfIntegral(_years_).
1. If _years_ is *undefined*, and _months_ is *undefined*, and _weeks_ is *undefined*, and _days_ is *undefined*, and _hours_ is *undefined*, and _minutes_ is *undefined*, and _seconds_ is *undefined*, and _milliseconds_ is *undefined*, and _microseconds_ is *undefined*, and _nanoseconds_ is *undefined*, throw a *TypeError* exception.
1. Return _result_.
CreateTemporalDuration (
_years_: an integer,
_months_: an integer,
_weeks_: an integer,
_days_: an integer,
_hours_: an integer,
_minutes_: an integer,
_seconds_: an integer,
_milliseconds_: an integer,
_microseconds_: an integer,
_nanoseconds_: an integer,
optional _newTarget_: a constructor,
): either a normal completion containing a Temporal.Duration or a throw completion
1. If IsValidDuration(_years_, _months_, _weeks_, _days_, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_) is *false*, throw a *RangeError* exception.
1. If _newTarget_ is not present, set _newTarget_ to %Temporal.Duration%.
1. Let _object_ be ? OrdinaryCreateFromConstructor(_newTarget_, *"%Temporal.Duration.prototype%"*, ยซ [[InitializedTemporalDuration]], [[Years]], [[Months]], [[Weeks]], [[Days]], [[Hours]], [[Minutes]], [[Seconds]], [[Milliseconds]], [[Microseconds]], [[Nanoseconds]] ยป).
1. Set _object_.[[Years]] to โ(๐ฝ(_years_)).
1. Set _object_.[[Months]] to โ(๐ฝ(_months_)).
1. Set _object_.[[Weeks]] to โ(๐ฝ(_weeks_)).
1. Set _object_.[[Days]] to โ(๐ฝ(_days_)).
1. Set _object_.[[Hours]] to โ(๐ฝ(_hours_)).
1. Set _object_.[[Minutes]] to โ(๐ฝ(_minutes_)).
1. Set _object_.[[Seconds]] to โ(๐ฝ(_seconds_)).
1. Set _object_.[[Milliseconds]] to โ(๐ฝ(_milliseconds_)).
1. Set _object_.[[Microseconds]] to โ(๐ฝ(_microseconds_)).
1. Set _object_.[[Nanoseconds]] to โ(๐ฝ(_nanoseconds_)).
1. Return _object_.
CreateNegatedTemporalDuration (
_duration_: a Temporal.Duration,
): a Temporal.Duration
1. Return ! CreateTemporalDuration(-_duration_.[[Years]], -_duration_.[[Months]], -_duration_.[[Weeks]], -_duration_.[[Days]], -_duration_.[[Hours]], -_duration_.[[Minutes]], -_duration_.[[Seconds]], -_duration_.[[Milliseconds]], -_duration_.[[Microseconds]], -_duration_.[[Nanoseconds]]).
TimeDurationFromComponents (
_hours_: an integer,
_minutes_: an integer,
_seconds_: an integer,
_milliseconds_: an integer,
_microseconds_: an integer,
_nanoseconds_: an integer,
): a time duration
1. Set _minutes_ to _minutes_ + _hours_ ร 60.
1. Set _seconds_ to _seconds_ + _minutes_ ร 60.
1. Set _milliseconds_ to _milliseconds_ + _seconds_ ร 1000.
1. Set _microseconds_ to _microseconds_ + _milliseconds_ ร 1000.
1. Set _nanoseconds_ to _nanoseconds_ + _microseconds_ ร 1000.
1. Assert: abs(_nanoseconds_) โค maxTimeDuration.
1. Return _nanoseconds_.
AddTimeDuration (
_one_: a time duration,
_two_: a time duration,
): either a normal completion containing a time duration or a throw completion
1. Let _result_ be _one_ + _two_.
1. If abs(_result_) > maxTimeDuration, throw a *RangeError* exception.
1. Return _result_.
Add24HourDaysToTimeDuration (
_d_: a time duration,
_days_: an integer,
): either a normal completion containing a time duration or a throw completion
1. Let _result_ be _d_ + _days_ ร nsPerDay.
1. If abs(_result_) > maxTimeDuration, throw a *RangeError* exception.
1. Return _result_.
AddTimeDurationToEpochNanoseconds (
_d_: a time duration,
_epochNs_: a BigInt,
): a BigInt
1. Return _epochNs_ + โค(_d_).
CompareTimeDuration (
_one_: a time duration,
_two_: a time duration,
): -1, 0, or 1
1. If _one_ > _two_, return 1.
1. If _one_ < _two_, return -1.
1. Return 0.
TimeDurationFromEpochNanosecondsDifference (
_one_: a BigInt,
_two_: a BigInt,
): a time duration
1. Let _result_ be โ(_one_) - โ(_two_).
1. Assert: abs(_result_) โค maxTimeDuration.
1. Return _result_.
RoundTimeDurationToIncrement (
_d_: a time duration,
_increment_: a positive integer,
_roundingMode_: a rounding mode,
): either a normal completion containing a time duration or a throw completion
1. Let _rounded_ be RoundNumberToIncrement(_d_, _increment_, _roundingMode_).
1. If abs(_rounded_) > maxTimeDuration, throw a *RangeError* exception.
1. Return _rounded_.
TimeDurationSign (
_d_: a time duration,
): -1, 0, or 1
1. If _d_ < 0, return -1.
1. If _d_ > 0, return 1.
1. Return 0.
DateDurationDays (
_dateDuration_: a Date Duration Record,
_plainRelativeTo_: a Temporal.PlainDate,
): either a normal completion containing an integer or a throw completion
1. Let _yearsMonthsWeeksDuration_ be ! AdjustDateDurationRecord(_dateDuration_, 0).
1. If DateDurationSign(_yearsMonthsWeeksDuration_) = 0, return _dateDuration_.[[Days]].
1. Let _later_ be ? CalendarDateAdd(_plainRelativeTo_.[[Calendar]], _plainRelativeTo_.[[ISODate]], _yearsMonthsWeeksDuration_, ~constrain~).
1. Let _epochDays1_ be ISODateToEpochDays(_plainRelativeTo_.[[ISODate]].[[Year]], _plainRelativeTo_.[[ISODate]].[[Month]] - 1, _plainRelativeTo_.[[ISODate]].[[Day]]).
1. Let _epochDays2_ be ISODateToEpochDays(_later_.[[Year]], _later_.[[Month]] - 1, _later_.[[Day]]).
1. Let _yearsMonthsWeeksInDays_ be _epochDays2_ - _epochDays1_.
1. Return _dateDuration_.[[Days]] + _yearsMonthsWeeksInDays_.
RoundTimeDuration (
_timeDuration_: a time duration,
_increment_: a positive integer,
_unit_: a time unit,
_roundingMode_: a rounding mode,
): either a normal completion containing a time duration, or a throw completion
1. Let _divisor_ be the value in the "Length in Nanoseconds" column of the row of whose "Value" column contains _unit_.
1. Return ? RoundTimeDurationToIncrement(_timeDuration_, _divisor_ ร _increment_, _roundingMode_).
TotalTimeDuration (
_timeDuration_: a time duration,
_unit_: a time unit or ~day~,
): a mathematical value
1. Let _divisor_ be the value in the "Length in Nanoseconds" column of the row of whose "Value" column contains _unit_.
1. NOTE: The following step cannot be implemented directly using floating-point arithmetic when ๐ฝ(_timeDuration_) is not a safe integer. The division can be implemented in C++ with the `__float128` type if the compiler supports it, or with software emulation such as in the SoftFP library.
1. Return _timeDuration_ / _divisor_.
Duration Nudge Result Records
A Duration Nudge Result Record is a Record value used to represent the result of rounding a duration up or down to an increment relative to a date-time, as in NudgeToCalendarUnit, NudgeToZonedTime, or NudgeToDayOrTime.
Duration Nudge Result Records have the fields listed in .
| Field Name |
Value |
Meaning |
| [[Duration]] |
an Internal Duration Record |
The resulting duration.
|
| [[NudgedEpochNs]] |
a BigInt |
The epoch time corresponding to the rounded duration, relative to the starting point.
|
| [[DidExpandCalendarUnit]] |
a Boolean |
Whether the rounding operation caused the duration to expand to the next day or larger unit.
|
NudgeToCalendarUnit (
_sign_: -1 or 1,
_duration_: an Internal Duration Record,
_destEpochNs_: a BigInt,
_isoDateTime_: an ISO Date-Time Record,
_timeZone_: an available time zone identifier or ~unset~,
_calendar_: a calendar type,
_increment_: a positive integer,
_unit_: a date unit,
_roundingMode_: a rounding mode,
): either a normal completion containing a Record with fields [[NudgeResult]] (a Duration Nudge Result Record) and [[Total]] (a mathematical value), or a throw completion
1. If _unit_ is ~year~, then
1. Let _years_ be RoundNumberToIncrement(_duration_.[[Date]].[[Years]], _increment_, ~trunc~).
1. Let _r1_ be _years_.
1. Let _r2_ be _years_ + _increment_ ร _sign_.
1. Let _startDuration_ be ? CreateDateDurationRecord(_r1_, 0, 0, 0).
1. Let _endDuration_ be ? CreateDateDurationRecord(_r2_, 0, 0, 0).
1. Else if _unit_ is ~month~, then
1. Let _months_ be RoundNumberToIncrement(_duration_.[[Date]].[[Months]], _increment_, ~trunc~).
1. Let _r1_ be _months_.
1. Let _r2_ be _months_ + _increment_ ร _sign_.
1. Let _startDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], 0, 0, _r1_).
1. Let _endDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], 0, 0, _r2_).
1. Else if _unit_ is ~week~, then
1. Let _yearsMonths_ be ! AdjustDateDurationRecord(_duration_.[[Date]], 0, 0).
1. Let _weeksStart_ be ? CalendarDateAdd(_calendar_, _isoDateTime_.[[ISODate]], _yearsMonths_, ~constrain~).
1. Let _weeksEnd_ be BalanceISODate(_weeksStart_.[[Year]], _weeksStart_.[[Month]], _weeksStart_.[[Day]] + _duration_.[[Date]].[[Days]]).
1. Let _untilResult_ be CalendarDateUntil(_calendar_, _weeksStart_, _weeksEnd_, ~week~).
1. Let _weeks_ be RoundNumberToIncrement(_duration_.[[Date]].[[Weeks]] + _untilResult_.[[Weeks]], _increment_, ~trunc~).
1. Let _r1_ be _weeks_.
1. Let _r2_ be _weeks_ + _increment_ ร _sign_.
1. Let _startDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], 0, _r1_).
1. Let _endDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], 0, _r2_).
1. Else,
1. Assert: _unit_ is ~day~.
1. Let _days_ be RoundNumberToIncrement(_duration_.[[Date]].[[Days]], _increment_, ~trunc~).
1. Let _r1_ be _days_.
1. Let _r2_ be _days_ + _increment_ ร _sign_.
1. Let _startDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], _r1_).
1. Let _endDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], _r2_).
1. Assert: If _sign_ is 1, _r1_ โฅ 0 and _r1_ < _r2_.
1. Assert: If _sign_ is -1, _r1_ โค 0 and _r1_ > _r2_.
1. Let _start_ be ? CalendarDateAdd(_calendar_, _isoDateTime_.[[ISODate]], _startDuration_, ~constrain~).
1. Let _end_ be ? CalendarDateAdd(_calendar_, _isoDateTime_.[[ISODate]], _endDuration_, ~constrain~).
1. Let _startDateTime_ be CombineISODateAndTimeRecord(_start_, _isoDateTime_.[[Time]]).
1. Let _endDateTime_ be CombineISODateAndTimeRecord(_end_, _isoDateTime_.[[Time]]).
1. If _timeZone_ is ~unset~, then
1. Let _startEpochNs_ be GetUTCEpochNanoseconds(_startDateTime_).
1. Let _endEpochNs_ be GetUTCEpochNanoseconds(_endDateTime_).
1. Else,
1. Let _startEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _startDateTime_, ~compatible~).
1. Let _endEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _endDateTime_, ~compatible~).
1. If _sign_ is 1, then
1. Assert: _startEpochNs_ โค _destEpochNs_ โค _endEpochNs_.
1. Else,
1. Assert: _endEpochNs_ โค _destEpochNs_ โค _startEpochNs_.
1. Assert: _startEpochNs_ โ _endEpochNs_.
1. Let _progress_ be (_destEpochNs_ - _startEpochNs_) / (_endEpochNs_ - _startEpochNs_).
1. Let _total_ be _r1_ + _progress_ ร _increment_ ร _sign_.
1. NOTE: The above two steps cannot be implemented directly using floating-point arithmetic. This division can be implemented as if expressing the denominator and numerator of _total_ as two time durations, and performing one division operation with a floating-point result.
1. Assert: 0 โค _progress_ โค 1.
1. If _sign_ < 0, let _isNegative_ be ~negative~; else let _isNegative_ be ~positive~.
1. Let _unsignedRoundingMode_ be GetUnsignedRoundingMode(_roundingMode_, _isNegative_).
1. If _progress_ = 1, then
1. Let _roundedUnit_ be abs(_r2_).
1. Else,
1. Assert: abs(_r1_) โค abs(_total_) < abs(_r2_).
1. Let _roundedUnit_ be ApplyUnsignedRoundingMode(abs(_total_), abs(_r1_), abs(_r2_), _unsignedRoundingMode_).
1. If _roundedUnit_ is abs(_r2_), then
1. Let _didExpandCalendarUnit_ be *true*.
1. Let _resultDuration_ be _endDuration_.
1. Let _nudgedEpochNs_ be _endEpochNs_.
1. Else,
1. Let _didExpandCalendarUnit_ be *false*.
1. Let _resultDuration_ be _startDuration_.
1. Let _nudgedEpochNs_ be _startEpochNs_.
1. Set _resultDuration_ to CombineDateAndTimeDuration(_resultDuration_, 0).
1. Let _nudgeResult_ be Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didExpandCalendarUnit_ }.
1. Return the Record { [[NudgeResult]]: _nudgeResult_, [[Total]]: _total_ }.
NudgeToZonedTime (
_sign_: -1 or 1,
_duration_: an Internal Duration Record,
_isoDateTime_: an ISO Date-Time Record,
_timeZone_: an available time zone identifier,
_calendar_: a calendar type,
_increment_: a positive integer,
_unit_: a time unit,
_roundingMode_: a rounding mode,
): either a normal completion containing a Duration Nudge Result Record or a throw completion
1. Let _start_ be ? CalendarDateAdd(_calendar_, _isoDateTime_.[[ISODate]], _duration_.[[Date]], ~constrain~).
1. Let _startDateTime_ be CombineISODateAndTimeRecord(_start_, _isoDateTime_.[[Time]]).
1. Let _endDate_ be BalanceISODate(_start_.[[Year]], _start_.[[Month]], _start_.[[Day]] + _sign_).
1. Let _endDateTime_ be CombineISODateAndTimeRecord(_endDate_, _isoDateTime_.[[Time]]).
1. Let _startEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _startDateTime_, ~compatible~).
1. Let _endEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _endDateTime_, ~compatible~).
1. Let _daySpan_ be TimeDurationFromEpochNanosecondsDifference(_endEpochNs_, _startEpochNs_).
1. Assert: TimeDurationSign(_daySpan_) = _sign_.
1. Let _unitLength_ be the value in the "Length in Nanoseconds" column of the row of whose "Value" column contains _unit_.
1. Let _roundedTimeDuration_ be ? RoundTimeDurationToIncrement(_duration_.[[Time]], _increment_ ร _unitLength_, _roundingMode_).
1. Let _beyondDaySpan_ be ! AddTimeDuration(_roundedTimeDuration_, -_daySpan_).
1. If TimeDurationSign(_beyondDaySpan_) โ -_sign_, then
1. Let _didRoundBeyondDay_ be *true*.
1. Let _dayDelta_ be _sign_.
1. Set _roundedTimeDuration_ to ? RoundTimeDurationToIncrement(_beyondDaySpan_, _increment_ ร _unitLength_, _roundingMode_).
1. Let _nudgedEpochNs_ be AddTimeDurationToEpochNanoseconds(_roundedTimeDuration_, _endEpochNs_).
1. Else,
1. Let _didRoundBeyondDay_ be *false*.
1. Let _dayDelta_ be 0.
1. Let _nudgedEpochNs_ be AddTimeDurationToEpochNanoseconds(_roundedTimeDuration_, _startEpochNs_).
1. Let _dateDuration_ be ! AdjustDateDurationRecord(_duration_.[[Date]], _duration_.[[Date]].[[Days]] + _dayDelta_).
1. Let _resultDuration_ be CombineDateAndTimeDuration(_dateDuration_, _roundedTimeDuration_).
1. Return Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didRoundBeyondDay_ }.
NudgeToDayOrTime (
_duration_: an Internal Duration Record,
_destEpochNs_: a BigInt,
_largestUnit_: a Temporal unit,
_increment_: a positive integer,
_smallestUnit_: a time unit or ~day~,
_roundingMode_: a rounding mode,
): either a normal completion containing a Duration Nudge Result Record or a throw completion
1. Let _timeDuration_ be ! Add24HourDaysToTimeDuration(_duration_.[[Time]], _duration_.[[Date]].[[Days]]).
1. Let _unitLength_ be the value in the "Length in Nanoseconds" column of the row of whose "Value" column contains _smallestUnit_.
1. Let _roundedTime_ be ? RoundTimeDurationToIncrement(_timeDuration_, _unitLength_ ร _increment_, _roundingMode_).
1. Let _diffTime_ be ! AddTimeDuration(_roundedTime_, -_timeDuration_).
1. Let _wholeDays_ be truncate(TotalTimeDuration(_timeDuration_, ~day~)).
1. Let _roundedWholeDays_ be truncate(TotalTimeDuration(_roundedTime_, ~day~)).
1. Let _dayDelta_ be _roundedWholeDays_ - _wholeDays_.
1. If _dayDelta_ < 0, let _dayDeltaSign_ be -1; else if _dayDelta_ > 0, let _dayDeltaSign_ be 1; else let _dayDeltaSign_ be 0.
1. If _dayDeltaSign_ = TimeDurationSign(_timeDuration_), let _didExpandDays_ be *true*; else let _didExpandDays_ be *false*.
1. Let _nudgedEpochNs_ be AddTimeDurationToEpochNanoseconds(_diffTime_, _destEpochNs_).
1. Let _days_ be 0.
1. Let _remainder_ be _roundedTime_.
1. If TemporalUnitCategory(_largestUnit_) is ~date~, then
1. Set _days_ to _roundedWholeDays_.
1. Set _remainder_ to ! AddTimeDuration(_roundedTime_, TimeDurationFromComponents(-_roundedWholeDays_ * HoursPerDay, 0, 0, 0, 0, 0)).
1. Let _dateDuration_ be ! AdjustDateDurationRecord(_duration_.[[Date]], _days_).
1. Let _resultDuration_ be CombineDateAndTimeDuration(_dateDuration_, _remainder_).
1. Return Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didExpandDays_ }.
BubbleRelativeDuration (
_sign_: -1 or 1,
_duration_: an Internal Duration Record,
_nudgedEpochNs_: a BigInt,
_isoDateTime_: an ISO Date-Time Record,
_timeZone_: an available time zone identifier or ~unset~,
_calendar_: a calendar type,
_largestUnit_: a date unit,
_smallestUnit_: a date unit,
): either a normal completion containing an Internal Duration Record or a throw completion
1. If _smallestUnit_ is _largestUnit_, return _duration_.
1. Let _largestUnitIndex_ be the ordinal index of the row of whose "Value" column contains _largestUnit_.
1. Let _smallestUnitIndex_ be the ordinal index of the row of whose "Value" column contains _smallestUnit_.
1. Let _unitIndex_ be _smallestUnitIndex_ - 1.
1. Let _done_ be *false*.
1. Repeat, while _unitIndex_ โฅ _largestUnitIndex_ and _done_ is *false*,
1. Let _unit_ be the value in the "Value" column of in the row whose ordinal index is _unitIndex_.
1. If _unit_ is not ~week~, or _largestUnit_ is ~week~, then
1. If _unit_ is ~year~, then
1. Let _years_ be _duration_.[[Date]].[[Years]] + _sign_.
1. Let _endDuration_ be ? CreateDateDurationRecord(_years_, 0, 0, 0).
1. Else if _unit_ is ~month~, then
1. Let _months_ be _duration_.[[Date]].[[Months]] + _sign_.
1. Let _endDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], 0, 0, _months_).
1. Else,
1. Assert: _unit_ is ~week~.
1. Let _weeks_ be _duration_.[[Date]].[[Weeks]] + _sign_.
1. Let _endDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], 0, _weeks_).
1. Let _end_ be ? CalendarDateAdd(_calendar_, _isoDateTime_.[[ISODate]], _endDuration_, ~constrain~).
1. Let _endDateTime_ be CombineISODateAndTimeRecord(_end_, _isoDateTime_.[[Time]]).
1. If _timeZone_ is ~unset~, then
1. Let _endEpochNs_ be GetUTCEpochNanoseconds(_endDateTime_).
1. Else,
1. Let _endEpochNs_ be ? GetEpochNanosecondsFor(_timeZone_, _endDateTime_, ~compatible~).
1. Let _beyondEnd_ be _nudgedEpochNs_ - _endEpochNs_.
1. If _beyondEnd_ < 0, let _beyondEndSign_ be -1; else if _beyondEnd_ > 0, let _beyondEndSign_ be 1; else let _beyondEndSign_ be 0.
1. If _beyondEndSign_ โ -_sign_, then
1. Set _duration_ to CombineDateAndTimeDuration(_endDuration_, 0).
1. Else,
1. Set _done_ to *true*.
1. Set _unitIndex_ to _unitIndex_ - 1.
1. Return _duration_.
RoundRelativeDuration (
_duration_: an Internal Duration Record,
_destEpochNs_: a BigInt,
_isoDateTime_: an ISO Date-Time Record,
_timeZone_: an available time zone identifier or ~unset~,
_calendar_: a calendar type,
_largestUnit_: a Temporal unit,
_increment_: a positive integer,
_smallestUnit_: a Temporal unit,
_roundingMode_: a rounding mode,
): either a normal completion containing an Internal Duration Record or a throw completion
1. Let _irregularLengthUnit_ be *false*.
1. If IsCalendarUnit(_smallestUnit_) is *true*, set _irregularLengthUnit_ to *true*.
1. If _timeZone_ is not ~unset~ and _smallestUnit_ is ~day~, set _irregularLengthUnit_ to *true*.
1. If InternalDurationSign(_duration_) < 0, let _sign_ be -1; else let _sign_ be 1.
1. If _irregularLengthUnit_ is *true*, then
1. Let _record_ be ? NudgeToCalendarUnit(_sign_, _duration_, _destEpochNs_, _isoDateTime_, _timeZone_, _calendar_, _increment_, _smallestUnit_, _roundingMode_).
1. Let _nudgeResult_ be _record_.[[NudgeResult]].
1. Else if _timeZone_ is not ~unset~, then
1. Let _nudgeResult_ be ? NudgeToZonedTime(_sign_, _duration_, _isoDateTime_, _timeZone_, _calendar_, _increment_, _smallestUnit_, _roundingMode_).
1. Else,
1. Let _nudgeResult_ be ? NudgeToDayOrTime(_duration_, _destEpochNs_, _largestUnit_, _increment_, _smallestUnit_, _roundingMode_).
1. Set _duration_ to _nudgeResult_.[[Duration]].
1. If _nudgeResult_.[[DidExpandCalendarUnit]] is *true* and _smallestUnit_ is not ~week~, then
1. Let _startUnit_ be LargerOfTwoTemporalUnits(_smallestUnit_, ~day~).
1. Set _duration_ to ? BubbleRelativeDuration(_sign_, _duration_, _nudgeResult_.[[NudgedEpochNs]], _isoDateTime_, _timeZone_, _calendar_, _largestUnit_, _startUnit_).
1. Return _duration_.
TotalRelativeDuration (
_duration_: an Internal Duration Record,
_destEpochNs_: a BigInt,
_isoDateTime_: an ISO Date-Time Record,
_timeZone_: an available time zone identifier or ~unset~,
_calendar_: a calendar type,
_unit_: a Temporal unit,
): either a normal completion containing a mathematical value, or a throw completion
1. If IsCalendarUnit(_unit_) is *true*, or _timeZone_ is not ~unset~ and _unit_ is ~day~, then
1. Let _sign_ be InternalDurationSign(_duration_).
1. Let _record_ be ? NudgeToCalendarUnit(_sign_, _duration_, _destEpochNs_, _isoDateTime_, _timeZone_, _calendar_, 1, _unit_, ~trunc~).
1. Return _record_.[[Total]].
1. Let _timeDuration_ be ! Add24HourDaysToTimeDuration(_duration_.[[Time]], _duration_.[[Date]].[[Days]]).
1. Return TotalTimeDuration(_timeDuration_, _unit_).
TemporalDurationToString (
_duration_: a Temporal.Duration,
_precision_: an integer between 0 and 9 inclusive, or ~auto~,
): a String
1. Let _sign_ be DurationSign(_duration_).
1. Let _datePart_ be the empty String.
1. If _duration_.[[Years]] โ 0, then
1. Set _datePart_ to the string concatenation of abs(_duration_.[[Years]]) formatted as a decimal number and the code unit 0x0059 (LATIN CAPITAL LETTER Y).
1. If _duration_.[[Months]] โ 0, then
1. Set _datePart_ to the string concatenation of _datePart_, abs(_duration_.[[Months]]) formatted as a decimal number, and the code unit 0x004D (LATIN CAPITAL LETTER M).
1. If _duration_.[[Weeks]] โ 0, then
1. Set _datePart_ to the string concatenation of _datePart_, abs(_duration_.[[Weeks]]) formatted as a decimal number, and the code unit 0x0057 (LATIN CAPITAL LETTER W).
1. If _duration_.[[Days]] โ 0, then
1. Set _datePart_ to the string concatenation of _datePart_, abs(_duration_.[[Days]]) formatted as a decimal number, and the code unit 0x0044 (LATIN CAPITAL LETTER D).
1. Let _timePart_ be the empty String.
1. If _duration_.[[Hours]] โ 0, then
1. Set _timePart_ to the string concatenation of abs(_duration_.[[Hours]]) formatted as a decimal number and the code unit 0x0048 (LATIN CAPITAL LETTER H).
1. If _duration_.[[Minutes]] โ 0, then
1. Set _timePart_ to the string concatenation of _timePart_, abs(_duration_.[[Minutes]]) formatted as a decimal number, and the code unit 0x004D (LATIN CAPITAL LETTER M).
1. Let _zeroMinutesAndHigher_ be *false*.
1. If DefaultTemporalLargestUnit(_duration_) is ~second~, ~millisecond~, ~microsecond~, or ~nanosecond~, set _zeroMinutesAndHigher_ to *true*.
1. Let _secondsDuration_ be TimeDurationFromComponents(0, 0, _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]).
1. If _secondsDuration_ โ 0, or _zeroMinutesAndHigher_ is *true*, or _precision_ is not ~auto~, then
1. Let _secondsPart_ be abs(truncate(_secondsDuration_ / 109)) formatted as a decimal number.
1. Let _subSecondsPart_ be FormatFractionalSeconds(abs(remainder(_secondsDuration_, 109)), _precision_).
1. Set _timePart_ to the string concatenation of _timePart_, _secondsPart_, _subSecondsPart_, and the code unit 0x0053 (LATIN CAPITAL LETTER S).
1. Let _signPart_ be the code unit 0x002D (HYPHEN-MINUS) if _sign_ < 0, and otherwise the empty String.
1. Let _result_ be the string concatenation of _signPart_, the code unit 0x0050 (LATIN CAPITAL LETTER P) and _datePart_.
1. If _timePart_ is not the empty String, then
1. Set _result_ to the string concatenation of _result_, the code unit 0x0054 (LATIN CAPITAL LETTER T), and _timePart_.
1. Return _result_.
AddDurations (
_operation_: ~add~ or ~subtract~,
_duration_: a Temporal.Duration,
_other_: an ECMAScript language value,
): either a normal completion containing a Temporal.Duration or a throw completion
1. Set _other_ to ? ToTemporalDuration(_other_).
1. If _operation_ is ~subtract~, set _other_ to CreateNegatedTemporalDuration(_other_).
1. Let _largestUnit1_ be DefaultTemporalLargestUnit(_duration_).
1. Let _largestUnit2_ be DefaultTemporalLargestUnit(_other_).
1. Let _largestUnit_ be LargerOfTwoTemporalUnits(_largestUnit1_, _largestUnit2_).
1. If IsCalendarUnit(_largestUnit_) is *true*, throw a *RangeError* exception.
1. Let _d1_ be ToInternalDurationRecordWith24HourDays(_duration_).
1. Let _d2_ be ToInternalDurationRecordWith24HourDays(_other_).
1. Let _timeResult_ be ? AddTimeDuration(_d1_.[[Time]], _d2_.[[Time]]).
1. Let _result_ be CombineDateAndTimeDuration(ZeroDateDuration(), _timeResult_).
1. Return ? TemporalDurationFromInternal(_result_, _largestUnit_).