diff --git a/polyfill/lib/duration.mjs b/polyfill/lib/duration.mjs
index 1b3a790646..916b52f995 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
@@ -305,11 +308,7 @@ export class Duration {
let precalculatedPlainDateTime;
const plainDateTimeOrRelativeToWillBeUsed =
- !roundingGranularityIsNoop ||
- ES.IsCalendarUnit(largestUnit) ||
- largestUnit === 'day' ||
- calendarUnitsPresent ||
- days !== 0;
+ ES.IsCalendarUnit(largestUnit) || largestUnit === 'day' || calendarUnitsPresent || days !== 0;
if (zonedRelativeTo && plainDateTimeOrRelativeToWillBeUsed) {
// Convert a ZonedDateTime relativeTo to PlainDateTime and PlainDate only
// if either is needed in one of the operations below, because the
@@ -327,79 +326,85 @@ 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 {
+ // No reference date to calculate difference relative to
+ if (calendarUnitsPresent) {
+ throw new RangeError('a starting point is required for years, months, or weeks balancing');
+ }
+ if (ES.IsCalendarUnit(largestUnit)) {
+ throw new RangeError(`a starting point is required for ${largestUnit}s balancing`);
+ }
+ if (ES.IsCalendarUnit(smallestUnit)) {
+ throw new RangeError(`a starting point is required for ${smallestUnit}s rounding`);
+ }
+ ({ days, norm } = ES.RoundDuration(0, 0, 0, days, norm, roundingIncrement, smallestUnit, roundingMode));
({ days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.BalanceTimeDuration(
norm.add24HourDays(days),
largestUnit
));
}
- ({ 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 +451,80 @@ 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);
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;
- }
- 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;
- }
- } else {
- norm = TimeDuration.normalize(hours, minutes, seconds, milliseconds, microseconds, nanoseconds);
- norm = norm.add24HourDays(days);
- days = 0;
+ const { total } = ES.DifferenceZonedDateTimeWithRounding(
+ relativeEpochNs,
+ targetEpochNs,
+ plainRelativeTo,
+ calendarRec,
+ zonedRelativeTo,
+ timeZoneRec,
+ precalculatedPlainDateTime,
+ ObjectCreate(null),
+ unit,
+ 1,
+ unit,
+ 'trunc'
+ );
+ return total;
}
- // 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
- );
+
+ 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);
+
+ const { 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'
+ );
+ return total;
+ }
+
+ // No reference date to calculate difference relative to
+ if (years !== 0 || months !== 0 || weeks !== 0) {
+ throw new RangeError('a starting point is required for years, months, or weeks total');
+ }
+ if (ES.IsCalendarUnit(unit)) {
+ throw new RangeError(`a starting point is required for ${unit}s total`);
+ }
+ norm = norm.add24HourDays(days);
+ const { total } = ES.RoundDuration(0, 0, 0, 0, norm, 1, unit, 'trunc');
return total;
}
toString(options = undefined) {
@@ -707,9 +723,11 @@ export class Duration {
}
if (calendarUnitsPresent) {
- // plainRelativeTo may be undefined, and if so Unbalance will throw
- ({ days: d1 } = ES.UnbalanceDateDurationRelative(y1, mon1, w1, d1, 'day', plainRelativeTo, calendarRec));
- ({ days: d2 } = ES.UnbalanceDateDurationRelative(y2, mon2, w2, d2, 'day', plainRelativeTo, calendarRec));
+ if (!plainRelativeTo) {
+ throw new RangeError('A starting point is required for years, months, or weeks comparison');
+ }
+ d1 = ES.UnbalanceDateDurationRelative(y1, mon1, w1, d1, plainRelativeTo, calendarRec);
+ d2 = ES.UnbalanceDateDurationRelative(y2, mon2, w2, d2, plainRelativeTo, calendarRec);
}
const norm1 = TimeDuration.normalize(h1, min1, s1, ms1, µs1, ns1).add24HourDays(d1);
const norm2 = TimeDuration.normalize(h2, min2, s2, ms2, µs2, ns2).add24HourDays(d2);
diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs
index a7f4b52215..dae66614d2 100644
--- a/polyfill/lib/ecmascript.mjs
+++ b/polyfill/lib/ecmascript.mjs
@@ -3508,43 +3508,15 @@ export function BalanceTimeDurationRelative(
return { days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds };
}
-export function UnbalanceDateDurationRelative(years, months, weeks, days, largestUnit, plainRelativeTo, calendarRec) {
- // calendarRec must have looked up dateAdd and dateUntil
- const TemporalDuration = GetIntrinsic('%Temporal.Duration%');
- const defaultLargestUnit = DefaultTemporalLargestUnit(years, months, weeks, days, 0, 0, 0, 0, 0, 0);
- const effectiveLargestUnit = LargerOfTwoTemporalUnits(largestUnit, 'day');
- if (LargerOfTwoTemporalUnits(defaultLargestUnit, effectiveLargestUnit) === effectiveLargestUnit) {
- // no-op
- return { years, months, weeks, days };
- }
- if (!calendarRec) throw new RangeError(`a starting point is required for ${largestUnit}s balancing`);
+export function UnbalanceDateDurationRelative(years, months, weeks, days, plainRelativeTo, calendarRec) {
+ // calendarRec must have looked up dateAdd, unless calendar units 0
+ if (years === 0 && months === 0 && weeks === 0) return days;
- switch (effectiveLargestUnit) {
- case 'year':
- throw new Error('assert not reached');
- case 'month': {
- // balance years down to months
- const later = CalendarDateAdd(calendarRec, plainRelativeTo, new TemporalDuration(years));
- const untilOptions = ObjectCreate(null);
- untilOptions.largestUnit = 'month';
- const untilResult = CalendarDateUntil(calendarRec, plainRelativeTo, later, untilOptions);
- const yearsInMonths = GetSlot(untilResult, MONTHS);
- return { years: 0, months: months + yearsInMonths, weeks, days };
- }
- case 'week': {
- // balance years and months down to days
- const later = CalendarDateAdd(calendarRec, plainRelativeTo, new TemporalDuration(years, months));
- const yearsMonthsInDays = DaysUntil(plainRelativeTo, later);
- return { years: 0, months: 0, weeks, days: days + yearsMonthsInDays };
- }
- default: {
- // largestUnit is "day", or any time unit
- // balance years, months, and weeks down to days
- const later = CalendarDateAdd(calendarRec, plainRelativeTo, new TemporalDuration(years, months, weeks));
- const yearsMonthsWeeksInDays = DaysUntil(plainRelativeTo, later);
- return { years: 0, months: 0, weeks: 0, days: days + yearsMonthsWeeksInDays };
- }
- }
+ // balance years, months, and weeks down to days
+ const TemporalDuration = GetIntrinsic('%Temporal.Duration%');
+ const later = CalendarDateAdd(calendarRec, plainRelativeTo, new TemporalDuration(years, months, weeks));
+ const yearsMonthsWeeksInDays = DaysUntil(plainRelativeTo, later);
+ return days + yearsMonthsWeeksInDays;
}
export function BalanceDateDurationRelative(
@@ -3570,8 +3542,6 @@ export function BalanceDateDurationRelative(
return { years, months, weeks, days };
}
- if (!plainRelativeTo) throw new RangeError(`a starting point is required for ${largestUnit}s balancing`);
-
const untilOptions = ObjectCreate(null);
untilOptions.largestUnit = largestUnit;
@@ -3830,9 +3800,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) {
@@ -3893,7 +3861,12 @@ export function DifferenceISODateTime(
const years = GetSlot(untilResult, YEARS);
const months = GetSlot(untilResult, MONTHS);
const weeks = GetSlot(untilResult, WEEKS);
- const days = GetSlot(untilResult, DAYS);
+ let days = GetSlot(untilResult, DAYS);
+ if (largestUnit !== dateLargestUnit) {
+ // largestUnit < days, so add the days in to the normalized duration
+ timeDuration = timeDuration.add24HourDays(days);
+ days = 0;
+ }
CombineDateAndNormalizedTimeDuration(years, months, weeks, days, timeDuration);
return { years, months, weeks, days, norm: timeDuration };
}
@@ -4027,6 +4000,213 @@ 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 = GetSlot(plainDate1, ISO_YEAR);
+ const mon1 = GetSlot(plainDate1, ISO_MONTH);
+ const d1 = GetSlot(plainDate1, ISO_DAY);
+ 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
+ ));
+ const total = norm.totalNs.toJSNumber();
+ return { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, total };
+ }
+
+ 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
+ };
+ }
+
+ 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');
+ const total = norm.totalNs.toJSNumber();
+ return { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, total };
+ }
+
+ 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 = TEMPORAL_UNITS.reduce((allowed, unitInfo) => {
const p = unitInfo[0];
@@ -4081,7 +4261,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,
@@ -4191,68 +4371,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,
@@ -4409,7 +4554,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
@@ -4438,65 +4589,21 @@ export function DifferenceTemporalZonedDateTime(operation, zonedDateTime, other,
);
const plainRelativeTo = TemporalDateTimeToDate(precalculatedPlainDateTime);
- 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 b4f56a6c72..fd62cb84bc 100644
--- a/spec/duration.html
+++ b/spec/duration.html
@@ -114,10 +114,9 @@
Temporal.Duration.compare ( _one_, _two_ [ , _options_ ] )
1. If _after1_ < _after2_, return *-1*𝔽.
1. Return *+0*𝔽.
1. If _calendarUnitsPresent_ is *true*, then
- 1. Let _unbalanceResult1_ be ? UnbalanceDateDurationRelative(_one_.[[Years]], _one_.[[Months]], _one_.[[Weeks]], _one_.[[Days]], *"day"*, _plainRelativeTo_, _calendarRec_).
- 1. Let _unbalanceResult2_ be ? UnbalanceDateDurationRelative(_two_.[[Years]], _two_.[[Months]], _two_.[[Weeks]], _two_.[[Days]], *"day"*, _plainRelativeTo_, _calendarRec_).
- 1. Let _days1_ be _unbalanceResult1_.[[Days]].
- 1. Let _days2_ be _unbalanceResult2_.[[Days]].
+ 1. If _plainRelativeTo_ is *undefined*, throw a *RangeError* exception.
+ 1. Let _days1_ be ? UnbalanceDateDurationRelative(_one_.[[Years]], _one_.[[Months]], _one_.[[Weeks]], _one_.[[Days]], _plainRelativeTo_, _calendarRec_).
+ 1. Let _days2_ be ? UnbalanceDateDurationRelative(_two_.[[Years]], _two_.[[Months]], _two_.[[Weeks]], _two_.[[Days]], _plainRelativeTo_, _calendarRec_).
1. Else,
1. Let _days1_ be _one_.[[Days]].
1. Let _days2_ be _two_.[[Days]].
@@ -461,26 +460,34 @@ Temporal.Duration.prototype.round ( _roundTo_ )
1. NOTE: The above conditions mean that the operation will have no effect: the smallest unit and rounding increment will leave the total duration unchanged, and it can be determined without calling a calendar or time zone method that no balancing will take place.
1. Return ! CreateTemporalDuration(_duration_.[[Years]], _duration_.[[Months]], _duration_.[[Weeks]], _duration_.[[Days]], _duration_.[[Hours]], _duration_.[[Minutes]], _duration_.[[Seconds]], _duration_.[[Milliseconds]], _duration_.[[Microseconds]], _duration_.[[Nanoseconds]]).
1. Let _precalculatedPlainDateTime_ be *undefined*.
- 1. If _roundingGranularityIsNoop_ is *false*, or IsCalendarUnit(_largestUnit_) is *true*, or _largestUnit_ is *"day"*, or _calendarUnitsPresent_ is *true*, or _duration_.[[Days]] ≠ 0, let _plainDateTimeOrRelativeToWillBeUsed_ be *true*; else let _plainDateTimeOrRelativeToWillBeUsed_ be *false*.
+ 1. If IsCalendarUnit(_largestUnit_) is *true*, or _largestUnit_ is *"day"*, or _calendarUnitsPresent_ is *true*, or _duration_.[[Days]] ≠ 0, let _plainDateTimeOrRelativeToWillBeUsed_ be *true*; else let _plainDateTimeOrRelativeToWillBeUsed_ be *false*.
1. If _zonedRelativeTo_ is not *undefined* and _plainDateTimeOrRelativeToWillBeUsed_ is *true*, then
1. NOTE: The above conditions mean that the corresponding `Temporal.PlainDateTime` or `Temporal.PlainDate` for _zonedRelativeTo_ will be used in one of the operations below.
1. Let _instant_ be ! CreateTemporalInstant(_zonedRelativeTo_.[[Nanoseconds]]).
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. Let _roundResult_ be _roundRecord_.[[DurationRecord]].
+ 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. Let _roundResult_ be _roundRecord_.[[DurationRecord]].
1. Else,
- 1. Let _normWithDays_ be ? Add24HourDaysToNormalizedTimeDuration(_roundResult_.[[NormalizedTime]], _roundResult_.[[Days]]).
+ 1. If _calendarUnitsPresent_ is *true*, or IsCalendarUnit(_largestUnit_) is *true*, or IsCalendarUnit(_smallestUnit_) is *true*, throw a *RangeError* exception.
+ 1. Let _roundRecord_ be ? RoundDuration(0, 0, 0, _duration_.[[Days]], _norm_, _roundingIncrement_, _smallestUnit_, _roundingMode_).
+ 1. Let _normWithDays_ be ? Add24HourDaysToNormalizedTimeDuration(_roundRecord_.[[NormalizedDuration]].[[Days]], _roundRecord_.[[NormalizedDuration]].[[NormalizedTime]]).
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. Let _roundResult_ be CreateDurationRecord(0, 0, 0, _balanceResult_.[[Days]], _balanceResult_.[[Hours]], _balanceResult_.[[Minutes]], _balanceResult_.[[Seconds]], _balanceResult_.[[Milliseconds]], _balanceResult_.[[Microseconds]], _balanceResult_.[[Nanoseconds]]).
+ 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 +520,22 @@ 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 _normWithDays_ be ? Add24HourDaysToNormalizedTimeDuration(_duration_.[[Days]], _norm_).
+ 1. Let _roundRecord_ be ? RoundDuration(0, 0, 0, 0, _normWithDays_, 1, _unit_, *"trunc"*).
1. Return 𝔽(_roundRecord_.[[Total]]).
@@ -1727,40 +1722,17 @@
_months_: an integer,
_weeks_: an integer,
_days_: an integer,
- _largestUnit_: a String,
- _plainRelativeTo_: *undefined* or a Temporal.PlainDate,
- _calendarRec_: *undefined* or a Calendar Methods Record,
- )
+ _plainRelativeTo_: a Temporal.PlainDate,
+ _calendarRec_: a Calendar Methods Record,
+ ): either a normal completion containing an integer or a throw completion
- 1. Assert: If _plainRelativeTo_ is not *undefined*, _calendarRec_ is not *undefined*.
- 1. Let _defaultLargestUnit_ be DefaultTemporalLargestUnit(_years_, _months_, _weeks_, _days_, 0, 0, 0, 0, 0).
- 1. Let _effectiveLargestUnit_ be LargerOfTwoTemporalUnits(_largestUnit_, *"day"*).
- 1. If _effectiveLargestUnit_ is LargerOfTwoTemporalUnits(_defaultLargestUnit_, _effectiveLargestUnit_), then
- 1. Return ! CreateDateDurationRecord(_years_, _months_, _weeks_, _days_).
- 1. Assert: _effectiveLargestUnit_ is not *"year"*.
- 1. If _calendarRec_ is *undefined*, then
- 1. Throw a *RangeError* exception.
+ 1. If _years_ = 0 and _months_ = 0 and _weeks_ = 0, return _days_.
1. Assert: CalendarMethodsRecordHasLookedUp(_calendarRec_, ~date-add~) is *true*.
- 1. If _effectiveLargestUnit_ is *"month"*, then
- 1. Assert: CalendarMethodsRecordHasLookedUp(_calendarRec_, ~date-until~) is *true*.
- 1. Let _yearsDuration_ be ! CreateTemporalDuration(_years_, 0, 0, 0, 0, 0, 0, 0, 0, 0).
- 1. Let _later_ be ? CalendarDateAdd(_calendarRec_, _plainRelativeTo_, _yearsDuration_).
- 1. Let _untilOptions_ be OrdinaryObjectCreate(*null*).
- 1. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, *"month"*).
- 1. Let _untilResult_ be ? CalendarDateUntil(_calendarRec_, _plainRelativeTo_, _later_, _untilOptions_).
- 1. Let _yearsInMonths_ be _untilResult_.[[Months]].
- 1. Return ? CreateDateDurationRecord(0, _months_ + _yearsInMonths_, _weeks_, _days_).
- 1. If _effectiveLargestUnit_ is *"week"*, then
- 1. Let _yearsMonthsDuration_ be ! CreateTemporalDuration(_years_, _months_, 0, 0, 0, 0, 0, 0, 0, 0).
- 1. Let _later_ be ? CalendarDateAdd(_calendarRec_, _plainRelativeTo_, _yearsMonthsDuration_).
- 1. Let _yearsMonthsInDays_ be DaysUntil(_plainRelativeTo_, _later_).
- 1. Return ? CreateDateDurationRecord(0, 0, _weeks_, _days_ + _yearsMonthsInDays_).
- 1. NOTE: _largestUnit_ can be any time unit as well as *"day"*.
1. Let _yearsMonthsWeeksDuration_ be ! CreateTemporalDuration(_years_, _months_, _weeks_, 0, 0, 0, 0, 0, 0, 0).
1. Let _later_ be ? CalendarDateAdd(_calendarRec_, _plainRelativeTo_, _yearsMonthsWeeksDuration_).
1. Let _yearsMonthsWeeksInDays_ be DaysUntil(_plainRelativeTo_, _later_).
@@ -1777,8 +1749,8 @@
_days_: an integer,
_largestUnit_: a String,
_smallestUnit_: a String,
- _plainRelativeTo_: *undefined* or a Temporal.PlainDate,
- _calendarRec_: *undefined* or a Calendar Methods Record,
+ _plainRelativeTo_: a Temporal.PlainDate,
+ _calendarRec_: a Calendar Methods Record,
): either a normal completion containing a Date Duration Record or a throw completion
- 1. Assert: If _plainRelativeTo_ is not *undefined*, _calendarRec_ is not *undefined*.
1. Let _allZero_ be *false*.
1. If _years_ = 0, and _months_ = 0, and _weeks_ = 0, and _days_ = 0, set _allZero_ to *true*.
1. If _largestUnit_ is not one of *"year"*, *"month"*, or *"week"*, or _allZero_ is *true*, then
1. Return ! CreateDateDurationRecord(_years_, _months_, _weeks_, _days_).
- 1. If _plainRelativeTo_ is *undefined*, then
- 1. Throw a *RangeError* exception.
1. Assert: CalendarMethodsRecordHasLookedUp(_calendarRec_, ~date-add~) is *true*.
1. Assert: CalendarMethodsRecordHasLookedUp(_calendarRec_, ~date-until~) is *true*.
1. Let _untilOptions_ be OrdinaryObjectCreate(*null*).
diff --git a/spec/instant.html b/spec/instant.html
index 1a56503b7f..8c9690b365 100644
--- a/spec/instant.html
+++ b/spec/instant.html
@@ -590,7 +590,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)
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]] }.
@@ -671,7 +669,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 18711cfc17..9767f4db43 100644
--- a/spec/plaindatetime.html
+++ b/spec/plaindatetime.html
@@ -1348,7 +1348,67 @@
1. Let _untilOptions_ be ! SnapshotOwnProperties(_options_, *null*).
1. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, _dateLargestUnit_).
1. Let _dateDifference_ be ? DifferenceDate(_calendarRec_, _date1_, _date2_, _untilOptions_).
- 1. Return ? CreateNormalizedDurationRecord(_dateDifference_.[[Years]], _dateDifference_.[[Months]], _dateDifference_.[[Weeks]], _dateDifference_.[[Days]], _timeDuration_).
+ 1. Let _days_ be _dateDifference_.[[Days]].
+ 1. If _largestUnit_ is not _dateLargestUnit_, then
+ 1. Set _timeDuration_ to ? Add24HourDaysToNormalizedTimeDuration(_dateDifference_.[[Days]], _timeDuration_).
+ 1. Set _days_ to 0.
+ 1. Return ? CreateNormalizedDurationRecord(_dateDifference_.[[Years]], _dateDifference_.[[Months]], _dateDifference_.[[Weeks]], _days_, _timeDuration_).
+
+
+
+
+
+ DifferencePlainDateTimeWithRounding (
+ _plainDate1_: a Temporal.PlainDate,
+ _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,
+ _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 a throw completion
+
+
+
+ 1. Assert: IsValidISODate(_y2_, _mon2_, _d2_) is *true*.
+ 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 _total_ be NormalizedTimeDurationSeconds(_normWithDays_) × 109 + NormalizedTimeDurationSubseconds(_normWithDays_).
+ 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]]: _total_ }.
+ 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]] }.
@@ -1376,21 +1436,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 53ef405013..972f410019 100644
--- a/spec/zoneddatetime.html
+++ b/spec/zoneddatetime.html
@@ -1541,6 +1541,52 @@
+
+
+ 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 a throw completion
+
+
+
+ 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. 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 _total_ be NormalizedTimeDurationSeconds(_difference_.[[NormalizedTime]]) × 109 + NormalizedTimeDurationSubseconds(_difference_.[[NormalizedTime]]).
+ 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]]: _total_ }.
+ 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 (
@@ -1562,7 +1608,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. NOTE: To calculate differences in two different time zones, _settings_.[[LargestUnit]] must be *"hour"* or smaller, because day lengths can vary between time zones due to DST and other UTC offset shifts.
@@ -1575,18 +1622,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. 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]]).