Skip to content

Commit ed85e96

Browse files
committed
Editorial: Limit year, month, and week length calculations to nonzero
In order to calculate the rounded value and totals in RoundDuration, when rounding to years, months, or weeks, we need to divide by the length of the year, month, or week in days. Throw an exception if this would otherwise result in division by zero. This is marked 'editorial' because division by zero with mathematical values is an editorial error in the spec. However, the month/week divisions didn't exist before the normative change in the previous commit, so this would previously only have applied to years. Closes: #2335
1 parent 69f7963 commit ed85e96

File tree

2 files changed

+6
-0
lines changed

2 files changed

+6
-0
lines changed

polyfill/lib/ecmascript.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5690,6 +5690,7 @@ export function RoundDuration(
56905690
// the duration. This lets us do days-or-larger rounding using BigInt
56915691
// math which reduces precision loss.
56925692
oneYearDays = MathAbs(oneYearDays);
5693+
if (oneYearDays === 0) throw new RangeError('custom calendar reported that a year is 0 days long');
56935694
const divisor = bigInt(oneYearDays).multiply(dayLengthNs);
56945695
nanoseconds = divisor.multiply(years).plus(bigInt(days).multiply(dayLengthNs)).plus(nanoseconds);
56955696
const rounded = RoundNumberToIncrement(nanoseconds, divisor.multiply(increment).toJSNumber(), roundingMode);
@@ -5737,6 +5738,7 @@ export function RoundDuration(
57375738
let { days: oneMonthDays } = MoveRelativeDate(calendarRec, plainRelativeTo, oneMonth);
57385739

57395740
oneMonthDays = MathAbs(oneMonthDays);
5741+
if (oneMonthDays === 0) throw new RangeError('custom calendar reported that a month is 0 days long');
57405742
const divisor = bigInt(oneMonthDays).multiply(dayLengthNs);
57415743
nanoseconds = divisor.multiply(months).plus(bigInt(days).multiply(dayLengthNs)).plus(nanoseconds);
57425744
const rounded = RoundNumberToIncrement(nanoseconds, divisor.multiply(increment), roundingMode);
@@ -5774,6 +5776,7 @@ export function RoundDuration(
57745776
let { days: oneWeekDays } = MoveRelativeDate(calendarRec, plainRelativeTo, oneWeek);
57755777

57765778
oneWeekDays = MathAbs(oneWeekDays);
5779+
if (oneWeekDays === 0) throw new RangeError('custom calendar reported that a week is 0 days long');
57775780
const divisor = bigInt(oneWeekDays).multiply(dayLengthNs);
57785781
nanoseconds = divisor.multiply(weeks).plus(bigInt(days).multiply(dayLengthNs)).plus(nanoseconds);
57795782
const rounded = RoundNumberToIncrement(nanoseconds, divisor.multiply(increment), roundingMode);

spec/duration.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,6 +1716,7 @@ <h1>
17161716
1. Let _oneYear_ be ! CreateTemporalDuration(_sign_, 0, 0, 0, 0, 0, 0, 0, 0, 0).
17171717
1. Set _moveResult_ to ? MoveRelativeDate(_calendarRec_, _plainRelativeTo_, _oneYear_).
17181718
1. Let _oneYearDays_ be _moveResult_.[[Days]].
1719+
1. If _oneYearDays_ = 0, throw a *RangeError* exception.
17191720
1. Let _fractionalYears_ be _years_ + _fractionalDays_ / abs(_oneYearDays_).
17201721
1. Set _years_ to RoundNumberToIncrement(_fractionalYears_, _increment_, _roundingMode_).
17211722
1. Set _total_ to _fractionalYears_.
@@ -1744,6 +1745,7 @@ <h1>
17441745
1. Let _oneMonth_ be ! CreateTemporalDuration(0, _sign_, 0, 0, 0, 0, 0, 0, 0, 0).
17451746
1. Let _moveResult_ be ? MoveRelativeDate(_calendarRec_, _plainRelativeTo_, _oneMonth_).
17461747
1. Let _oneMonthDays_ be _moveResult_.[[Days]].
1748+
1. If _oneMonthDays_ = 0, throw a *RangeError* exception.
17471749
1. Let _fractionalMonths_ be _months_ + _fractionalDays_ / abs(_oneMonthDays_).
17481750
1. Set _months_ to RoundNumberToIncrement(_fractionalMonths_, _increment_, _roundingMode_).
17491751
1. Set _total_ to _fractionalMonths_.
@@ -1765,6 +1767,7 @@ <h1>
17651767
1. Let _oneWeek_ be ! CreateTemporalDuration(0, 0, _sign_, 0, 0, 0, 0, 0, 0, 0).
17661768
1. Let _moveResult_ be ? MoveRelativeDate(_calendarRec_, _plainRelativeTo_, _oneWeek_).
17671769
1. Let _oneWeekDays_ be _moveResult_.[[Days]].
1770+
1. If _oneWeekDays_ = 0, throw a *RangeError* exception.
17681771
1. Let _fractionalWeeks_ be _weeks_ + _fractionalDays_ / abs(_oneWeekDays_).
17691772
1. Set _weeks_ to RoundNumberToIncrement(_fractionalWeeks_, _increment_, _roundingMode_).
17701773
1. Set _total_ to _fractionalWeeks_.

0 commit comments

Comments
 (0)