diff --git a/polyfill/lib/duration.mjs b/polyfill/lib/duration.mjs index 5cc43191d..bd578d695 100644 --- a/polyfill/lib/duration.mjs +++ b/polyfill/lib/duration.mjs @@ -10,7 +10,6 @@ import { // class static functions and methods MathAbs, - NumberIsNaN, ObjectCreate, ObjectDefineProperty, @@ -236,7 +235,7 @@ export class Duration { const calendar = GetSlot(zonedRelativeTo, CALENDAR); const relativeEpochNs = GetSlot(zonedRelativeTo, EPOCHNANOSECONDS); const targetEpochNs = ES.AddZonedDateTime(relativeEpochNs, timeZone, calendar, duration); - ({ duration } = ES.DifferenceZonedDateTimeWithRounding( + duration = ES.DifferenceZonedDateTimeWithRounding( relativeEpochNs, targetEpochNs, timeZone, @@ -245,7 +244,7 @@ export class Duration { roundingIncrement, smallestUnit, roundingMode - )); + ); if (ES.TemporalUnitCategory(largestUnit) === 'date') largestUnit = 'hour'; return ES.UnnormalizeDuration(duration, largestUnit); } @@ -260,7 +259,7 @@ export class Duration { const dateDuration = ES.AdjustDateDurationRecord(duration.date, targetTime.deltaDays); const targetDate = ES.CalendarDateAdd(calendar, isoRelativeToDate, dateDuration, 'constrain'); - ({ duration } = ES.DifferencePlainDateTimeWithRounding( + duration = ES.DifferencePlainDateTimeWithRounding( isoRelativeToDate.year, isoRelativeToDate.month, isoRelativeToDate.day, @@ -284,7 +283,7 @@ export class Duration { roundingIncrement, smallestUnit, roundingMode - )); + ); return ES.UnnormalizeDuration(duration, largestUnit); } @@ -297,7 +296,7 @@ export class Duration { } assert(!ES.IsCalendarUnit(smallestUnit), 'smallestUnit was larger than largestUnit'); let duration = ES.NormalizeDurationWith24HourDays(this); - ({ duration } = ES.RoundTimeDuration(duration, roundingIncrement, smallestUnit, roundingMode)); + duration = ES.RoundTimeDuration(duration, roundingIncrement, smallestUnit, roundingMode); return ES.UnnormalizeDuration(duration, largestUnit); } total(totalOf) { @@ -320,18 +319,7 @@ export class Duration { const calendar = GetSlot(zonedRelativeTo, CALENDAR); const relativeEpochNs = GetSlot(zonedRelativeTo, EPOCHNANOSECONDS); const targetEpochNs = ES.AddZonedDateTime(relativeEpochNs, timeZone, calendar, duration); - const { total } = ES.DifferenceZonedDateTimeWithRounding( - relativeEpochNs, - targetEpochNs, - timeZone, - calendar, - unit, - 1, - unit, - 'trunc' - ); - assert(!NumberIsNaN(total), 'total went through NudgeToZonedTime code path'); - return total; + return ES.DifferenceZonedDateTimeWithTotal(relativeEpochNs, targetEpochNs, timeZone, calendar, unit); } if (plainRelativeTo) { @@ -344,7 +332,7 @@ export class Duration { const dateDuration = ES.AdjustDateDurationRecord(duration.date, targetTime.deltaDays); const targetDate = ES.CalendarDateAdd(calendar, isoRelativeToDate, dateDuration, 'constrain'); - const { total } = ES.DifferencePlainDateTimeWithRounding( + return ES.DifferencePlainDateTimeWithTotal( isoRelativeToDate.year, isoRelativeToDate.month, isoRelativeToDate.day, @@ -364,13 +352,8 @@ export class Duration { targetTime.microsecond, targetTime.nanosecond, calendar, - unit, - 1, - unit, - 'trunc' + unit ); - assert(!NumberIsNaN(total), 'total went through NudgeToZonedTime code path'); - return total; } // No reference date to calculate difference relative to @@ -382,8 +365,7 @@ export class Duration { throw new RangeErrorCtor(`a starting point is required for ${unit}s total`); } const duration = ES.NormalizeDurationWith24HourDays(this); - const { total } = ES.RoundTimeDuration(duration, 1, unit, 'trunc'); - return total; + return ES.TotalTimeDuration(duration.norm, unit); } toString(options = undefined) { if (!ES.IsTemporalDuration(this)) throw new TypeErrorCtor('invalid receiver'); @@ -400,7 +382,7 @@ export class Duration { const largestUnit = ES.DefaultTemporalLargestUnit(this); let duration = ES.NormalizeDuration(this); - ({ duration } = ES.RoundTimeDuration(duration, increment, unit, roundingMode)); + duration = ES.RoundTimeDuration(duration, increment, unit, roundingMode); const roundedDuration = ES.UnnormalizeDuration(duration, ES.LargerOfTwoTemporalUnits(largestUnit, 'second')); return ES.TemporalDurationToString(roundedDuration, precision); } diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index 9f86935c3..4a040694e 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -3457,12 +3457,12 @@ function NudgeToCalendarUnit(sign, duration, destEpochNs, dateTime, timeZone, ca const didExpandCalendarUnit = roundedUnit === MathAbs(r2); duration = { date: didExpandCalendarUnit ? endDuration : startDuration, norm: TimeDuration.ZERO }; - return { + const nudgeResult = { duration, - total, nudgedEpochNs: didExpandCalendarUnit ? endEpochNs : startEpochNs, didExpandCalendarUnit }; + return { nudgeResult, total }; } // Attempts rounding of time units within a time zone's day, but if the rounding @@ -3513,7 +3513,6 @@ function NudgeToZonedTime(sign, duration, dateTime, timeZone, calendar, incremen const resultDuration = CombineDateAndNormalizedTimeDuration(dateDuration, roundedNorm); return { duration: resultDuration, - total: NaN, // Not computed in this path, so we assert that it is not NaN later on nudgedEpochNs, didExpandCalendarUnit: didRoundBeyondDay }; @@ -3526,7 +3525,6 @@ function NudgeToDayOrTime(duration, destEpochNs, largestUnit, increment, smalles const norm = duration.norm.add24HourDays(duration.date.days); // Convert to nanoseconds and round const unitLength = Call(MapPrototypeGet, NS_PER_TIME_UNIT, [smallestUnit]); - const total = norm.fdiv(unitLength); const roundedNorm = norm.round(increment * unitLength, roundingMode); const diffNorm = roundedNorm.subtract(norm); @@ -3547,7 +3545,6 @@ function NudgeToDayOrTime(duration, destEpochNs, largestUnit, increment, smalles const dateDuration = AdjustDateDurationRecord(duration.date, days); return { duration: { date: dateDuration, norm: remainder }, - total, nudgedEpochNs, didExpandCalendarUnit: didExpandDays }; @@ -3667,7 +3664,7 @@ function RoundRelativeDuration( let nudgeResult; if (irregularLengthUnit) { // Rounding an irregular-length unit? Use epoch-nanosecond-bounding technique - nudgeResult = NudgeToCalendarUnit( + ({ nudgeResult } = NudgeToCalendarUnit( sign, duration, destEpochNs, @@ -3677,11 +3674,9 @@ function RoundRelativeDuration( increment, smallestUnit, roundingMode - ); + )); } else if (timeZone) { - // Special-case for rounding time units within a zoned day. total() never - // takes this path because largestUnit is then also a time unit, so - // DifferenceZonedDateTimeWithRounding uses Instant math + // Special-case for rounding time units within a zoned day nudgeResult = NudgeToZonedTime(sign, duration, dateTime, timeZone, calendar, increment, smallestUnit, roundingMode); } else { // Rounding uniform-length days/hours/minutes/etc units. Simple nanosecond @@ -3706,7 +3701,25 @@ function RoundRelativeDuration( ); } - return { duration, total: nudgeResult.total }; + return duration; +} + +function TotalRelativeDuration(duration, destEpochNs, dateTime, timeZone, calendar, unit) { + // The duration must already be balanced. This should be achieved by calling + // one of the non-rounding since/until internal methods prior. It's okay to + // have a bottom-heavy weeks because weeks don't bubble-up into months. It's + // okay to have >24 hour day assuming the final day of relativeTo+duration has + // >24 hours in its timezone. (should automatically end up like this if using + // non-rounding since/until internal methods prior) + if (IsCalendarUnit(unit) || (timeZone && unit === 'day')) { + // Rounding an irregular-length unit? Use epoch-nanosecond-bounding technique + const sign = NormalizedDurationSign(duration) < 0 ? -1 : 1; + return NudgeToCalendarUnit(sign, duration, destEpochNs, dateTime, timeZone, calendar, 1, unit, 'trunc').total; + } + // Rounding uniform-length days/hours/minutes/etc units. Simple nanosecond + // math. years/months/weeks unchanged + const norm = duration.norm.add24HourDays(duration.date.days); + return TotalTimeDuration(norm, unit); } export function DifferencePlainDateTimeWithRounding( @@ -3735,10 +3748,7 @@ export function DifferencePlainDateTimeWithRounding( roundingMode ) { if (CompareISODateTime(y1, mon1, d1, h1, min1, s1, ms1, µs1, ns1, y2, mon2, d2, h2, min2, s2, ms2, µs2, ns2) == 0) { - return { - duration: { date: ZeroDateDuration(), norm: TimeDuration.ZERO }, - total: 0 - }; + return { date: ZeroDateDuration(), norm: TimeDuration.ZERO }; } const duration = DifferenceISODateTime( @@ -3764,9 +3774,7 @@ export function DifferencePlainDateTimeWithRounding( largestUnit ); - if (smallestUnit === 'nanosecond' && roundingIncrement === 1) { - return { duration, total: duration.norm.totalNs.toJSNumber() }; - } + if (smallestUnit === 'nanosecond' && roundingIncrement === 1) return duration; const dateTime = { year: y1, @@ -3793,6 +3801,72 @@ export function DifferencePlainDateTimeWithRounding( ); } +export function DifferencePlainDateTimeWithTotal( + y1, + mon1, + d1, + h1, + min1, + s1, + ms1, + µs1, + ns1, + y2, + mon2, + d2, + h2, + min2, + s2, + ms2, + µs2, + ns2, + calendar, + unit +) { + if (CompareISODateTime(y1, mon1, d1, h1, min1, s1, ms1, µs1, ns1, y2, mon2, d2, h2, min2, s2, ms2, µs2, ns2) == 0) { + return 0; + } + + const duration = DifferenceISODateTime( + y1, + mon1, + d1, + h1, + min1, + s1, + ms1, + µs1, + ns1, + y2, + mon2, + d2, + h2, + min2, + s2, + ms2, + µs2, + ns2, + calendar, + unit + ); + + if (unit === 'nanosecond') return duration.norm.totalNs.toJSNumber(); + + const dateTime = { + year: y1, + month: mon1, + day: d1, + hour: h1, + minute: min1, + second: s1, + millisecond: ms1, + microsecond: µs1, + nanosecond: ns1 + }; + const destEpochNs = GetUTCEpochNanoseconds(y2, mon2, d2, h2, min2, s2, ms2, µs2, ns2); + return TotalRelativeDuration(duration, destEpochNs, dateTime, null, calendar, unit); +} + export function DifferenceZonedDateTimeWithRounding( ns1, ns2, @@ -3810,9 +3884,7 @@ export function DifferenceZonedDateTimeWithRounding( const duration = DifferenceZonedDateTime(ns1, ns2, timeZone, calendar, largestUnit); - if (smallestUnit === 'nanosecond' && roundingIncrement === 1) { - return { duration, total: duration.norm.totalNs.toJSNumber() }; - } + if (smallestUnit === 'nanosecond' && roundingIncrement === 1) return duration; const dateTime = GetISODateTimeFor(timeZone, ns1); return RoundRelativeDuration( @@ -3828,6 +3900,17 @@ export function DifferenceZonedDateTimeWithRounding( ); } +export function DifferenceZonedDateTimeWithTotal(ns1, ns2, timeZone, calendar, unit) { + if (TemporalUnitCategory(unit) === 'time') { + // The user is only asking for a time difference, so return difference of instants. + return TotalTimeDuration(TimeDuration.fromEpochNsDiff(ns2, ns1), unit); + } + + const duration = DifferenceZonedDateTime(ns1, ns2, timeZone, calendar, unit); + const dateTime = GetISODateTimeFor(timeZone, ns1); + return TotalRelativeDuration(duration, ns2, dateTime, timeZone, calendar, unit); +} + export function GetDifferenceSettings(op, options, group, disallowed, fallbackSmallest, smallestLargestDefaultUnit) { const ALLOWED_UNITS = Call(ArrayPrototypeReduce, TEMPORAL_UNITS, [ (allowed, unitInfo) => { @@ -3888,7 +3971,7 @@ export function DifferenceTemporalInstant(operation, instant, other, options) { const onens = GetSlot(instant, EPOCHNANOSECONDS); const twons = GetSlot(other, EPOCHNANOSECONDS); - const { duration } = DifferenceInstant( + const duration = DifferenceInstant( onens, twons, settings.roundingIncrement, @@ -3947,7 +4030,7 @@ export function DifferenceTemporalPlainDate(operation, plainDate, other, options settings.roundingIncrement, settings.smallestUnit, settings.roundingMode - ).duration; + ); } let result = UnnormalizeDuration(duration, 'day'); @@ -3981,7 +4064,7 @@ export function DifferenceTemporalPlainDateTime(operation, plainDateTime, other, return new Duration(); } - const { duration } = DifferencePlainDateTimeWithRounding( + const duration = DifferencePlainDateTimeWithRounding( GetSlot(plainDateTime, ISO_YEAR), GetSlot(plainDateTime, ISO_MONTH), GetSlot(plainDateTime, ISO_DAY), @@ -4034,12 +4117,7 @@ export function DifferenceTemporalPlainTime(operation, plainTime, other, options ); let duration = { date: ZeroDateDuration(), norm }; if (settings.smallestUnit !== 'nanosecond' || settings.roundingIncrement !== 1) { - ({ duration } = RoundTimeDuration( - duration, - settings.roundingIncrement, - settings.smallestUnit, - settings.roundingMode - )); + duration = RoundTimeDuration(duration, settings.roundingIncrement, settings.smallestUnit, settings.roundingMode); } let result = UnnormalizeDuration(duration, settings.largestUnit); @@ -4099,7 +4177,7 @@ export function DifferenceTemporalPlainYearMonth(operation, yearMonth, other, op settings.roundingIncrement, settings.smallestUnit, settings.roundingMode - ).duration; + ); } let result = UnnormalizeDuration(duration, 'day'); @@ -4126,7 +4204,7 @@ export function DifferenceTemporalZonedDateTime(operation, zonedDateTime, other, let result; if (TemporalUnitCategory(settings.largestUnit) !== 'date') { // The user is only asking for a time difference, so return difference of instants. - const { duration } = DifferenceInstant( + const duration = DifferenceInstant( ns1, ns2, settings.roundingIncrement, @@ -4145,7 +4223,7 @@ export function DifferenceTemporalZonedDateTime(operation, zonedDateTime, other, if (ns1.equals(ns2)) return new Duration(); - const { duration } = DifferenceZonedDateTimeWithRounding( + const duration = DifferenceZonedDateTimeWithRounding( ns1, ns2, timeZone, @@ -4463,24 +4541,23 @@ export function RoundTime(hour, minute, second, millisecond, microsecond, nanose export function RoundTimeDuration(duration, increment, unit, roundingMode) { // unit must not be a calendar unit - - let days = duration.date.days; - let norm = duration.norm; - let total; if (unit === 'day') { // First convert time units up to days - const { quotient, remainder } = norm.divmod(DAY_NANOS); - days += quotient; - total = days + remainder.fdiv(DAY_NANOS); - days = RoundNumberToIncrement(total, increment, roundingMode); - norm = TimeDuration.ZERO; - } else { - const divisor = Call(MapPrototypeGet, NS_PER_TIME_UNIT, [unit]); - total = norm.fdiv(divisor); - norm = norm.round(divisor * increment, roundingMode); + const { quotient, remainder } = duration.norm.divmod(DAY_NANOS); + let days = duration.date.days + quotient + remainder.fdiv(DAY_NANOS); + days = RoundNumberToIncrement(days, increment, roundingMode); + const dateDuration = AdjustDateDurationRecord(duration.date, days); + return CombineDateAndNormalizedTimeDuration(dateDuration, TimeDuration.ZERO); } - const dateDuration = AdjustDateDurationRecord(duration.date, days); - return { duration: CombineDateAndNormalizedTimeDuration(dateDuration, norm), total }; + + const divisor = Call(MapPrototypeGet, NS_PER_TIME_UNIT, [unit]); + const norm = duration.norm.round(divisor * increment, roundingMode); + return CombineDateAndNormalizedTimeDuration(duration.date, norm); +} + +export function TotalTimeDuration(norm, unit) { + const divisor = Call(MapPrototypeGet, NS_PER_TIME_UNIT, [unit]); + return norm.fdiv(divisor); } export function CompareISODate(y1, m1, d1, y2, m2, d2) { diff --git a/spec/duration.html b/spec/duration.html index 9acec68c8..c277c42b1 100644 --- a/spec/duration.html +++ b/spec/duration.html @@ -432,9 +432,9 @@

Temporal.Duration.prototype.round ( _roundTo_ )

1. Let _calendar_ be _zonedRelativeTo_.[[Calendar]]. 1. Let _relativeEpochNs_ be _zonedRelativeTo_.[[EpochNanoseconds]]. 1. Let _targetEpochNs_ be ? AddZonedDateTime(_relativeEpochNs_, _timeZone_, _calendar_, _normalizedDuration_, ~constrain~). - 1. Let _roundRecord_ be ? DifferenceZonedDateTimeWithRounding(_relativeEpochNs_, _targetEpochNs_, _timeZone_, _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_). + 1. Set _normalizedDuration_ to ? DifferenceZonedDateTimeWithRounding(_relativeEpochNs_, _targetEpochNs_, _timeZone_, _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_). 1. If TemporalUnitCategory(_largestUnit_) is ~date~, set _largestUnit_ to ~hour~. - 1. Return ? UnnormalizeDuration(_roundRecord_.[[NormalizedDuration]], _largestUnit_). + 1. Return ? UnnormalizeDuration(_normalizedDuration_, _largestUnit_). 1. If _plainRelativeTo_ is not *undefined*, then 1. Let _normalizedDuration_ be NormalizeDurationWith24HourDays(_duration_). 1. Let _targetTime_ be AddTime(0, 0, 0, 0, 0, 0, _normalizedDuration_.[[NormalizedTime]]). @@ -442,12 +442,12 @@

Temporal.Duration.prototype.round ( _roundTo_ )

1. Let _calendar_ be _plainRelativeTo_.[[Calendar]]. 1. Let _dateDuration_ be ! AdjustDateDurationRecord(_normalizedDuration_.[[Date]], _targetTime_.[[Days]]). 1. Let _targetDate_ be ? CalendarDateAdd(_calendar_, _isoRelativeToDate_, _dateDuration_, ~constrain~). - 1. Let _roundRecord_ be ? DifferencePlainDateTimeWithRounding(_isoRelativeToDate_.[[Year]], _isoRelativeToDate_.[[Month]], _isoRelativeToDate_.[[Day]], 0, 0, 0, 0, 0, 0, _targetDate_.[[Year]], _targetDate_.[[Month]], _targetDate_.[[Day]], _targetTime_.[[Hour]], _targetTime_.[[Minute]], _targetTime_.[[Second]], _targetTime_.[[Millisecond]], _targetTime_.[[Microsecond]], _targetTime_.[[Nanosecond]], _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_). - 1. Return ? UnnormalizeDuration(_roundRecord_.[[NormalizedDuration]], _largestUnit_). + 1. Set _normalizedDuration_ to ? DifferencePlainDateTimeWithRounding(_isoRelativeToDate_.[[Year]], _isoRelativeToDate_.[[Month]], _isoRelativeToDate_.[[Day]], 0, 0, 0, 0, 0, 0, _targetDate_.[[Year]], _targetDate_.[[Month]], _targetDate_.[[Day]], _targetTime_.[[Hour]], _targetTime_.[[Minute]], _targetTime_.[[Second]], _targetTime_.[[Millisecond]], _targetTime_.[[Microsecond]], _targetTime_.[[Nanosecond]], _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_). + 1. Return ? UnnormalizeDuration(_normalizedDuration_, _largestUnit_). 1. If IsCalendarUnit(_existingLargestUnit_) is *true*, or IsCalendarUnit(_largestUnit_) is *true*, throw a *RangeError* exception. 1. Assert: IsCalendarUnit(_smallestUnit_) is *false*. 1. Let _normalizedDuration_ be NormalizeDurationWith24HourDays(_duration_). - 1. Set _normalizedDuration_ to ? RoundTimeDuration(_normalizedDuration_, _roundingIncrement_, _smallestUnit_, _roundingMode_).[[NormalizedDuration]]. + 1. Set _normalizedDuration_ to ? RoundTimeDuration(_normalizedDuration_, _roundingIncrement_, _smallestUnit_, _roundingMode_). 1. Return ? UnnormalizeDuration(_normalizedDuration_, _largestUnit_). @@ -476,7 +476,7 @@

Temporal.Duration.prototype.total ( _totalOf_ )

1. Let _calendar_ be _zonedRelativeTo_.[[Calendar]]. 1. Let _relativeEpochNs_ be _zonedRelativeTo_.[[EpochNanoseconds]]. 1. Let _targetEpochNs_ be ? AddZonedDateTime(_relativeEpochNs_, _timeZone_, _calendar_, _normalizedDuration_, ~constrain~). - 1. Let _roundRecord_ be ? DifferenceZonedDateTimeWithRounding(_relativeEpochNs_, _targetEpochNs_, _timeZone_, _calendar_, _unit_, 1, _unit_, ~trunc~). + 1. Let _total_ be ? DifferenceZonedDateTimeWithTotal(_relativeEpochNs_, _targetEpochNs_, _timeZone_, _calendar_, _unit_). 1. Else if _plainRelativeTo_ is not *undefined*, then 1. Let _normalizedDuration_ be NormalizeDurationWith24HourDays(_duration_). 1. Let _targetTime_ be AddTime(0, 0, 0, 0, 0, 0, _normalizedDuration_.[[NormalizedTime]]). @@ -484,14 +484,13 @@

Temporal.Duration.prototype.total ( _totalOf_ )

1. Let _calendar_ be _plainRelativeTo_.[[Calendar]]. 1. Let _dateDuration_ be ! AdjustDateDurationRecord(_normalizedDuration_.[[Date]], _targetTime_.[[Days]]). 1. Let _targetDate_ be ? CalendarDateAdd(_calendar_, _isoRelativeToDate_, _dateDuration_, ~constrain~). - 1. Let _roundRecord_ be ? DifferencePlainDateTimeWithRounding(_isoRelativeToDate_.[[Year]], _isoRelativeToDate_.[[Month]], _isoRelativeToDate_.[[Day]], 0, 0, 0, 0, 0, 0, _targetDate_.[[Year]], _targetDate_.[[Month]], _targetDate_.[[Day]], _targetTime_.[[Hour]], _targetTime_.[[Minute]], _targetTime_.[[Second]], _targetTime_.[[Millisecond]], _targetTime_.[[Microsecond]], _targetTime_.[[Nanosecond]], _calendar_, _unit_, 1, _unit_, ~trunc~). + 1. Let _total_ be ? DifferencePlainDateTimeWithTotal(_isoRelativeToDate_.[[Year]], _isoRelativeToDate_.[[Month]], _isoRelativeToDate_.[[Day]], 0, 0, 0, 0, 0, 0, _targetDate_.[[Year]], _targetDate_.[[Month]], _targetDate_.[[Day]], _targetTime_.[[Hour]], _targetTime_.[[Minute]], _targetTime_.[[Second]], _targetTime_.[[Millisecond]], _targetTime_.[[Microsecond]], _targetTime_.[[Nanosecond]], _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 _normalizedDuration_ be NormalizeDurationWith24HourDays(_duration_). - 1. Let _roundRecord_ be ? RoundTimeDuration(_normalizedDuration_, 1, _unit_, ~trunc~). - 1. Assert: _roundRecord_.[[Total]] is not ~unset~. - 1. Return 𝔽(_roundRecord_.[[Total]]). + 1. Let _total_ be TotalTimeDuration(_normalizedDuration_, _unit_). + 1. Return 𝔽(_total_). @@ -512,9 +511,9 @@

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

1. Return TemporalDurationToString(_duration_, _precision_.[[Precision]]). 1. Let _largestUnit_ be DefaultTemporalLargestUnit(_duration_). 1. Let _normalizedDuration_ be NormalizeDuration(_duration_). - 1. Let _roundRecord_ be ? RoundTimeDuration(_normalizedDuration_, _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). + 1. Set _normalizedDuration_ to ? RoundTimeDuration(_normalizedDuration_, _precision_.[[Increment]], _precision_.[[Unit]], _roundingMode_). 1. Let _roundedLargestUnit_ be LargerOfTwoTemporalUnits(_largestUnit_, ~second~). - 1. Let _roundedDuration_ be ! UnnormalizeDuration(_roundRecord_.[[NormalizedDuration]], _roundedLargestUnit_). + 1. Let _roundedDuration_ be ! UnnormalizeDuration(_normalizedDuration_, _roundedLargestUnit_). 1. Return TemporalDurationToString(_roundedDuration_, _precision_.[[Precision]]). @@ -1586,33 +1585,41 @@

_increment_: a positive integer, _unit_: a time unit or ~day~, _roundingMode_: a rounding mode, - ): either a normal completion containing a Record with fields [[NormalizedDuration]] (a Normalized Duration Record) and [[Total]] (a mathematical value), or a throw completion + ): either a normal completion containing a Normalized Duration Record, or a throw completion

description
- It rounds a _duration_ according to the rounding parameters _unit_, _increment_, and _roundingMode_, and returns a Record with the Normalized Duration Record result in its [[NormalizedDuration]] field. - It also returns the total of the smallest unit before the rounding operation in its [[Total]] field, for use in `Temporal.Duration.prototype.total`. + It rounds a _duration_ according to the rounding parameters _unit_, _increment_, and _roundingMode_, and returns the Normalized Duration Record result.
- 1. Let _days_ be _duration_.[[Date]].[[Days]]. - 1. Let _norm_ be _duration_.[[NormalizedTime]]. 1. If _unit_ is ~day~, then - 1. Let _fractionalDays_ be _days_ + DivideNormalizedTimeDuration(_norm_, nsPerDay). - 1. Set _days_ to RoundNumberToIncrement(_fractionalDays_, _increment_, _roundingMode_). - 1. Let _total_ be _fractionalDays_. - 1. Set _norm_ to ZeroTimeDuration(). - 1. Else, - 1. Assert: TemporalUnitCategory(_unit_) is ~time~. - 1. Let _divisor_ be the value in the "Length in Nanoseconds" column of the row of whose "Value" column contains _unit_. - 1. Let _total_ be DivideNormalizedTimeDuration(_norm_, _divisor_). - 1. Set _norm_ to ? RoundNormalizedTimeDurationToIncrement(_norm_, _divisor_ × _increment_, _roundingMode_). - 1. Let _dateDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], _days_). - 1. Return the Record { - [[NormalizedDuration]]: ? CombineDateAndNormalizedTimeDuration(_dateDuration_, _norm_), - [[Total]]: _total_ - }. + 1. Let _fractionalDays_ be _duration_.[[Date]].[[Days]] + DivideNormalizedTimeDuration(_duration_.[[NormalizedTime]], nsPerDay). + 1. Let _days_ be RoundNumberToIncrement(_fractionalDays_, _increment_, _roundingMode_). + 1. Let _dateDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], _days_). + 1. Return ! CombineDateAndNormalizedTimeDuration(_dateDuration_, ZeroTimeDuration()). + 1. Assert: TemporalUnitCategory(_unit_) is ~time~. + 1. Let _divisor_ be the value in the "Length in Nanoseconds" column of the row of whose "Value" column contains _unit_. + 1. Let _norm_ be ? RoundNormalizedTimeDurationToIncrement(_duration_.[[NormalizedTime]], _divisor_ × _increment_, _roundingMode_). + 1. Return ? CombineDateAndNormalizedTimeDuration(_duration_.[[Date]], _norm_). + + + + +

+ TotalTimeDuration ( + _norm_: a Normalized Time Duration Record, + _unit_: a time unit or ~day~, + ): a mathematical value +

+
+
description
+
It returns the total number of _unit_ in _duration_.
+
+ + 1. Let _divisor_ be the value in the "Length in Nanoseconds" column of the row of whose "Value" column contains _unit_. + 1. Return DivideNormalizedTimeDuration(_norm_, _divisor_).
@@ -1634,13 +1641,6 @@

Duration Nudge Result Records

The resulting duration. - - [[Total]] - a mathematical value or ~unset~ - - The possibly fractional total of the smallest unit before the rounding operation, for use in `Temporal.Duration.prototype.total`, or ~unset~ if not relevant. - - [[NudgedEpochNs]] a BigInt @@ -1671,7 +1671,7 @@

_increment_: a positive integer, _unit_: a date unit, _roundingMode_: a rounding mode, - ): either a normal completion containing a Duration Nudge Result Record or a throw completion + ): either a normal completion containing a Record with fields [[NudgeResult]] (a Duration Nudge Result Record) and [[Total]] (a mathematical value), or a throw completion

description
@@ -1748,7 +1748,8 @@

1. Let _resultDuration_ be _startDuration_. 1. Let _nudgedEpochNs_ be _startEpochNs_. 1. Set _resultDuration_ to ! CombineDateAndNormalizedTimeDuration(_resultDuration_, ZeroTimeDuration()). - 1. Return Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[Total]]: _total_, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didExpandCalendarUnit_ }. + 1. Let _nudgeResult_ be Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didExpandCalendarUnit_ }. + 1. Return the Record { [[NudgeResult]]: _nudgeResult_, [[Total]]: _total_ }. @@ -1795,7 +1796,7 @@

1. Let _nudgedEpochNs_ be AddNormalizedTimeDurationToEpochNanoseconds(_roundedNorm_, _startEpochNs_). 1. Let _dateDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], _duration_.[[Date]].[[Days]] + _dayDelta_). 1. Let _resultDuration_ be ? CombineDateAndNormalizedTimeDuration(_dateDuration_, _roundedNorm_). - 1. Return Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[Total]]: ~unset~, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didRoundBeyondDay_ }. + 1. Return Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didRoundBeyondDay_ }. @@ -1819,7 +1820,6 @@

1. Let _norm_ be ! Add24HourDaysToNormalizedTimeDuration(_duration_.[[NormalizedTime]], _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 _total_ be DivideNormalizedTimeDuration(_norm_, _unitLength_). 1. Let _roundedNorm_ be ? RoundNormalizedTimeDurationToIncrement(_norm_, _unitLength_ × _increment_, _roundingMode_). 1. Let _diffNorm_ be ! SubtractNormalizedTimeDuration(_roundedNorm_, _norm_). 1. Let _wholeDays_ be truncate(DivideNormalizedTimeDuration(_norm_, nsPerDay)). @@ -1835,7 +1835,7 @@

1. Set _remainder_ to ! SubtractNormalizedTimeDuration(_roundedNorm_, NormalizeTimeDuration(_roundedWholeDays_ * HoursPerDay, 0, 0, 0, 0, 0)). 1. Let _dateDuration_ be ? AdjustDateDurationRecord(_duration_.[[Date]], _days_). 1. Let _resultDuration_ be ? CombineDateAndNormalizedTimeDuration(_dateDuration_, _remainder_). - 1. Return Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[Total]]: _total_, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didExpandDays_ }. + 1. Return Duration Nudge Result Record { [[Duration]]: _resultDuration_, [[NudgedEpochNs]]: _nudgedEpochNs_, [[DidExpandCalendarUnit]]: _didExpandDays_ }. @@ -1907,13 +1907,12 @@

_increment_: a positive integer, _smallestUnit_: a Temporal unit, _roundingMode_: a rounding mode, - ): either a normal completion containing a Record with fields [[NormalizedDuration]] (a NormalizedDurationRecord) and [[Total]] (a mathematical value or ~unset~), or a throw completion + ): either a normal completion containing a Normalized Duration Record or a throw completion

description
- It rounds a duration _duration_ relative to _dateTime_ according to the rounding parameters _smallestUnit_, _increment_, and _roundingMode_, bubbles overflows up to the next highest unit until _largestUnit_, and returns a normalized duration in its [[NormalizedDuration]] field. - It also returns the total of the smallest unit before the rounding operation in its [[Total]] field, for use in `Temporal.Duration.prototype.total`. + It rounds a duration _duration_ relative to _dateTime_ according to the rounding parameters _smallestUnit_, _increment_, and _roundingMode_, bubbles overflows up to the next highest unit until _largestUnit_, and returns a normalized duration.
@@ -1922,7 +1921,8 @@

1. If _timeZone_ is not ~unset~ and _smallestUnit_ is ~day~, set _irregularLengthUnit_ to *true*. 1. If NormalizedDurationSign(_duration_) < 0, let _sign_ be -1; else let _sign_ be 1. 1. If _irregularLengthUnit_ is *true*, then - 1. Let _nudgeResult_ be ? NudgeToCalendarUnit(_sign_, _duration_, _destEpochNs_, _dateTime_, _timeZone_, _calendar_, _increment_, _smallestUnit_, _roundingMode_). + 1. Let _record_ be ? NudgeToCalendarUnit(_sign_, _duration_, _destEpochNs_, _dateTime_, _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_, _dateTime_, _timeZone_, _calendar_, _increment_, _smallestUnit_, _roundingMode_). 1. Else, @@ -1931,10 +1931,32 @@

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]], _dateTime_, _timeZone_, _calendar_, _largestUnit_, _startUnit_). - 1. Return the Record { - [[NormalizedDuration]]: _duration_, - [[Total]]: _nudgeResult_.[[Total]] - }. + 1. Return _duration_. + + + + +

+ TotalRelativeDuration ( + _duration_: a Normalized Duration Record, + _destEpochNs_: a BigInt, + _dateTime_: 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 +

+
+
description
+
It returns the total number of _unit_ in _duration_, relative to _dateTime_ if a starting point is necessary for calendar units.
+
+ + 1. If IsCalendarUnit(_unit_) is *true*, or _timeZone_ is not ~unset~ and _unit_ is ~day~, then + 1. Let _sign_ be NormalizedDurationSign(_duration_). + 1. Let _record_ be ? NudgeToCalendarUnit(_sign_, _duration_, _destEpochNs_, _dateTime_, _timeZone_, _calendar_, 1, _unit_, ~trunc~). + 1. Return _record_.[[Total]]. + 1. Let _norm_ be ! Add24HourDaysToNormalizedTimeDuration(_duration_.[[NormalizedTime]], _duration_.[[Date]].[[Days]]). + 1. Return TotalTimeDuration(_norm_, _unit_).
diff --git a/spec/instant.html b/spec/instant.html index c92e1db6f..68993569d 100644 --- a/spec/instant.html +++ b/spec/instant.html @@ -466,7 +466,7 @@

_roundingIncrement_: a positive integer, _smallestUnit_: a time unit or ~day~, _roundingMode_: a rounding mode, - ): a Record with fields [[NormalizedDuration]] (a Normalized Duration Record) and [[Total]] (a mathematical value) + ): a Normalized Duration Record

description
@@ -543,8 +543,8 @@

1. Set _other_ to ? ToTemporalInstant(_other_). 1. Let _resolvedOptions_ be ? GetOptionsObject(_options_). 1. Let _settings_ be ? GetDifferenceSettings(_operation_, _resolvedOptions_, ~time~, « », ~nanosecond~, ~second~). - 1. Let _diffRecord_ be DifferenceInstant(_instant_.[[EpochNanoseconds]], _other_.[[EpochNanoseconds]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). - 1. Let _result_ be ! UnnormalizeDuration(_diffRecord_.[[NormalizedDuration]], _settings_.[[LargestUnit]]). + 1. Let _normalizedDuration_ be DifferenceInstant(_instant_.[[EpochNanoseconds]], _other_.[[EpochNanoseconds]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). + 1. Let _result_ be ! UnnormalizeDuration(_normalizedDuration_, _settings_.[[LargestUnit]]). 1. If _operation_ is ~since~, set _result_ to CreateNegatedTemporalDuration(_result_). 1. Return _result_. diff --git a/spec/plaindatetime.html b/spec/plaindatetime.html index 78e44f14c..b70858490 100644 --- a/spec/plaindatetime.html +++ b/spec/plaindatetime.html @@ -1206,7 +1206,7 @@

_roundingIncrement_: a positive integer, _smallestUnit_: a Temporal unit, _roundingMode_: a rounding mode, - ): either a normal completion containing a Record with fields [[NormalizedDuration]] (a Normalized Duration Record) and [[Total]] (a mathematical value), or a throw completion + ): either a normal completion containing a Normalized Duration Record or a throw completion

description
@@ -1216,17 +1216,57 @@

1. Assert: IsValidISODate(_y1_, _mon1_, _d1_) is *true*. 1. Assert: IsValidISODate(_y2_, _mon2_, _d2_) is *true*. 1. If CompareISODateTime(_y1_, _mon1_, _d1_, _h1_, _min1_, _s1_, _ms1_, _mus1_, _ns1_, _y2_, _mon2_, _d2_, _h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_) = 0, then - 1. Let _duration_ be ! CombineDateAndNormalizedTimeDuration(ZeroDateDuration(), ZeroTimeDuration()). - 1. Return the Record { [[NormalizedDuration]]: _duration_, [[Total]]: 0 }. + 1. Return ! CombineDateAndNormalizedTimeDuration(ZeroDateDuration(), ZeroTimeDuration()). 1. Let _diff_ be ? DifferenceISODateTime(_y1_, _mon1_, _d1_, _h1_, _min1_, _s1_, _ms1_, _mus1_, _ns1_, _y2_, _mon2_, _d2_, _h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_, _calendar_, _largestUnit_). - 1. If _smallestUnit_ is ~nanosecond~ and _roundingIncrement_ = 1, then - 1. Return the Record { [[NormalizedDuration]]: _diff_, [[Total]]: _diff_.[[NormalizedTime]].[[TotalNanoseconds]] }. + 1. If _smallestUnit_ is ~nanosecond~ and _roundingIncrement_ = 1, return _diff_. 1. Let _dateTime_ be ISO Date-Time Record { [[Year]]: _y1_, [[Month]]: _mon1_, [[Day]]: _d1_, [[Hour]]: _h1_, [[Minute]]: _min1_, [[Second]]: _s1_, [[Millisecond]]: _ms1_, [[Microsecond]]: _mus1_, [[Nanosecond]]: _ns1_ }. 1. Let _destEpochNs_ be GetUTCEpochNanoseconds(_y2_, _mon2_, _d2_, _h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_). 1. Return ? RoundRelativeDuration(_diff_, _destEpochNs_, _dateTime_, ~unset~, _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_). + +

+ DifferencePlainDateTimeWithTotal ( + _y1_: an integer, + _mon1_: an integer, + _d1_: an integer, + _h1_: an integer in the inclusive interval from 0 to 23, + _min1_: an integer in the inclusive interval from 0 to 59, + _s1_: an integer in the inclusive interval from 0 to 59, + _ms1_: an integer in the inclusive interval from 0 to 999, + _mus1_: an integer in the inclusive interval from 0 to 999, + _ns1_: an integer in the inclusive interval from 0 to 999, + _y2_: an integer, + _mon2_: an integer, + _d2_: an integer, + _h2_: an integer in the inclusive interval from 0 to 23, + _min2_: an integer in the inclusive interval from 0 to 59, + _s2_: an integer in the inclusive interval from 0 to 59, + _ms2_: an integer in the inclusive interval from 0 to 999, + _mus2_: an integer in the inclusive interval from 0 to 999, + _ns2_: an integer in the inclusive interval from 0 to 999, + _calendar_: a calendar type, + _unit_: a Temporal unit, + ): either a normal completion containing a mathematical value or a throw completion +

+
+
description
+
+
+ + 1. Assert: IsValidISODate(_y1_, _mon1_, _d1_) is *true*. + 1. Assert: IsValidISODate(_y2_, _mon2_, _d2_) is *true*. + 1. If CompareISODateTime(_y1_, _mon1_, _d1_, _h1_, _min1_, _s1_, _ms1_, _mus1_, _ns1_, _y2_, _mon2_, _d2_, _h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_) = 0, then + 1. Return 0. + 1. Let _diff_ be ? DifferenceISODateTime(_y1_, _mon1_, _d1_, _h1_, _min1_, _s1_, _ms1_, _mus1_, _ns1_, _y2_, _mon2_, _d2_, _h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_, _calendar_, _unit_). + 1. If _unit_ is ~nanosecond~, return _diff_.[[NormalizedTime]].[[TotalNanoseconds]]. + 1. Let _dateTime_ be ISO Date-Time Record { [[Year]]: _y1_, [[Month]]: _mon1_, [[Day]]: _d1_, [[Hour]]: _h1_, [[Minute]]: _min1_, [[Second]]: _s1_, [[Millisecond]]: _ms1_, [[Microsecond]]: _mus1_, [[Nanosecond]]: _ns1_ }. + 1. Let _destEpochNs_ be GetUTCEpochNanoseconds(_y2_, _mon2_, _d2_, _h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_). + 1. Return ? TotalRelativeDuration(_diff_, _destEpochNs_, _dateTime_, ~unset~, _calendar_, _unit_). + +
+

DifferenceTemporalPlainDateTime ( @@ -1248,8 +1288,8 @@

1. If _dateTime_.[[ISOYear]] = _other_.[[ISOYear]], and _dateTime_.[[ISOMonth]] = _other_.[[ISOMonth]], and _dateTime_.[[ISODay]] = _other_.[[ISODay]], and _dateTime_.[[ISOHour]] = _other_.[[ISOHour]], and _dateTime_.[[ISOMinute]] = _other_.[[ISOMinute]], and _dateTime_.[[ISOSecond]] = _other_.[[ISOSecond]], and _dateTime_.[[ISOMillisecond]] = _other_.[[ISOMillisecond]], and _dateTime_.[[ISOMicrosecond]] = _other_.[[ISOMicrosecond]], and _dateTime_.[[ISONanosecond]] = _other_.[[ISONanosecond]], then 1. Return ! CreateTemporalDuration(0, 0, 0, 0, 0, 0, 0, 0, 0, 0). 1. Let _plainDate_ be ! CreateTemporalDate(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[Calendar]]). - 1. Let _resultRecord_ be ? DifferencePlainDateTimeWithRounding(_plainDate_.[[ISOYear]], _plainDate_.[[ISOMonth]], _plainDate_.[[ISODay]], _dateTime_.[[ISOHour]], _dateTime_.[[ISOMinute]], _dateTime_.[[ISOSecond]], _dateTime_.[[ISOMillisecond]], _dateTime_.[[ISOMicrosecond]], _dateTime_.[[ISONanosecond]], _other_.[[ISOYear]], _other_.[[ISOMonth]], _other_.[[ISODay]], _other_.[[ISOHour]], _other_.[[ISOMinute]], _other_.[[ISOSecond]], _other_.[[ISOMillisecond]], _other_.[[ISOMicrosecond]], _other_.[[ISONanosecond]], _dateTime_.[[Calendar]], _settings_.[[LargestUnit]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). - 1. Let _result_ be ? UnnormalizeDuration(_resultRecord_.[[NormalizedDuration]], _settings_.[[LargestUnit]]). + 1. Let _normalizedDuration_ be ? DifferencePlainDateTimeWithRounding(_plainDate_.[[ISOYear]], _plainDate_.[[ISOMonth]], _plainDate_.[[ISODay]], _dateTime_.[[ISOHour]], _dateTime_.[[ISOMinute]], _dateTime_.[[ISOSecond]], _dateTime_.[[ISOMillisecond]], _dateTime_.[[ISOMicrosecond]], _dateTime_.[[ISONanosecond]], _other_.[[ISOYear]], _other_.[[ISOMonth]], _other_.[[ISODay]], _other_.[[ISOHour]], _other_.[[ISOMinute]], _other_.[[ISOSecond]], _other_.[[ISOMillisecond]], _other_.[[ISOMicrosecond]], _other_.[[ISONanosecond]], _dateTime_.[[Calendar]], _settings_.[[LargestUnit]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). + 1. Let _result_ be ? UnnormalizeDuration(_normalizedDuration_, _settings_.[[LargestUnit]]). 1. If _operation_ is ~since~, set _result_ to CreateNegatedTemporalDuration(_result_). 1. Return _result_. diff --git a/spec/plaintime.html b/spec/plaintime.html index da041b278..705c06cb1 100644 --- a/spec/plaintime.html +++ b/spec/plaintime.html @@ -999,8 +999,7 @@

1. Let _norm_ be DifferenceTime(_temporalTime_.[[ISOHour]], _temporalTime_.[[ISOMinute]], _temporalTime_.[[ISOSecond]], _temporalTime_.[[ISOMillisecond]], _temporalTime_.[[ISOMicrosecond]], _temporalTime_.[[ISONanosecond]], _other_.[[ISOHour]], _other_.[[ISOMinute]], _other_.[[ISOSecond]], _other_.[[ISOMillisecond]], _other_.[[ISOMicrosecond]], _other_.[[ISONanosecond]]). 1. Let _duration_ be ! CombineDateAndNormalizedTimeDuration(ZeroDateDuration(), _norm_). 1. If _settings_.[[SmallestUnit]] is not ~nanosecond~ or _settings_.[[RoundingIncrement]] ≠ 1, then - 1. Let _roundRecord_ be ! RoundTimeDuration(_duration_, _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). - 1. Set _duration_ to _roundRecord_.[[NormalizedDuration]]. + 1. Set _duration_ to ! RoundTimeDuration(_duration_, _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). 1. Let _result_ be ! UnnormalizeDuration(_duration_, _settings_.[[LargestUnit]]). 1. If _operation_ is ~since~, set _result_ to CreateNegatedTemporalDuration(_result_). 1. Return _result_. diff --git a/spec/plainyearmonth.html b/spec/plainyearmonth.html index 94d2597d7..c3c25718b 100644 --- a/spec/plainyearmonth.html +++ b/spec/plainyearmonth.html @@ -677,8 +677,7 @@

1. Let _destEpochNs_ be GetUTCEpochNanoseconds(_otherDate_.[[Year]], _otherDate_.[[Month]], _otherDate_.[[Day]], 0, 0, 0, 0, 0, 0). 1. Let _midnight_ be a Time Record with all fields set to 0. 1. Let _dateTime_ be CombineISODateAndTimeRecord(_thisDate_, _midnight_). - 1. Let _roundResult_ be ? RoundRelativeDuration(_duration_, _destEpochNs_, _dateTime_, ~unset~, _calendar_, _settings_.[[LargestUnit]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]).[[Duration]]. - 1. Set _duration_ to _roundResult_.[[NormalizedDuration]]. + 1. Set _duration_ to ? RoundRelativeDuration(_duration_, _destEpochNs_, _dateTime_, ~unset~, _calendar_, _settings_.[[LargestUnit]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]).[[Duration]]. 1. Let _result_ be ? UnnormalizeDuration(_duration_, ~day~). 1. If _operation_ is ~since~, set _result_ to CreateNegatedTemporalDuration(_result_). 1. Return _result_. diff --git a/spec/zoneddatetime.html b/spec/zoneddatetime.html index bf657fdbf..348eebefc 100644 --- a/spec/zoneddatetime.html +++ b/spec/zoneddatetime.html @@ -1157,7 +1157,7 @@

_roundingIncrement_: a positive integer, _smallestUnit_: a Temporal unit, _roundingMode_: a rounding mode, - ): either a normal completion containing a Record with fields [[NormalizedDuration]] (a Normalized Duration Record) and [[Total]] (a mathematical value or ~unset~), or a throw completion + ): either a normal completion containing a Normalized Duration Record, or a throw completion

description
@@ -1167,13 +1167,36 @@

1. If TemporalUnitCategory(_largestUnit_) is ~time~, then 1. Return DifferenceInstant(_ns1_, _ns2_, _roundingIncrement_, _smallestUnit_, _roundingMode_). 1. Let _difference_ be ? DifferenceZonedDateTime(_ns1_, _ns2_, _timeZone_, _calendar_, _largestUnit_). - 1. If _smallestUnit_ is ~nanosecond~ and _roundingIncrement_ = 1, then - 1. Return the Record { [[NormalizedDuration]]: _difference_, [[Total]]: _difference_.[[NormalizedTime]].[[TotalNanoseconds]] }. + 1. If _smallestUnit_ is ~nanosecond~ and _roundingIncrement_ = 1, return _difference_. 1. Let _dateTime_ be GetISODateTimeFor(_timeZone_, _ns1_). 1. Return ? RoundRelativeDuration(_difference_, _ns2_, _dateTime_, _timeZone_, _calendar_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_). + +

+ DifferenceZonedDateTimeWithTotal ( + _ns1_: a BigInt, + _ns2_: a BigInt, + _timeZone_: an available time zone identifier, + _calendar_: a calendar type, + _unit_: a Temporal unit, + ): either a normal completion containing a mathematical value, or a throw completion +

+
+
description
+
+
+ + 1. If TemporalUnitCategory(_unit_) is ~time~, then + 1. Let _difference_ be NormalizedTimeDurationFromEpochNanosecondsDifference(_ns2_, _ns1_). + 1. Return TotalTimeDuration(_difference_, _unit_). + 1. Let _difference_ be ? DifferenceZonedDateTime(_ns1_, _ns2_, _timeZone_, _calendar_, _unit_). + 1. Let _dateTime_ be GetISODateTimeFor(_timeZone_, _ns1_). + 1. Return ? TotalRelativeDuration(_difference_, _ns2_, _dateTime_, _timeZone_, _calendar_, _unit_). + +
+

DifferenceTemporalZonedDateTime ( @@ -1203,8 +1226,8 @@

1. Throw a *RangeError* exception. 1. If _zonedDateTime_.[[EpochNanoseconds]] = _other_.[[EpochNanoseconds]], then 1. Return ! CreateTemporalDuration(0, 0, 0, 0, 0, 0, 0, 0, 0, 0). - 1. Let _resultRecord_ be ? DifferenceZonedDateTimeWithRounding(_zonedDateTime_.[[EpochNanoseconds]], _other_.[[EpochNanoseconds]], _zonedDateTime_.[[TimeZone]], _zonedDateTime_.[[Calendar]], _settings_.[[LargestUnit]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). - 1. Let _result_ be ? UnnormalizeDuration(_resultRecord_.[[Duration]], ~hour~). + 1. Let _normalizedDuration_ be ? DifferenceZonedDateTimeWithRounding(_zonedDateTime_.[[EpochNanoseconds]], _other_.[[EpochNanoseconds]], _zonedDateTime_.[[TimeZone]], _zonedDateTime_.[[Calendar]], _settings_.[[LargestUnit]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). + 1. Let _result_ be ? UnnormalizeDuration(_normalizedDuration_, ~hour~). 1. If _operation_ is ~since~, set _result_ to CreateNegatedTemporalDuration(_result_). 1. Return _result_.