Skip to content

Commit

Permalink
Bug 1929284 - Part 26: Constrain day when year is present in Calendar…
Browse files Browse the repository at this point in the history
…MonthDayToISOReferenceDate. r=allstarschh

See also:
- tc39/proposal-temporal#2863
- tc39/proposal-temporal#2864

Differential Revision: https://phabricator.services.mozilla.com/D228027
  • Loading branch information
anba committed Dec 3, 2024
1 parent 8f36fdd commit 329d262
Showing 1 changed file with 27 additions and 14 deletions.
41 changes: 27 additions & 14 deletions js/src/builtin/temporal/Calendar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2235,8 +2235,34 @@ static bool CalendarMonthDayToISOReferenceDate(JSContext* cx,
return false;
}
}
MOZ_ASSERT(monthCode != MonthCode{});

if (overflow == TemporalOverflow::Constrain) {
// Call into ICU4X if `day` exceeds the minimum number of days.
int32_t minDaysInMonth = CalendarDaysInMonth(calendar, monthCode).first;
if (day > minDaysInMonth) {
day = capi::ICU4XDate_day_of_month(date.get());
}
} else {
MOZ_ASSERT(overflow == TemporalOverflow::Reject);
MOZ_ASSERT(day == int32_t(capi::ICU4XDate_day_of_month(date.get())));
}
} else {
MOZ_ASSERT(monthCode != MonthCode{});

// Constrain `day` to maximum possible day of the input month.
int32_t maxDaysInMonth = CalendarDaysInMonth(calendar, monthCode).second;
if (overflow == TemporalOverflow::Constrain) {
day = std::min(day, maxDaysInMonth);
} else {
MOZ_ASSERT(overflow == TemporalOverflow::Reject);

if (day > maxDaysInMonth) {
ReportCalendarFieldOverflow(cx, "day", day);
return false;
}
}
}
MOZ_ASSERT(monthCode != MonthCode{});

// Try years starting from 31 December, 1972.
constexpr auto isoReferenceDate = PlainDate{1972, 12, 31};
Expand All @@ -2252,19 +2278,6 @@ static bool CalendarMonthDayToISOReferenceDate(JSContext* cx,
return false;
}

// Constrain day to maximum possible day for the input month.
int32_t daysInMonth = CalendarDaysInMonth(calendar, monthCode).second;
if (overflow == TemporalOverflow::Constrain) {
day = std::min(day, daysInMonth);
} else {
MOZ_ASSERT(overflow == TemporalOverflow::Reject);

if (day > daysInMonth) {
ReportCalendarFieldOverflow(cx, "day", day);
return false;
}
}

// 10'000 is sufficient to find all possible month-days, even for rare cases
// like `{calendar: "chinese", monthCode: "M09L", day: 30}`.
constexpr size_t maxIterations = 10'000;
Expand Down

0 comments on commit 329d262

Please sign in to comment.