diff --git a/polyfill/lib/duration.mjs b/polyfill/lib/duration.mjs index 1b3a790646..0722ec9374 100644 --- a/polyfill/lib/duration.mjs +++ b/polyfill/lib/duration.mjs @@ -1,7 +1,7 @@ /* global __debug__ */ import * as ES from './ecmascript.mjs'; -import { MakeIntrinsicClass } from './intrinsicclass.mjs'; +import { GetIntrinsic, MakeIntrinsicClass } from './intrinsicclass.mjs'; import { CalendarMethodRecord } from './methodrecord.mjs'; import { YEARS, @@ -17,6 +17,9 @@ import { CALENDAR, INSTANT, EPOCHNANOSECONDS, + ISO_YEAR, + ISO_MONTH, + ISO_DAY, CreateSlots, GetSlot, SetSlot @@ -327,79 +330,106 @@ export class Duration { 'dateUntil' ]); - ({ years, months, weeks, days } = ES.UnbalanceDateDurationRelative( - years, - months, - weeks, - days, - largestUnit, - plainRelativeTo, - calendarRec - )); let norm = TimeDuration.normalize(hours, minutes, seconds, milliseconds, microseconds, nanoseconds); - ({ years, months, weeks, days, norm } = ES.RoundDuration( - years, - months, - weeks, - days, - norm, - roundingIncrement, - smallestUnit, - roundingMode, - plainRelativeTo, - calendarRec, - zonedRelativeTo, - timeZoneRec, - precalculatedPlainDateTime - )); + if (zonedRelativeTo) { - ({ years, months, weeks, days, norm } = ES.AdjustRoundedDurationDays( - years, - months, - weeks, - days, - norm, - roundingIncrement, - smallestUnit, - roundingMode, - zonedRelativeTo, - calendarRec, + const relativeEpochNs = GetSlot(zonedRelativeTo, EPOCHNANOSECONDS); + const targetEpochNs = ES.AddZonedDateTime( + GetSlot(zonedRelativeTo, INSTANT), timeZoneRec, - precalculatedPlainDateTime - )); - const intermediate = ES.MoveRelativeZonedDateTime( - zonedRelativeTo, calendarRec, - timeZoneRec, years, months, weeks, - 0, - precalculatedPlainDateTime - ); - ({ days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.BalanceTimeDurationRelative( days, norm, - largestUnit, - intermediate, - timeZoneRec - )); + precalculatedPlainDateTime + ); + ({ years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = + ES.DifferenceZonedDateTimeWithRounding( + relativeEpochNs, + targetEpochNs, + plainRelativeTo, + calendarRec, + zonedRelativeTo, + timeZoneRec, + precalculatedPlainDateTime, + ObjectCreate(null), + largestUnit, + roundingIncrement, + smallestUnit, + roundingMode + )); + } else if (plainRelativeTo) { + let targetTime = ES.AddTime(0, 0, 0, 0, 0, 0, norm); + + // Delegate the date part addition to the calendar + const TemporalDuration = GetIntrinsic('%Temporal.Duration%'); + const dateDuration = new TemporalDuration(years, months, weeks, days + targetTime.deltaDays, 0, 0, 0, 0, 0, 0); + const targetDate = ES.AddDate(calendarRec, plainRelativeTo, dateDuration); + + ({ years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = + ES.DifferencePlainDateTimeWithRounding( + plainRelativeTo, + 0, + 0, + 0, + 0, + 0, + 0, + GetSlot(targetDate, ISO_YEAR), + GetSlot(targetDate, ISO_MONTH), + GetSlot(targetDate, ISO_DAY), + targetTime.hour, + targetTime.minute, + targetTime.second, + targetTime.millisecond, + targetTime.microsecond, + targetTime.nanosecond, + calendarRec, + largestUnit, + roundingIncrement, + smallestUnit, + roundingMode + )); } else { - ({ days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.BalanceTimeDuration( - norm.add24HourDays(days), - largestUnit - )); + if (calendarUnitsPresent) { + throw new RangeError('a starting point is required for years, months, or weeks balancing'); + } + if (largestUnit === 'year' || largestUnit === 'month' || largestUnit === 'week') { + throw new RangeError(`a starting point is required for ${largestUnit}s balancing`); + } + if (smallestUnit === 'year' || smallestUnit === 'month' || smallestUnit === 'week') { + throw new RangeError(`a starting point is required for ${smallestUnit}s rounding`); + } + + const isoCalendarRec = new CalendarMethodRecord('iso8601', ['dateAdd', 'dateUntil']); + const target = ES.AddDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, isoCalendarRec, years, months, weeks, days, norm); + ({ years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = + ES.DifferencePlainDateTimeWithRounding( + undefined, + 0, + 0, + 0, + 0, + 0, + 0, + target.year, + target.month, + target.day, + target.hour, + target.minute, + target.second, + target.millisecond, + target.microsecond, + target.nanosecond, + isoCalendarRec, + largestUnit, + roundingIncrement, + smallestUnit, + roundingMode + )); } - ({ years, months, weeks, days } = ES.BalanceDateDurationRelative( - years, - months, - weeks, - days, - largestUnit, - smallestUnit, - plainRelativeTo, - calendarRec - )); return new Duration(years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); } @@ -446,69 +476,100 @@ export class Duration { 'dateUntil' ]); - // Convert larger units down to days - ({ years, months, weeks, days } = ES.UnbalanceDateDurationRelative( - years, - months, - weeks, - days, - unit, - plainRelativeTo, - calendarRec - )); - let norm; - // If the unit we're totalling is smaller than `days`, convert days down to that unit. + let norm = TimeDuration.normalize(hours, minutes, seconds, milliseconds, microseconds, nanoseconds); + let total; if (zonedRelativeTo) { - const intermediate = ES.MoveRelativeZonedDateTime( - zonedRelativeTo, - calendarRec, + const relativeEpochNs = GetSlot(zonedRelativeTo, EPOCHNANOSECONDS); + const targetEpochNs = ES.AddZonedDateTime( + GetSlot(zonedRelativeTo, INSTANT), timeZoneRec, + calendarRec, years, months, weeks, - 0, + days, + norm, precalculatedPlainDateTime ); - norm = TimeDuration.normalize(hours, minutes, seconds, milliseconds, microseconds, nanoseconds); - - // Inline BalanceTimeDurationRelative, without the final balance step - const start = GetSlot(intermediate, INSTANT); - const startNs = GetSlot(intermediate, EPOCHNANOSECONDS); - let intermediateNs = startNs; - let startDt; - if (days !== 0) { - startDt = ES.GetPlainDateTimeFor(timeZoneRec, start, 'iso8601'); - intermediateNs = ES.AddDaysToZonedDateTime(start, startDt, timeZoneRec, 'iso8601', days).epochNs; + ({ total } = ES.DifferenceZonedDateTimeWithRounding( + relativeEpochNs, + targetEpochNs, + plainRelativeTo, + calendarRec, + zonedRelativeTo, + timeZoneRec, + precalculatedPlainDateTime, + ObjectCreate(null), + unit, + 1, + unit, + 'trunc' + )); + } else if (plainRelativeTo) { + let targetTime = ES.AddTime(0, 0, 0, 0, 0, 0, norm); + + // Delegate the date part addition to the calendar + const TemporalDuration = GetIntrinsic('%Temporal.Duration%'); + const dateDuration = new TemporalDuration(years, months, weeks, days + targetTime.deltaDays, 0, 0, 0, 0, 0, 0); + const targetDate = ES.AddDate(calendarRec, plainRelativeTo, dateDuration); + + ({ total } = ES.DifferencePlainDateTimeWithRounding( + plainRelativeTo, + 0, + 0, + 0, + 0, + 0, + 0, + GetSlot(targetDate, ISO_YEAR), + GetSlot(targetDate, ISO_MONTH), + GetSlot(targetDate, ISO_DAY), + targetTime.hour, + targetTime.minute, + targetTime.second, + targetTime.millisecond, + targetTime.microsecond, + targetTime.nanosecond, + calendarRec, + unit, + 1, + unit, + 'trunc' + )); + } else { + if (years !== 0 || months !== 0 || weeks !== 0) { + throw new RangeError('a starting point is required for years, months, or weeks total'); } - const endNs = ES.AddInstant(intermediateNs, norm); - norm = TimeDuration.fromEpochNsDiff(endNs, startNs); - if (ES.IsCalendarUnit(unit) || unit === 'day') { - if (!norm.isZero()) startDt ??= ES.GetPlainDateTimeFor(timeZoneRec, start, 'iso8601'); - ({ days, norm } = ES.NormalizedTimeDurationToDays(norm, intermediate, timeZoneRec, startDt)); - } else { - days = 0; + if (unit === 'year' || unit === 'month' || unit === 'week') { + throw new RangeError(`a starting point is required for ${unit}s total`); } - } else { - norm = TimeDuration.normalize(hours, minutes, seconds, milliseconds, microseconds, nanoseconds); - norm = norm.add24HourDays(days); - days = 0; + + const isoCalendarRec = new CalendarMethodRecord('iso8601', ['dateAdd', 'dateUntil']); + const target = ES.AddDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, isoCalendarRec, years, months, weeks, days, norm); + ({ total } = ES.DifferencePlainDateTimeWithRounding( + undefined, + 0, + 0, + 0, + 0, + 0, + 0, + target.year, + target.month, + target.day, + target.hour, + target.minute, + target.second, + target.millisecond, + target.microsecond, + target.nanosecond, + isoCalendarRec, + unit, + 1, + unit, + 'trunc' + )); } - // Finally, truncate to the correct unit and calculate remainder - const { total } = ES.RoundDuration( - years, - months, - weeks, - days, - norm, - 1, - unit, - 'trunc', - plainRelativeTo, - calendarRec, - zonedRelativeTo, - timeZoneRec, - precalculatedPlainDateTime - ); return total; } toString(options = undefined) { diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs index 14f3355ba1..2f698d9642 100644 --- a/polyfill/lib/ecmascript.mjs +++ b/polyfill/lib/ecmascript.mjs @@ -3765,9 +3765,7 @@ export function DifferenceTime(h1, min1, s1, ms1, µs1, ns1, h2, min2, s2, ms2, export function DifferenceInstant(ns1, ns2, increment, smallestUnit, roundingMode) { const diff = TimeDuration.fromEpochNsDiff(ns2, ns1); - if (smallestUnit === 'nanosecond' && increment === 1) return diff; - - return RoundDuration(0, 0, 0, 0, diff, increment, smallestUnit, roundingMode).norm; + return RoundDuration(0, 0, 0, 0, diff, increment, smallestUnit, roundingMode); } export function DifferenceDate(calendarRec, plainDate1, plainDate2, options) { @@ -3909,6 +3907,212 @@ export function DifferenceZonedDateTime( return { years, months, weeks, days, norm }; } +export function DifferencePlainDateTimeWithRounding( + plainDate1, + h1, + min1, + s1, + ms1, + µs1, + ns1, + y2, + mon2, + d2, + h2, + min2, + s2, + ms2, + µs2, + ns2, + calendarRec, + largestUnit, + roundingIncrement, + smallestUnit, + roundingMode, + resolvedOptions +) { + const y1 = plainDate1 ? GetSlot(plainDate1, ISO_YEAR) : 1970; + const mon1 = plainDate1 ? GetSlot(plainDate1, ISO_MONTH) : 1; + const d1 = plainDate1 ? GetSlot(plainDate1, ISO_DAY) : 1; + if (CompareISODateTime(y1, mon1, d1, h1, min1, s1, ms1, µs1, ns1, y2, mon2, d2, h2, min2, s2, ms2, µs2, ns2) == 0) { + return { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours: 0, + minutes: 0, + seconds: 0, + milliseconds: 0, + microseconds: 0, + nanoseconds: 0, + total: 0 + }; + } + + let { years, months, weeks, days, norm } = DifferenceISODateTime( + y1, + mon1, + d1, + h1, + min1, + s1, + ms1, + µs1, + ns1, + y2, + mon2, + d2, + h2, + min2, + s2, + ms2, + µs2, + ns2, + calendarRec, + largestUnit, + resolvedOptions + ); + + const roundingIsNoop = smallestUnit === 'nanosecond' && roundingIncrement === 1; + if (roundingIsNoop) { + const normWithDays = norm.add24HourDays(days); + let hours, minutes, seconds, milliseconds, microseconds, nanoseconds; + ({ days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration( + normWithDays, + largestUnit + )); + return { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds }; + } + + let total; + ({ years, months, weeks, days, norm, total } = RoundDuration( + years, + months, + weeks, + days, + norm, + roundingIncrement, + smallestUnit, + roundingMode, + plainDate1, + calendarRec + )); + const normWithDays = norm.add24HourDays(days); + let hours, minutes, seconds, milliseconds, microseconds, nanoseconds; + ({ days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration( + normWithDays, + largestUnit + )); + ({ years, months, weeks, days } = BalanceDateDurationRelative( + years, + months, + weeks, + days, + largestUnit, + smallestUnit, + plainDate1, + calendarRec + )); + return { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, total }; +} + +export function DifferenceZonedDateTimeWithRounding( + ns1, + ns2, + plainRelativeTo, + calendarRec, + zonedDateTime, + timeZoneRec, + precalculatedPlainDateTime, + resolvedOptions, + largestUnit, + roundingIncrement, + smallestUnit, + roundingMode +) { + if (!IsCalendarUnit(largestUnit) && largestUnit !== 'day') { + // The user is only asking for a time difference, so return difference of instants. + const { norm, total } = DifferenceInstant(ns1, ns2, roundingIncrement, smallestUnit, largestUnit, roundingMode); + const { hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration(norm, largestUnit); + return { + years: 0, + months: 0, + weeks: 0, + days: 0, + hours, + minutes, + seconds, + milliseconds, + microseconds, + nanoseconds, + total + }; + } + + resolvedOptions.largestUnit = largestUnit; + let { years, months, weeks, days, norm } = DifferenceZonedDateTime( + ns1, + ns2, + timeZoneRec, + calendarRec, + largestUnit, + resolvedOptions, + precalculatedPlainDateTime + ); + + const roundingIsNoop = smallestUnit === 'nanosecond' && roundingIncrement === 1; + if (roundingIsNoop) { + const { hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration(norm, 'hour'); + return { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds }; + } + + let total; + ({ years, months, weeks, days, norm, total } = RoundDuration( + years, + months, + weeks, + days, + norm, + roundingIncrement, + smallestUnit, + roundingMode, + plainRelativeTo, + calendarRec, + zonedDateTime, + timeZoneRec, + precalculatedPlainDateTime + )); + ({ years, months, weeks, days, norm } = AdjustRoundedDurationDays( + years, + months, + weeks, + days, + norm, + roundingIncrement, + smallestUnit, + roundingMode, + zonedDateTime, + calendarRec, + timeZoneRec, + precalculatedPlainDateTime + )); + ({ years, months, weeks, days } = BalanceDateDurationRelative( + years, + months, + weeks, + days, + largestUnit, + smallestUnit, + plainRelativeTo, + calendarRec + )); + CombineDateAndNormalizedTimeDuration(years, months, weeks, days, norm); + const { hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration(norm, 'hour'); + + return { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, total }; +} + export function GetDifferenceSettings(op, options, group, disallowed, fallbackSmallest, smallestLargestDefaultUnit) { const ALLOWED_UNITS = SINGULAR_PLURAL_UNITS.reduce((allowed, unitInfo) => { const p = unitInfo[0]; @@ -3963,7 +4167,7 @@ export function DifferenceTemporalInstant(operation, instant, other, options) { const onens = GetSlot(instant, EPOCHNANOSECONDS); const twons = GetSlot(other, EPOCHNANOSECONDS); - const norm = DifferenceInstant( + const { norm } = DifferenceInstant( onens, twons, settings.roundingIncrement, @@ -4073,68 +4277,33 @@ export function DifferenceTemporalPlainDateTime(operation, plainDateTime, other, return new Duration(); } + const plainDate1 = TemporalDateTimeToDate(plainDateTime); const calendarRec = new CalendarMethodRecord(calendar, ['dateAdd', 'dateUntil']); - - let { years, months, weeks, days, norm } = DifferenceISODateTime( - GetSlot(plainDateTime, ISO_YEAR), - GetSlot(plainDateTime, ISO_MONTH), - GetSlot(plainDateTime, ISO_DAY), - GetSlot(plainDateTime, ISO_HOUR), - GetSlot(plainDateTime, ISO_MINUTE), - GetSlot(plainDateTime, ISO_SECOND), - GetSlot(plainDateTime, ISO_MILLISECOND), - GetSlot(plainDateTime, ISO_MICROSECOND), - GetSlot(plainDateTime, ISO_NANOSECOND), - GetSlot(other, ISO_YEAR), - GetSlot(other, ISO_MONTH), - GetSlot(other, ISO_DAY), - GetSlot(other, ISO_HOUR), - GetSlot(other, ISO_MINUTE), - GetSlot(other, ISO_SECOND), - GetSlot(other, ISO_MILLISECOND), - GetSlot(other, ISO_MICROSECOND), - GetSlot(other, ISO_NANOSECOND), - calendarRec, - settings.largestUnit, - resolvedOptions - ); - - let hours, minutes, seconds, milliseconds, microseconds, nanoseconds; - const roundingIsNoop = settings.smallestUnit === 'nanosecond' && settings.roundingIncrement === 1; - if (!roundingIsNoop) { - const relativeTo = TemporalDateTimeToDate(plainDateTime); - ({ years, months, weeks, days, norm } = RoundDuration( - years, - months, - weeks, - days, - norm, + const { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = + DifferencePlainDateTimeWithRounding( + plainDate1, + GetSlot(plainDateTime, ISO_HOUR), + GetSlot(plainDateTime, ISO_MINUTE), + GetSlot(plainDateTime, ISO_SECOND), + GetSlot(plainDateTime, ISO_MILLISECOND), + GetSlot(plainDateTime, ISO_MICROSECOND), + GetSlot(plainDateTime, ISO_NANOSECOND), + GetSlot(other, ISO_YEAR), + GetSlot(other, ISO_MONTH), + GetSlot(other, ISO_DAY), + GetSlot(other, ISO_HOUR), + GetSlot(other, ISO_MINUTE), + GetSlot(other, ISO_SECOND), + GetSlot(other, ISO_MILLISECOND), + GetSlot(other, ISO_MICROSECOND), + GetSlot(other, ISO_NANOSECOND), + calendarRec, + settings.largestUnit, settings.roundingIncrement, settings.smallestUnit, settings.roundingMode, - relativeTo, - calendarRec - )); - ({ days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration( - norm.add24HourDays(days), - settings.largestUnit - )); - ({ years, months, weeks, days } = BalanceDateDurationRelative( - years, - months, - weeks, - days, - settings.largestUnit, - settings.smallestUnit, - relativeTo, - calendarRec - )); - } else { - ({ days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration( - norm.add24HourDays(days), - settings.largestUnit - )); - } + resolvedOptions + ); return new Duration( sign * years, @@ -4290,7 +4459,13 @@ export function DifferenceTemporalZonedDateTime(operation, zonedDateTime, other, months = 0; weeks = 0; days = 0; - const norm = DifferenceInstant(ns1, ns2, settings.roundingIncrement, settings.smallestUnit, settings.roundingMode); + const { norm } = DifferenceInstant( + ns1, + ns2, + settings.roundingIncrement, + settings.smallestUnit, + settings.roundingMode + ); ({ hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration( norm, settings.largestUnit @@ -4319,66 +4494,21 @@ export function DifferenceTemporalZonedDateTime(operation, zonedDateTime, other, ); const plainRelativeTo = TemporalDateTimeToDate(precalculatedPlainDateTime); - resolvedOptions.largestUnit = settings.largestUnit; - let norm; - ({ years, months, weeks, days, norm } = DifferenceZonedDateTime( - ns1, - ns2, - timeZoneRec, - calendarRec, - settings.largestUnit, - resolvedOptions, - precalculatedPlainDateTime - )); - - const roundingIsNoop = settings.smallestUnit === 'nanosecond' && settings.roundingIncrement === 1; - if (!roundingIsNoop) { - ({ years, months, weeks, days, norm } = RoundDuration( - years, - months, - weeks, - days, - norm, - settings.roundingIncrement, - settings.smallestUnit, - settings.roundingMode, + ({ years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = + DifferenceZonedDateTimeWithRounding( + ns1, + ns2, plainRelativeTo, calendarRec, zonedDateTime, timeZoneRec, - precalculatedPlainDateTime - )); - let deltaDays; - ({ days: deltaDays, norm } = NormalizedTimeDurationToDays(norm, zonedDateTime, timeZoneRec)); - days += deltaDays; - ({ years, months, weeks, days, norm } = AdjustRoundedDurationDays( - years, - months, - weeks, - days, - norm, - settings.roundingIncrement, - settings.smallestUnit, - settings.roundingMode, - zonedDateTime, - calendarRec, - timeZoneRec, - precalculatedPlainDateTime - )); - // BalanceTimeDuration already performed in AdjustRoundedDurationDays - ({ years, months, weeks, days } = BalanceDateDurationRelative( - years, - months, - weeks, - days, + precalculatedPlainDateTime, + resolvedOptions, settings.largestUnit, + settings.roundingIncrement, settings.smallestUnit, - plainRelativeTo, - calendarRec + settings.roundingMode )); - CombineDateAndNormalizedTimeDuration(years, months, weeks, days, norm); - } - ({ hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = BalanceTimeDuration(norm, 'hour')); } return new Duration( diff --git a/spec/duration.html b/spec/duration.html index ea593b18e9..d1cb3c691c 100644 --- a/spec/duration.html +++ b/spec/duration.html @@ -468,19 +468,25 @@

Temporal.Duration.prototype.round ( _roundTo_ )

1. Set _precalculatedPlainDateTime_ to ? GetPlainDateTimeFor(_timeZoneRec_, _instant_, _zonedRelativeTo_.[[Calendar]]). 1. Set _plainRelativeTo_ to ! CreateTemporalDate(_precalculatedPlainDateTime_.[[ISOYear]], _precalculatedPlainDateTime_.[[ISOMonth]], _precalculatedPlainDateTime_.[[ISODay]], _zonedRelativeTo_.[[Calendar]]). 1. Let _calendarRec_ be ? CreateCalendarMethodsRecordFromRelativeTo(_plainRelativeTo_, _zonedRelativeTo_, « ~date-add~, ~date-until~ »). - 1. Let _unbalanceResult_ be ? UnbalanceDateDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _largestUnit_, _plainRelativeTo_, _calendarRec_). 1. Let _norm_ be NormalizeTimeDuration(_duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]). - 1. Let _roundRecord_ be ? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _unbalanceResult_.[[Days]], _norm_, _roundingIncrement_, _smallestUnit_, _roundingMode_, _plainRelativeTo_, _calendarRec_, _zonedRelativeTo_, _timeZoneRec_, _precalculatedPlainDateTime_). - 1. Let _roundResult_ be _roundRecord_.[[NormalizedDuration]]. + 1. Let _emptyOptions_ be OrdinaryObjectCreate(*null*). 1. If _zonedRelativeTo_ is not *undefined*, then - 1. Set _roundResult_ to ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _roundResult_.[[Days]], _roundResult_.[[NormalizedTime]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _zonedRelativeTo_, _calendarRec_, _timeZoneRec_, _precalculatedPlainDateTime_). - 1. Let _intermediate_ be ? MoveRelativeZonedDateTime(_zonedRelativeTo_, _calendarRec_, _timeZoneRec_, _roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], 0, _precalculatedPlainDateTime_). - 1. Let _balanceResult_ be ? BalanceTimeDurationRelative(_roundResult_.[[Days]], _roundResult_.[[NormalizedTime]], _largestUnit_, _intermediate_, _timeZoneRec_, _precalculatedPlainDateTime_). + 1. Let _relativeEpochNs_ be _zonedRelativeTo_.[[Nanoseconds]]. + 1. Let _relativeInstant_ be ! CreateTemporalInstant(_relativeEpochNs_). + 1. Let _targetEpochNs_ be ? AddZonedDateTime(_relativeInstant_, _timeZoneRec_, _calendarRec_, _duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _norm_, _precalculatedPlainDateTime_). + 1. Let _roundRecord_ be ? DifferenceZonedDateTimeWithRounding(_relativeEpochNs_, _targetEpochNs_, _plainRelativeTo_, _calendarRec_, _zonedRelativeTo_, _timeZoneRec_, _precalculatedPlainDateTime_, _emptyOptions_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_). + 1. Else if _plainRelativeTo_ is not *undefined*, then + 1. Let _targetTime_ be AddTime(0, 0, 0, 0, 0, 0, _norm_). + 1. Let _dateDuration_ be ? CreateTemporalDuration(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]] + _targetTime_.[[Days]], 0, 0, 0, 0, 0, 0). + 1. Let _targetDate_ be ? AddDate(_calendarRec_, _plainRelativeTo_, _dateDuration_). + 1. Let _roundRecord_ be ? DifferencePlainDateTimeWithRounding(_plainRelativeTo_, 0, 0, 0, 0, 0, 0, _targetDate_.[[ISOYear]], _targetDate_.[[ISOMonth]], _targetDate_.[[ISODay]], _targetTime_.[[Hours]], _targetTime_.[[Minutes]], _targetTime_.[[Seconds]], _targetTime_.[[Milliseconds]], _targetTime_.[[Microseconds]], _targetTime_.[[Nanoseconds]], _calendarRec_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_, _emptyOptions_). 1. Else, - 1. Let _normWithDays_ be ? Add24HourDaysToNormalizedTimeDuration(_roundResult_.[[NormalizedTime]], _roundResult_.[[Days]]). - 1. Let _balanceResult_ be BalanceTimeDuration(_normWithDays_, _largestUnit_). - 1. Let _result_ be ? BalanceDateDurationRelative(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _balanceResult_.[[Days]], _largestUnit_, _smallestUnit_, _plainRelativeTo_, _calendarRec_). - 1. Return ! CreateTemporalDuration(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], _balanceResult_.[[Hours]], _balanceResult_.[[Minutes]], _balanceResult_.[[Seconds]], _balanceResult_.[[Milliseconds]], _balanceResult_.[[Microseconds]], _balanceResult_.[[Nanoseconds]]). + 1. If _calendarUnitsPresent_ is *true*, or IsCalendarUnit(_largestUnit_) is *true*, or IsCalendarUnit(_smallestUnit_) is *true*, throw a *RangeError* exception. + 1. Let _isoCalendarRec_ be ! CreateCalendarMethodsRecord(*"iso8601"*, « ~date-add~, ~date-until~ »). + 1. Let _target_ be ? AddDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, _isoCalendarRec_, _duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _norm_, *undefined*). + 1. Let _roundRecord_ be ? DifferencePlainDateTimeWithRounding(~empty~, 0, 0, 0, 0, 0, 0, _target_.[[ISOYear]], _target_.[[ISOMonth]], _target_.[[ISODay]], _target_.[[ISOHour]], _target_.[[ISOMinute]], _target_.[[ISOSecond]], _target_.[[ISOMillisecond]], _target_.[[ISOMicrosecond]], _target_.[[ISONanosecond]], _isoCalendarRec_, _largestUnit_, _roundingIncrement_, _smallestUnit_, _roundingMode_, _emptyOptions_). + 1. Let _roundResult_ be _roundRecord_.[[DurationRecord]]. + 1. Return ! CreateTemporalDuration(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _roundResult_.[[Days]], _roundResult_.[[Hours]], _roundResult_.[[Minutes]], _roundResult_.[[Seconds]], _roundResult_.[[Milliseconds]], _roundResult_.[[Microseconds]], _roundResult_.[[Nanoseconds]]). @@ -513,34 +519,23 @@

Temporal.Duration.prototype.total ( _totalOf_ )

1. Set _precalculatedPlainDateTime_ to ? GetPlainDateTimeFor(_timeZoneRec_, _instant_, _zonedRelativeTo_.[[Calendar]]). 1. Set _plainRelativeTo_ to ! CreateTemporalDate(_precalculatedPlainDateTime_.[[ISOYear]], _precalculatedPlainDateTime_.[[ISOMonth]], _precalculatedPlainDateTime_.[[ISODay]], _zonedRelativeTo_.[[Calendar]]). 1. Let _calendarRec_ be ? CreateCalendarMethodsRecordFromRelativeTo(_plainRelativeTo_, _zonedRelativeTo_, « ~date-add~, ~date-until~ »). - 1. Let _unbalanceResult_ be ? UnbalanceDateDurationRelative(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _unit_, _plainRelativeTo_, _calendarRec_). - 1. Let _days_ be _unbalanceResult_.[[Days]]. + 1. Let _norm_ be NormalizeTimeDuration(_duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]). + 1. Let _emptyOptions_ be OrdinaryObjectCreate(*null*). 1. If _zonedRelativeTo_ is not *undefined*, then - 1. Let _intermediate_ be ? MoveRelativeZonedDateTime(_zonedRelativeTo_, _calendarRec_, _timeZoneRec_, _unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], 0, _precalculatedPlainDateTime_). - 1. Let _norm_ be NormalizeTimeDuration(_duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]). - 1. Let _startNs_ be _intermediate_.[[Nanoseconds]]. - 1. Let _startInstant_ be ! CreateTemporalInstant(_startNs_). - 1. Let _startDateTime_ be *undefined*. - 1. If _days_ ≠ 0, then - 1. Set _startDateTime_ to ? GetPlainDateTimeFor(_timeZoneRec_, _startInstant_, *"iso8601"*). - 1. Let _addResult_ be ? AddDaysToZonedDateTime(_startInstant_, _startDateTime_, _timeZoneRec_, *"iso8601"*, _days_). - 1. Let _intermediateNs_ be _addResult_.[[EpochNanoseconds]]. - 1. Else, - 1. Let _intermediateNs_ be _startNs_. - 1. Let _endNs_ be ? AddInstant(_intermediateNs_, _norm_). - 1. Set _norm_ to NormalizedTimeDurationFromEpochNanosecondsDifference(_endNs_, _startNs_). - 1. If IsCalendarUnit(_unit_) is *true* or _unit_ is *"day"*, then - 1. If NormalizedTimeDurationIsZero(_norm_) is *false* and _startDateTime_ is *undefined*, set _startDateTime_ to ? GetPlainDateTimeFor(_timeZoneRec_, _startInstant_, *"iso8601"*). - 1. Let _result_ be ? NormalizedTimeDurationToDays(_norm_, _intermediate_, _timeZoneRec_, _startDateTime_). - 1. Set _norm_ to _result_.[[Remainder]]. - 1. Set _days_ to _result_.[[Days]]. - 1. Else, - 1. Set _days_ to 0. + 1. Let _relativeEpochNs_ be _zonedRelativeTo_.[[Nanoseconds]]. + 1. Let _relativeInstant_ be ! CreateTemporalInstant(_relativeEpochNs_). + 1. Let _targetEpochNs_ be ? AddZonedDateTime(_relativeInstant_, _timeZoneRec_, _calendarRec_, _duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _norm_, _precalculatedPlainDateTime_). + 1. Let _roundRecord_ be ? DifferenceZonedDateTimeWithRounding(_relativeEpochNs_, _targetEpochNs_, _plainRelativeTo_, _calendarRec_, _zonedRelativeTo_, _timeZoneRec_, _precalculatedPlainDateTime_, _emptyOptions_, _unit_, 1, _unit_, *"trunc"*). + 1. Else if _plainRelativeTo_ is not *undefined*, then + 1. Let _targetTime_ be AddTime(0, 0, 0, 0, 0, 0, _norm_). + 1. Let _dateDuration_ be ? CreateTemporalDuration(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]] + _targetTime_.[[Days]], 0, 0, 0, 0, 0, 0). + 1. Let _targetDate_ be ? AddDate(_calendarRec_, _plainRelativeTo_, _dateDuration_). + 1. Let _roundRecord_ be ? DifferencePlainDateTimeWithRounding(_plainRelativeTo_, 0, 0, 0, 0, 0, 0, _targetDate_.[[ISOYear]], _targetDate_.[[ISOMonth]], _targetDate_.[[ISODay]], _targetTime_.[[Hours]], _targetTime_.[[Minutes]], _targetTime_.[[Seconds]], _targetTime_.[[Milliseconds]], _targetTime_.[[Microseconds]], _targetTime_.[[Nanoseconds]], _calendarRec_, _unit_, 1, _unit_, *"trunc"*, _emptyOptions_). 1. Else, - 1. Let _norm_ be NormalizeTimeDuration(_duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]). - 1. Set _norm_ to ? Add24HourDaysToNormalizedTimeDuration(_norm_, _days_). - 1. Set _days_ to 0. - 1. Let _roundRecord_ be ? RoundDuration(_unbalanceResult_.[[Years]], _unbalanceResult_.[[Months]], _unbalanceResult_.[[Weeks]], _days_, _norm_, 1, _unit_, *"trunc"*, _plainRelativeTo_, _calendarRec_, _zonedRelativeTo_, _timeZoneRec_, _precalculatedPlainDateTime_). + 1. If _duration_.[[Years]] ≠ 0, or _duration_.[[Months]] ≠ 0, or _duration_.[[Weeks]] ≠ 0, or IsCalendarUnit(_unit_) is *true*, throw a *RangeError* exception. + 1. Let _isoCalendarRec_ be ! CreateCalendarMethodsRecord(*"iso8601"*, « ~date-add~, ~date-until~ »). + 1. Let _target_ be ? AddDateTime(1970, 1, 1, 0, 0, 0, 0, 0, 0, _isoCalendarRec_, _duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _norm_, *undefined*). + 1. Let _roundRecord_ be ? DifferencePlainDateTimeWithRounding(~empty~, 0, 0, 0, 0, 0, 0, _target_.[[ISOYear]], _target_.[[ISOMonth]], _target_.[[ISODay]], _target_.[[ISOHour]], _target_.[[ISOMinute]], _target_.[[ISOSecond]], _target_.[[ISOMillisecond]], _target_.[[ISOMicrosecond]], _target_.[[ISONanosecond]], _isoCalendarRec_, _unit_, 1, _unit_, *"trunc"*, _emptyOptions_). 1. Return 𝔽(_roundRecord_.[[Total]]). diff --git a/spec/instant.html b/spec/instant.html index dedc1e280b..d546fc1553 100644 --- a/spec/instant.html +++ b/spec/instant.html @@ -574,7 +574,7 @@

_roundingIncrement_: a positive integer, _smallestUnit_: a String, _roundingMode_: a String from the Identifier column of , - ): a Normalized Time Duration Record + ): a Record with fields [[NormalizedTimeDuration]] (a Normalized Time Duration Record) and [[Total]] (a mathematical value)

description
@@ -582,10 +582,8 @@

1. Let _difference_ be NormalizedTimeDurationFromEpochNanosecondsDifference(_ns2_, _ns1_). - 1. If _smallestUnit_ is *"nanosecond"* and _roundingIncrement_ is 1, then - 1. Return _difference_. 1. Let _roundRecord_ be ! RoundDuration(0, 0, 0, 0, _difference_, _roundingIncrement_, _smallestUnit_, _roundingMode_). - 1. Return _roundRecord_.[[NormalizedDuration]].[[NormalizedTime]]. + 1. Return the Record { [[NormalizedTimeDuration]]: _roundRecord_.[[NormalizedDuration]].[[NormalizedTime]], [[Total]]: _roundRecord_.[[Total]] }. @@ -656,7 +654,8 @@

1. Set _other_ to ? ToTemporalInstant(_other_). 1. Let _resolvedOptions_ be ? SnapshotOwnProperties(? GetOptionsObject(_options_), *null*). 1. Let _settings_ be ? GetDifferenceSettings(_operation_, _resolvedOptions_, ~time~, « », *"nanosecond"*, *"second"*). - 1. Let _norm_ be DifferenceInstant(_instant_.[[Nanoseconds]], _other_.[[Nanoseconds]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). + 1. Let _diffRecord_ be DifferenceInstant(_instant_.[[Nanoseconds]], _other_.[[Nanoseconds]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). + 1. Let _norm_ be _diffRecord_.[[NormalizedTimeDuration]]. 1. Let _result_ be BalanceTimeDuration(_norm_, _settings_.[[LargestUnit]]). 1. Return ! CreateTemporalDuration(0, 0, 0, 0, _sign_ × _result_.[[Hours]], _sign_ × _result_.[[Minutes]], _sign_ × _result_.[[Seconds]], _sign_ × _result_.[[Milliseconds]], _sign_ × _result_.[[Microseconds]], _sign_ × _result_.[[Nanoseconds]]). diff --git a/spec/plaindatetime.html b/spec/plaindatetime.html index 1e28c59490..c11cff48f0 100644 --- a/spec/plaindatetime.html +++ b/spec/plaindatetime.html @@ -1274,6 +1274,66 @@

1. Return ? CreateNormalizedDurationRecord(_dateDifference_.[[Years]], _dateDifference_.[[Months]], _dateDifference_.[[Weeks]], _dateDifference_.[[Days]], _timeDuration_). + + +

+ DifferencePlainDateTimeWithRounding ( + _plainDate1_: a Temporal.PlainDate or ~empty~, + _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 in the inclusive interval from 1 to 12, + _d2_: an integer in the inclusive interval from 1 to ISODaysInMonth(_mon2_), + _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, + _calendarRec_: a Calendar Methods Record, + _largestUnit_: a String etc, + _roundingIncrement_: an integer, + _smallestUnit_: a String, + _roundingMode_: a String, + _resolvedOptions_: an Object with [[Prototype]] slot *null*, + ): either a normal completion containing a Record with fields [[DurationRecord]] (a Duration Record) and [[Total]] (a mathematical value or ~empty~), or a throw completion +

+
+
description
+
+
+ + 1. If _plainDate1_ is ~empty~, then + 1. Let _y1_ be 1970. + 1. Let _mon1_ be 1. + 1. Let _d1_ be 1. + 1. Else, + 1. Let _y1_ be _plainDate1_.[[ISOYear]]. + 1. Let _mon1_ be _plainDate1_.[[ISOMonth]]. + 1. Let _d1_ be _plainDate1_.[[ISODay]]. + 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 _durationRecord_ be CreateDurationRecord(0, 0, 0, 0, 0, 0, 0, 0, 0, 0). + 1. Return the Record { [[DurationRecord]]: _durationRecord_, [[Total]]: 0 }. + 1. Let _diff_ be ? DifferenceISODateTime(_y1_, _mon1_, _d1_, _h1_, _min1_, _s1_, _ms1_, _mus1_, _ns1_, _y2_, _mon2_, _d2_, _h2_, _min2_, _s2_, _ms2_, _mus2_, _ns2_, _calendarRec_, _largestUnit_, _resolvedOptions_). + 1. If _smallestUnit_ is *"nanosecond"* and _roundingIncrement_ = 1, then + 1. Let _normWithDays_ be ? Add24HourDaysToNormalizedTimeDuration(_diff_.[[NormalizedTime]], _diff_.[[Days]]). + 1. Let _timeResult_ be BalanceTimeDuration(_normWithDays_, _largestUnit_). + 1. Let _durationRecord_ be CreateDurationRecord(_diff_.[[Years]], _diff_.[[Months]], _diff_.[[Weeks]], _timeResult_.[[Days]], _timeResult_.[[Hours]], _timeResult_.[[Minutes]], _timeResult_.[[Seconds]], _timeResult_.[[Milliseconds]], _timeResult_.[[Microseconds]], _timeResult_.[[Nanoseconds]]). + 1. Return the Record { [[DurationRecord]]: _durationRecord_, [[Total]]: ~empty~ }. + 1. Let _roundRecord_ be ? RoundDuration(_diff_.[[Years]], _diff_.[[Months]], _diff_.[[Weeks]], _diff_.[[Days]], _diff_.[[NormalizedTime]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _plainDate1_, _calendarRec_). + 1. Let _roundResult_ be _roundRecord_.[[NormalizedDuration]]. + 1. Let _normWithDays_ be ? Add24HourDaysToNormalizedTimeDuration(_roundResult_.[[NormalizedTime]], _roundResult_.[[Days]]). + 1. Let _timeResult_ be BalanceTimeDuration(_normWithDays_, _largestUnit_). + 1. Let _balanceResult_ be ? BalanceDateDurationRelative(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _timeResult_.[[Days]], _largestUnit_, _smallestUnit_, _plainDate1_, _calendarRec_). + 1. Let _durationRecord_ be CreateDurationRecord(_balanceResult_.[[Years]], _balanceResult_.[[Months]], _balanceResult_.[[Weeks]], _balanceResult_.[[Days]], _timeResult_.[[Hours]], _timeResult_.[[Minutes]], _timeResult_.[[Seconds]], _timeResult_.[[Milliseconds]], _timeResult_.[[Microseconds]], _timeResult_.[[Nanoseconds]]). + 1. Return the Record { [[DurationRecord]]: _durationRecord_, [[Total]]: _roundRecord_.[[Total]] }. + +
+

DifferenceTemporalPlainDateTime ( @@ -1298,21 +1358,11 @@

1. Set _datePartsIdentical_ to *true*. 1. If _datePartsIdentical_ is *true*, 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 _calendarRec_ be ? CreateCalendarMethodsRecord(_dateTime_.[[Calendar]], « ~date-add~, ~date-until~ »). - 1. Let _result_ be ? DifferenceISODateTime(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[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]], _calendarRec_, _settings_.[[LargestUnit]], _resolvedOptions_). - 1. If _settings_.[[SmallestUnit]] is *"nanosecond"* and _settings_.[[RoundingIncrement]] = 1, let _roundingGranularityIsNoop_ be *true*; else let _roundingGranularityIsNoop_ be *false*. - 1. If _roundingGranularityIsNoop_ is *false*, then - 1. Let _relativeTo_ be ! CreateTemporalDate(_dateTime_.[[ISOYear]], _dateTime_.[[ISOMonth]], _dateTime_.[[ISODay]], _dateTime_.[[Calendar]]). - 1. Let _roundRecord_ be ? RoundDuration(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], _result_.[[NormalizedTime]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]], _relativeTo_, _calendarRec_). - 1. Let _roundResult_ be _roundRecord_.[[NormalizedDuration]]. - 1. Let _normWithDays_ be ? Add24HourDaysToNormalizedTimeDuration(_roundResult_.[[NormalizedTime]], _roundResult_.[[Days]]). - 1. Let _timeResult_ be BalanceTimeDuration(_normWithDays_, _settings_.[[LargestUnit]]). - 1. Let _balanceResult_ be ? BalanceDateDurationRelative(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _timeResult_.[[Days]], _settings_.[[LargestUnit]], _settings_.[[SmallestUnit]], _relativeTo_, _calendarRec_). - 1. Else, - 1. Let _normWithDays_ be ? Add24HourDaysToNormalizedTimeDuration(_result_.[[NormalizedTime]], _result_.[[Days]]). - 1. Let _timeResult_ be BalanceTimeDuration(_normWithDays_, _settings_.[[LargestUnit]]). - 1. Let _balanceResult_ be ! CreateDateDurationRecord(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _timeResult_.[[Days]]). - 1. Return ! CreateTemporalDuration(_sign_ × _balanceResult_.[[Years]], _sign_ × _balanceResult_.[[Months]], _sign_ × _balanceResult_.[[Weeks]], _sign_ × _balanceResult_.[[Days]], _sign_ × _timeResult_.[[Hours]], _sign_ × _timeResult_.[[Minutes]], _sign_ × _timeResult_.[[Seconds]], _sign_ × _timeResult_.[[Milliseconds]], _sign_ × _timeResult_.[[Microseconds]], _sign_ × _timeResult_.[[Nanoseconds]]). + 1. Let _resultRecord_ be ? DifferencePlainDateTimeWithRounding(_plainDate_, _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]], _calendarRec_, _settings_.[[LargestUnit]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]], _resolvedOptions_). + 1. Let _result_ be _resultRecord_.[[DurationRecord]]. + 1. Return ! CreateTemporalDuration(_sign_ × _result_.[[Years]], _sign_ × _result_.[[Months]], _sign_ × _result_.[[Weeks]], _sign_ × _result_.[[Days]], _sign_ × _result_.[[Hours]], _sign_ × _result_.[[Minutes]], _sign_ × _result_.[[Seconds]], _sign_ × _result_.[[Milliseconds]], _sign_ × _result_.[[Microseconds]], _sign_ × _result_.[[Nanoseconds]]). diff --git a/spec/zoneddatetime.html b/spec/zoneddatetime.html index ba333b1703..9735e19f46 100644 --- a/spec/zoneddatetime.html +++ b/spec/zoneddatetime.html @@ -1477,6 +1477,53 @@

}. + + +

+ DifferenceZonedDateTimeWithRounding ( + _ns1_: a BigInt, + _ns2_: a BigInt, + _plainRelativeTo_: a Temporal.PlainDate, + _calendarRec_: a Calendar Methods Record, + _zonedDateTime_: a Temporal.ZonedDateTime, + _timeZoneRec_: a Time Zone Methods Record, + _precalculatedPlainDateTime_: a Temporal.PlainDateTime, + _resolvedOptions_: an Object with [[Prototype]] slot *null*, + _largestUnit_: a String, + _roundingIncrement_: an integer, + _smallestUnit_: a String, + _roundingMode_: a String, + ): either a normal completion containing a Record with fields [[DurationRecord]] (a Duration Record) and [[Total]] (a mathematical value or ~empty~), or a throw completion +

+
+
description
+
+
+ + 1. If IsCalendarUnit(_largestUnit_) is *false* and _largestUnit_ is not *"day"*, then + 1. Let _diffRecord_ be DifferenceInstant(_ns1_, _ns2_, _roundingIncrement_, _smallestUnit_, _roundingMode_). + 1. Let _norm_ be _diffRecord_.[[NormalizedTimeDuration]]. + 1. Let _result_ be BalanceTimeDuration(_norm_, _largestUnit_). + 1. Let _durationRecord_ be CreateDurationRecord(0, 0, 0, 0, _result_.[[Hours]], _result_.[[Minutes]], _result_.[[Seconds]], _result_.[[Milliseconds]], _result_.[[Microseconds]], _result_.[[Nanoseconds]]). + 1. Return the Record { [[DurationRecord]]: _durationRecord_, [[Total]]: _diffRecord_.[[Total]] }. + 1. Perform ! CreateDataPropertyOrThrow(_resolvedOptions_, *"largestUnit"*, _largestUnit_). + 1. Let _difference_ be ? DifferenceZonedDateTime(_ns1_, _ns2_, _timeZoneRec_, _calendarRec_, _largestUnit_, _resolvedOptions_, _precalculatedPlainDateTime_). + 1. If _smallestUnit_ is *"nanosecond"* and _roundingIncrement_ is 1, let _roundingGranularityIsNoop_ be *true*; else let _roundingGranularityIsNoop_ be *false*. + 1. If _roundingGranularityIsNoop_ is *true*, then + 1. Let _timeResult_ be BalanceTimeDuration(_difference_.[[NormalizedTime]], *"hour"*). + 1. Let _durationRecord_ be CreateDurationRecord(_difference_.[[Years]], _difference_.[[Months]], _difference_.[[Weeks]], _difference_.[[Days]], _timeResult_.[[Hours]], _timeResult_.[[Minutes]], _timeResult_.[[Seconds]], _timeResult_.[[Milliseconds]], _timeResult_.[[Microseconds]], _timeResult_.[[Nanoseconds]]). + 1. Return the Record { [[DurationRecord]]: _durationRecord_, [[Total]]: ~empty~ }. + 1. Let _roundRecord_ be ? RoundDuration(_difference_.[[Years]], _difference_.[[Months]], _difference_.[[Weeks]], _difference_.[[Days]], _difference_.[[NormalizedTime]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _plainRelativeTo_, _calendarRec_, _zonedDateTime_, _timeZoneRec_, _precalculatedPlainDateTime_). + 1. Let _roundResult_ be _roundRecord_.[[NormalizedDuration]]. + 1. Let _adjustResult_ be ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _roundResult_.[[Days]], _roundResult_.[[NormalizedTime]], _roundingIncrement_, _smallestUnit_, _roundingMode_, _zonedDateTime_, _calendarRec_, _timeZoneRec_, _precalculatedPlainDateTime_). + 1. Let _balanceResult_ be ? BalanceDateDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]], _adjustResult_.[[Weeks]], _adjustResult_.[[Days]], _largestUnit_, _smallestUnit_, _plainRelativeTo_, _calendarRec_). + 1. Set _result_ to ? CombineDateAndNormalizedTimeDuration(_balanceResult_, _adjustResult_.[[NormalizedTime]]). + 1. Let _timeResult_ be BalanceTimeDuration(_result_.[[NormalizedTime]], *"hour"*). + 1. Let _durationRecord_ be CreateDurationRecord(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], _timeResult_.[[Hours]], _timeResult_.[[Minutes]], _timeResult_.[[Seconds]], _timeResult_.[[Milliseconds]], _timeResult_.[[Microseconds]], _timeResult_.[[Nanoseconds]]). + 1. Return the Record { [[DurationRecord]]: _durationRecord_, [[Total]]: _roundRecord_.[[Total]] }. + +
+

DifferenceTemporalZonedDateTime ( @@ -1498,7 +1545,8 @@

1. Let _resolvedOptions_ be ? SnapshotOwnProperties(? GetOptionsObject(_options_), *null*). 1. Let _settings_ be ? GetDifferenceSettings(_operation_, _resolvedOptions_, ~datetime~, « », *"nanosecond"*, *"hour"*). 1. If _settings_.[[LargestUnit]] is not one of *"year"*, *"month"*, *"week"*, or *"day"*, then - 1. Let _norm_ be DifferenceInstant(_zonedDateTime_.[[Nanoseconds]], _other_.[[Nanoseconds]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). + 1. Let _diffRecord_ be DifferenceInstant(_zonedDateTime_.[[Nanoseconds]], _other_.[[Nanoseconds]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). + 1. Let _norm_ be _diffRecord_.[[NormalizedTimeDuration]]. 1. Let _result_ be BalanceTimeDuration(_norm_, _settings_.[[LargestUnit]]). 1. Return ! CreateTemporalDuration(0, 0, 0, 0, _sign_ × _result_.[[Hours]], _sign_ × _result_.[[Minutes]], _sign_ × _result_.[[Seconds]], _sign_ × _result_.[[Milliseconds]], _sign_ × _result_.[[Microseconds]], _sign_ × _result_.[[Nanoseconds]]). 1. If ? TimeZoneEquals(_zonedDateTime_.[[TimeZone]], _other_.[[TimeZone]]) is *false*, then @@ -1510,19 +1558,9 @@

1. Let _instant_ be ! CreateTemporalInstant(_zonedDateTime_.[[Nanoseconds]]). 1. Let _precalculatedPlainDateTime_ be ? GetPlainDateTimeFor(_timeZoneRec_, _instant_, _calendarRec_.[[Receiver]]). 1. Let _plainRelativeTo_ be ! CreateTemporalDate(_precalculatedPlainDateTime_.[[ISOYear]], _precalculatedPlainDateTime_.[[ISOMonth]], _precalculatedPlainDateTime_.[[ISODay]], _calendarRec_.[[Receiver]]). - 1. Perform ! CreateDataPropertyOrThrow(_resolvedOptions_, *"largestUnit"*, _settings_.[[LargestUnit]]). - 1. Let _result_ be ? DifferenceZonedDateTime(_zonedDateTime_.[[Nanoseconds]], _other_.[[Nanoseconds]], _timeZoneRec_, _calendarRec_, _settings_.[[LargestUnit]], _resolvedOptions_, _precalculatedPlainDateTime_). - 1. If _settings_.[[SmallestUnit]] is *"nanosecond"* and _settings_.[[RoundingIncrement]] is 1, let _roundingGranularityIsNoop_ be *true*; else let _roundingGranularityIsNoop_ be *false*. - 1. If _roundingGranularityIsNoop_ is *false*, then - 1. Let _roundRecord_ be ? RoundDuration(_result_.[[Years]], _result_.[[Months]], _result_.[[Weeks]], _result_.[[Days]], _result_.[[NormalizedTime]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]], _plainRelativeTo_, _calendarRec_, _zonedDateTime_, _timeZoneRec_, _precalculatedPlainDateTime_). - 1. Let _roundResult_ be _roundRecord_.[[NormalizedDuration]]. - 1. Let _daysResult_ be ! NormalizedTimeDurationToDays(_roundResult_.[[NormalizedTime]], _zonedDateTime_, _timeZoneRec_). - 1. Let _days_ be _roundResult_.[[Days]] + _daysResult_.[[Days]]. - 1. Let _adjustResult_ be ? AdjustRoundedDurationDays(_roundResult_.[[Years]], _roundResult_.[[Months]], _roundResult_.[[Weeks]], _days_, _daysResult_.[[NormalizedTime]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]], _zonedDateTime_, _calendarRec_, _timeZoneRec_, _precalculatedPlainDateTime_). - 1. Let _balanceResult_ be ? BalanceDateDurationRelative(_adjustResult_.[[Years]], _adjustResult_.[[Months]], _adjustResult_.[[Weeks]], _adjustResult_.[[Days]], _settings_.[[LargestUnit]], _settings_.[[SmallestUnit]], _plainRelativeTo_, _calendarRec_). - 1. Set _result_ to ? CombineDateAndNormalizedTimeDuration(_balanceResult_, _adjustResult_.[[NormalizedTime]]). - 1. Let _timeResult_ be BalanceTimeDuration(_result_.[[NormalizedTime]], *"hour"*). - 1. Return ! CreateTemporalDuration(_sign_ × _result_.[[Years]], _sign_ × _result_.[[Months]], _sign_ × _result_.[[Weeks]], _sign_ × _result_.[[Days]], _sign_ × _timeResult_.[[Hours]], _sign_ × _timeResult_.[[Minutes]], _sign_ × _timeResult_.[[Seconds]], _sign_ × _timeResult_.[[Milliseconds]], _sign_ × _timeResult_.[[Microseconds]], _sign_ × _timeResult_.[[Nanoseconds]]). + 1. Let _resultRecord_ be ? DifferenceZonedDateTimeWithRounding(_zonedDateTime_.[[Nanoseconds]], _other_.[[Nanoseconds]], _plainRelativeTo_, _calendarRec_, _zonedDateTime_, _timeZoneRec_, _precalculatedPlainDateTime_, _resolvedOptions_, _settings_.[[LargestUnit]], _settings_.[[RoundingIncrement]], _settings_.[[SmallestUnit]], _settings_.[[RoundingMode]]). + 1. Let _result_ be _resultRecord_.[[DurationRecord]]. + 1. Return ! CreateTemporalDuration(_sign_ × _result_.[[Years]], _sign_ × _result_.[[Months]], _sign_ × _result_.[[Weeks]], _sign_ × _result_.[[Days]], _sign_ × _result_.[[Hours]], _sign_ × _result_.[[Minutes]], _sign_ × _result_.[[Seconds]], _sign_ × _result_.[[Milliseconds]], _sign_ × _result_.[[Microseconds]], _sign_ × _result_.[[Nanoseconds]]).