Skip to content

Commit

Permalink
Fix: Don't call GetMethod on a string calendar
Browse files Browse the repository at this point in the history
When GetMethod is used to lookup the dateAdd or dateUntil method of a
calendar, we need to account for the case where the calendar is a builtin
calendar represented by a string. This was an oversight in #2482.

In hindsight, the lookups of dateAdd and dateUntil in
BalanceDurationRelative should have been grouped together as they were in
UnbalanceDurationRelative. But since that will be addressed anyway by the
Calendar Method Records in the yet-to-be-merged PR #2519, I'm not planning
to change that here.

Closes: #2547
  • Loading branch information
ptomato committed Apr 18, 2023
1 parent 8e9a398 commit 083b90e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 24 deletions.
27 changes: 15 additions & 12 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3295,8 +3295,11 @@ export function UnbalanceDurationRelative(years, months, weeks, days, largestUni
{
if (!calendar) throw new RangeError('a starting point is required for months balancing');
// balance years down to months
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateUntil = GetMethod(calendar, 'dateUntil');
let dateAdd, dateUntil;
if (typeof calendar !== 'string') {
dateAdd = GetMethod(calendar, 'dateAdd');
dateUntil = GetMethod(calendar, 'dateUntil');
}
while (!years.abs().isZero()) {
const newRelativeTo = CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd);
const untilOptions = ObjectCreate(null);
Expand All @@ -3312,7 +3315,7 @@ export function UnbalanceDurationRelative(years, months, weeks, days, largestUni
case 'week':
{
if (!calendar) throw new RangeError('a starting point is required for weeks balancing');
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
// balance years down to days
while (!years.abs().isZero()) {
let oneYearDays;
Expand All @@ -3334,7 +3337,7 @@ export function UnbalanceDurationRelative(years, months, weeks, days, largestUni
{
if (years.isZero() && months.isZero() && weeks.isZero()) break;
if (!calendar) throw new RangeError('a starting point is required for balancing calendar units');
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
// balance years down to days
while (!years.abs().isZero()) {
let oneYearDays;
Expand Down Expand Up @@ -3394,7 +3397,7 @@ export function BalanceDurationRelative(years, months, weeks, days, largestUnit,
switch (largestUnit) {
case 'year': {
if (!calendar) throw new RangeError('a starting point is required for years balancing');
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
// balance days up to years
let newRelativeTo, oneYearDays;
({ relativeTo: newRelativeTo, days: oneYearDays } = MoveRelativeDate(calendar, relativeTo, oneYear, dateAdd));
Expand All @@ -3417,7 +3420,7 @@ export function BalanceDurationRelative(years, months, weeks, days, largestUnit,

// balance months up to years
newRelativeTo = CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd);
const dateUntil = GetMethod(calendar, 'dateUntil');
const dateUntil = typeof calendar !== 'string' ? GetMethod(calendar, 'dateUntil') : undefined;
const untilOptions = ObjectCreate(null);
untilOptions.largestUnit = 'month';
let untilResult = CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil);
Expand All @@ -3436,7 +3439,7 @@ export function BalanceDurationRelative(years, months, weeks, days, largestUnit,
}
case 'month': {
if (!calendar) throw new RangeError('a starting point is required for months balancing');
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
// balance days up to months
let newRelativeTo, oneMonthDays;
({ relativeTo: newRelativeTo, days: oneMonthDays } = MoveRelativeDate(calendar, relativeTo, oneMonth, dateAdd));
Expand All @@ -3450,7 +3453,7 @@ export function BalanceDurationRelative(years, months, weeks, days, largestUnit,
}
case 'week': {
if (!calendar) throw new RangeError('a starting point is required for weeks balancing');
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
// balance days up to weeks
let newRelativeTo, oneWeekDays;
({ relativeTo: newRelativeTo, days: oneWeekDays } = MoveRelativeDate(calendar, relativeTo, oneWeek, dateAdd));
Expand Down Expand Up @@ -4386,7 +4389,7 @@ export function AddDuration(

const dateDuration1 = new TemporalDuration(y1, mon1, w1, d1, 0, 0, 0, 0, 0, 0);
const dateDuration2 = new TemporalDuration(y2, mon2, w2, d2, 0, 0, 0, 0, 0, 0);
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
const intermediate = CalendarDateAdd(calendar, relativeTo, dateDuration1, undefined, dateAdd);
const end = CalendarDateAdd(calendar, intermediate, dateDuration2, undefined, dateAdd);

Expand Down Expand Up @@ -5125,7 +5128,7 @@ export function RoundDuration(
// convert months and weeks to days by calculating difference(
// relativeTo + years, relativeTo + { years, months, weeks })
const yearsDuration = new TemporalDuration(years);
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
const yearsLater = CalendarDateAdd(calendar, relativeTo, yearsDuration, undefined, dateAdd);
const yearsMonthsWeeks = new TemporalDuration(years, months, weeks);
const yearsMonthsWeeksLater = CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, undefined, dateAdd);
Expand Down Expand Up @@ -5169,7 +5172,7 @@ export function RoundDuration(
// convert weeks to days by calculating difference(relativeTo +
// { years, months }, relativeTo + { years, months, weeks })
const yearsMonths = new TemporalDuration(years, months);
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
const yearsMonthsLater = CalendarDateAdd(calendar, relativeTo, yearsMonths, undefined, dateAdd);
const yearsMonthsWeeks = new TemporalDuration(years, months, weeks);
const yearsMonthsWeeksLater = CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, undefined, dateAdd);
Expand Down Expand Up @@ -5204,7 +5207,7 @@ export function RoundDuration(
// convert days to weeks in a loop as described above under 'years'.
const sign = MathSign(days);
const oneWeek = new TemporalDuration(0, 0, days < 0 ? -1 : 1);
const dateAdd = GetMethod(calendar, 'dateAdd');
const dateAdd = typeof calendar !== 'string' ? GetMethod(calendar, 'dateAdd') : undefined;
let oneWeekDays;
({ relativeTo, days: oneWeekDays } = MoveRelativeDate(calendar, relativeTo, oneWeek, dateAdd));
while (MathAbs(days) >= MathAbs(oneWeekDays)) {
Expand Down
58 changes: 46 additions & 12 deletions spec/duration.html
Original file line number Diff line number Diff line change
Expand Up @@ -1328,8 +1328,12 @@ <h1>
1. If _largestUnit_ is *"month"*, then
1. If _calendar_ is *undefined*, then
1. Throw a *RangeError* exception.
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Let _dateUntil_ be ? GetMethod(_calendar_, *"dateUntil"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Let _dateUntil_ be ? GetMethod(_calendar_, *"dateUntil"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Let _dateUntil_ be ~unused~.
1. Repeat, while _years_ &ne; 0,
1. Let _newRelativeTo_ be ? CalendarDateAdd(_calendar_, _relativeTo_, _oneYear_, *undefined*, _dateAdd_).
1. Let _untilOptions_ be OrdinaryObjectCreate(*null*).
Expand All @@ -1342,7 +1346,10 @@ <h1>
1. Else if _largestUnit_ is *"week"*, then
1. If _calendar_ is *undefined*, then
1. Throw a *RangeError* exception.
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Repeat, while _years_ &ne; 0,
1. Let _moveResult_ be ? MoveRelativeDate(_calendar_, _relativeTo_, _oneYear_, _dateAdd_).
1. Set _relativeTo_ to _moveResult_.[[RelativeTo]].
Expand All @@ -1357,7 +1364,10 @@ <h1>
1. If any of _years_, _months_, and _weeks_ are not zero, then
1. If _calendar_ is *undefined*, then
1. Throw a *RangeError* exception.
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Repeat, while _years_ &ne; 0,
1. Let _moveResult_ be ? MoveRelativeDate(_calendar_, _relativeTo_, _oneYear_, _dateAdd_).
1. Set _relativeTo_ to _moveResult_.[[RelativeTo]].
Expand Down Expand Up @@ -1405,7 +1415,10 @@ <h1>
1. Set _relativeTo_ to ? ToTemporalDate(_relativeTo_).
1. Let _calendar_ be _relativeTo_.[[Calendar]].
1. If _largestUnit_ is *"year"*, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Let _moveResult_ be ? MoveRelativeDate(_calendar_, _relativeTo_, _oneYear_, _dateAdd_).
1. Let _newRelativeTo_ be _moveResult_.[[RelativeTo]].
1. Let _oneYearDays_ be _moveResult_.[[Days]].
Expand All @@ -1427,7 +1440,10 @@ <h1>
1. Set _newRelativeTo_ to _moveResult_.[[RelativeTo]].
1. Set _oneMonthDays_ to _moveResult_.[[Days]].
1. Set _newRelativeTo_ to ? CalendarDateAdd(_calendar_, _relativeTo_, _oneYear_, *undefined*, _dateAdd_).
1. Let _dateUntil_ be ? GetMethod(_calendar_, *"dateUntil"*).
1. If _calendar_ is an Object, then
1. Let _dateUntil_ be ? GetMethod(_calendar_, *"dateUntil"*).
1. Else,
1. Let _dateUntil_ be ~unused~.
1. Let _untilOptions_ be OrdinaryObjectCreate(*null*).
1. Perform ! CreateDataPropertyOrThrow(_untilOptions_, *"largestUnit"*, *"month"*).
1. Let _untilResult_ be ? CalendarDateUntil(_calendar_, _relativeTo_, _newRelativeTo_, _untilOptions_, _dateUntil_).
Expand All @@ -1442,7 +1458,10 @@ <h1>
1. Set _untilResult_ to ? CalendarDateUntil(_calendar_, _relativeTo_, _newRelativeTo_, _untilOptions_, _dateUntil_).
1. Set _oneYearMonths_ to _untilResult_.[[Months]].
1. Else if _largestUnit_ is *"month"*, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Let _moveResult_ be ? MoveRelativeDate(_calendar_, _relativeTo_, _oneMonth_, _dateAdd_).
1. Let _newRelativeTo_ be _moveResult_.[[RelativeTo]].
1. Let _oneMonthDays_ be _moveResult_.[[Days]].
Expand All @@ -1455,7 +1474,10 @@ <h1>
1. Set _oneMonthDays_ to _moveResult_.[[Days]].
1. Else,
1. Assert: _largestUnit_ is *"week"*.
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Let _moveResult_ be ? MoveRelativeDate(_calendar_, _relativeTo_, _oneWeek_, _dateAdd_).
1. Let _newRelativeTo_ be _moveResult_.[[RelativeTo]].
1. Let _oneWeekDays_ be _moveResult_.[[Days]].
Expand Down Expand Up @@ -1513,7 +1535,10 @@ <h1>
1. Let _calendar_ be _relativeTo_.[[Calendar]].
1. Let _dateDuration1_ be ! CreateTemporalDuration(_y1_, _mon1_, _w1_, _d1_, 0, 0, 0, 0, 0, 0).
1. Let _dateDuration2_ be ! CreateTemporalDuration(_y2_, _mon2_, _w2_, _d2_, 0, 0, 0, 0, 0, 0).
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Let _intermediate_ be ? CalendarDateAdd(_calendar_, _relativeTo_, _dateDuration1_, *undefined*, _dateAdd_).
1. Let _end_ be ? CalendarDateAdd(_calendar_, _intermediate_, _dateDuration2_, *undefined*, _dateAdd_).
1. Let _dateLargestUnit_ be ! LargerOfTwoTemporalUnits(*"day"*, _largestUnit_).
Expand Down Expand Up @@ -1651,7 +1676,10 @@ <h1>
1. Let _remainder_ be *undefined*.
1. If _unit_ is *"year"*, then
1. Let _yearsDuration_ be ! CreateTemporalDuration(_years_, 0, 0, 0, 0, 0, 0, 0, 0, 0).
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Let _yearsLater_ be ? CalendarDateAdd(_calendar_, _relativeTo_, _yearsDuration_, *undefined*, _dateAdd_).
1. Let _yearsMonthsWeeks_ be ! CreateTemporalDuration(_years_, _months_, _weeks_, 0, 0, 0, 0, 0, 0, 0).
1. Let _yearsMonthsWeeksLater_ be ? CalendarDateAdd(_calendar_, _relativeTo_, _yearsMonthsWeeks_, *undefined*, _dateAdd_).
Expand Down Expand Up @@ -1680,7 +1708,10 @@ <h1>
1. Set _months_, _weeks_, and _days_ to 0.
1. Else if _unit_ is *"month"*, then
1. Let _yearsMonths_ be ! CreateTemporalDuration(_years_, _months_, 0, 0, 0, 0, 0, 0, 0, 0).
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Let _yearsMonthsLater_ be ? CalendarDateAdd(_calendar_, _relativeTo_, _yearsMonths_, *undefined*, _dateAdd_).
1. Let _yearsMonthsWeeks_ be ! CreateTemporalDuration(_years_, _months_, _weeks_, 0, 0, 0, 0, 0, 0, 0).
1. Let _yearsMonthsWeeksLater_ be ? CalendarDateAdd(_calendar_, _relativeTo_, _yearsMonthsWeeks_, *undefined*, _dateAdd_).
Expand All @@ -1705,7 +1736,10 @@ <h1>
1. Else if _unit_ is *"week"*, then
1. If _days_ &lt; 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. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. If _calendar_ is an Object, then
1. Let _dateAdd_ be ? GetMethod(_calendar_, *"dateAdd"*).
1. Else,
1. Let _dateAdd_ be ~unused~.
1. Let _moveResult_ be ? MoveRelativeDate(_calendar_, _relativeTo_, _oneWeek_, _dateAdd_).
1. Set _relativeTo_ to _moveResult_.[[RelativeTo]].
1. Let _oneWeekDays_ be _moveResult_.[[Days]].
Expand Down

0 comments on commit 083b90e

Please sign in to comment.