diff --git a/polyfill/lib/ecmascript.mjs b/polyfill/lib/ecmascript.mjs
index 2fdde44e85..b42e25c834 100644
--- a/polyfill/lib/ecmascript.mjs
+++ b/polyfill/lib/ecmascript.mjs
@@ -5088,15 +5088,9 @@ export function RoundDuration(
relativeTo = undefined
) {
const TemporalDuration = GetIntrinsic('%Temporal.Duration%');
- let calendar, zdtRelative;
- if (relativeTo) {
- if (IsTemporalZonedDateTime(relativeTo)) {
- zdtRelative = relativeTo;
- relativeTo = ToTemporalDate(relativeTo);
- } else if (!IsTemporalDate(relativeTo)) {
- throw new TypeError('starting point must be PlainDate or ZonedDateTime');
- }
- calendar = GetSlot(relativeTo, CALENDAR);
+
+ if ((unit === 'year' || unit === 'month' || unit === 'week') && !relativeTo) {
+ throw new RangeError(`A starting point is required for ${unit}s rounding`);
}
// First convert time units up to days, if rounding to days or higher units.
@@ -5105,8 +5099,8 @@ export function RoundDuration(
if (unit === 'year' || unit === 'month' || unit === 'week' || unit === 'day') {
nanoseconds = TotalDurationNanoseconds(0, hours, minutes, seconds, milliseconds, microseconds, nanoseconds, 0);
let intermediate;
- if (zdtRelative) {
- intermediate = MoveRelativeZonedDateTime(zdtRelative, years, months, weeks, days);
+ if (IsTemporalZonedDateTime(relativeTo)) {
+ intermediate = MoveRelativeZonedDateTime(relativeTo, years, months, weeks, days);
}
let deltaDays;
({ days: deltaDays, nanoseconds, dayLengthNs } = NanosecondsToDays(nanoseconds, intermediate));
@@ -5117,7 +5111,8 @@ export function RoundDuration(
let total;
switch (unit) {
case 'year': {
- if (!calendar) throw new RangeError('A starting point is required for years rounding');
+ relativeTo = ToTemporalDate(relativeTo);
+ const calendar = GetSlot(relativeTo, CALENDAR);
// convert months and weeks to days by calculating difference(
// relativeTo + years, relativeTo + { years, months, weeks })
@@ -5161,7 +5156,8 @@ export function RoundDuration(
break;
}
case 'month': {
- if (!calendar) throw new RangeError('A starting point is required for months rounding');
+ relativeTo = ToTemporalDate(relativeTo);
+ const calendar = GetSlot(relativeTo, CALENDAR);
// convert weeks to days by calculating difference(relativeTo +
// { years, months }, relativeTo + { years, months, weeks })
@@ -5196,7 +5192,9 @@ export function RoundDuration(
break;
}
case 'week': {
- if (!calendar) throw new RangeError('A starting point is required for weeks rounding');
+ relativeTo = ToTemporalDate(relativeTo);
+ const calendar = GetSlot(relativeTo, CALENDAR);
+
// Weeks may be different lengths of days depending on the calendar,
// convert days to weeks in a loop as described above under 'years'.
const sign = MathSign(days);
diff --git a/spec/duration.html b/spec/duration.html
index ecc0fee81c..9930b0b2cf 100644
--- a/spec/duration.html
+++ b/spec/duration.html
@@ -1663,21 +1663,11 @@
1. If _relativeTo_ is not present, set _relativeTo_ to *undefined*.
1. If _unit_ is *"year"*, *"month"*, or *"week"*, and _relativeTo_ is *undefined*, then
1. Throw a *RangeError* exception.
- 1. Let _zonedRelativeTo_ be *undefined*.
- 1. If _relativeTo_ is not *undefined*, then
- 1. If _relativeTo_ has an [[InitializedTemporalZonedDateTime]] internal slot, then
- 1. Set _zonedRelativeTo_ to _relativeTo_.
- 1. Set _relativeTo_ to ? ToTemporalDate(_relativeTo_).
- 1. Else,
- 1. Assert: _relativeTo_ has an [[InitializedTemporalDate]] internal slot.
- 1. Let _calendar_ be _relativeTo_.[[Calendar]].
- 1. Else,
- 1. NOTE: _calendar_ will not be used below.
1. If _unit_ is one of *"year"*, *"month"*, *"week"*, or *"day"*, then
1. Let _nanoseconds_ be ! TotalDurationNanoseconds(0, _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, _nanoseconds_, 0).
1. Let _intermediate_ be *undefined*.
- 1. If _zonedRelativeTo_ is not *undefined*, then
- 1. Let _intermediate_ be ? MoveRelativeZonedDateTime(_zonedRelativeTo_, _years_, _months_, _weeks_, _days_).
+ 1. If _relativeTo_ is an Object with an [[InitializedTemporalZonedDateTime]] internal slot, then
+ 1. Let _intermediate_ be ? MoveRelativeZonedDateTime(_relativeTo_, _years_, _months_, _weeks_, _days_).
1. Let _result_ be ? NanosecondsToDays(_nanoseconds_, _intermediate_).
1. Set _days_ to _days_ + _result_.[[Days]] + _result_.[[Nanoseconds]] / _result_.[[DayLength]].
1. Set _hours_, _minutes_, _seconds_, _milliseconds_, _microseconds_, and _nanoseconds_ to 0.
@@ -1685,6 +1675,8 @@
1. Let _fractionalSeconds_ be _nanoseconds_ × 10-9 + _microseconds_ × 10-6 + _milliseconds_ × 10-3 + _seconds_.
1. Let _remainder_ be *undefined*.
1. If _unit_ is *"year"*, then
+ 1. Set _relativeTo_ to ? ToTemporalDate(_relativeTo_).
+ 1. Let _calendar_ be _relativeTo_.[[Calendar]].
1. Let _yearsDuration_ be ! CreateTemporalDuration(_years_, 0, 0, 0, 0, 0, 0, 0, 0, 0).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
@@ -1717,6 +1709,8 @@
1. Set _remainder_ to _fractionalYears_ - _years_.
1. Set _months_, _weeks_, and _days_ to 0.
1. Else if _unit_ is *"month"*, then
+ 1. Set _relativeTo_ to ? ToTemporalDate(_relativeTo_).
+ 1. Let _calendar_ be _relativeTo_.[[Calendar]].
1. Let _yearsMonths_ be ! CreateTemporalDuration(_years_, _months_, 0, 0, 0, 0, 0, 0, 0, 0).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
@@ -1744,6 +1738,8 @@
1. Set _remainder_ to _fractionalMonths_ - _months_.
1. Set _weeks_ and _days_ to 0.
1. Else if _unit_ is *"week"*, then
+ 1. Set _relativeTo_ to ? ToTemporalDate(_relativeTo_).
+ 1. Let _calendar_ be _relativeTo_.[[Calendar]].
1. If _days_ < 0, let _sign_ be -1; else, let _sign_ be 1.
1. Let _oneWeek_ be ! CreateTemporalDuration(0, 0, _sign_, 0, 0, 0, 0, 0, 0, 0).
1. If _calendar_ is an Object, then