LibJS: Ensure NudgeToCalendarUnit is given a non-zero duration sign

Otherwise, we trip internal Temporal spec assertions.

This is an editorial change in the Temporal spec. See:
https://github.com/tc39/proposal-temporal/commit/30f8575
This commit is contained in:
Timothy Flynn 2025-08-28 15:35:57 -04:00 committed by Jelle Raaijmakers
parent 0c038bf12e
commit 2fa6655dcb
2 changed files with 10 additions and 2 deletions

View File

@ -1378,8 +1378,8 @@ ThrowCompletionOr<Crypto::BigFraction> total_relative_duration(VM& vm, InternalD
{
// 1. If IsCalendarUnit(unit) is true, or timeZone is not UNSET and unit is DAY, then
if (is_calendar_unit(unit) || (time_zone.has_value() && unit == Unit::Day)) {
// a. Let sign be InternalDurationSign(duration).
auto sign = internal_duration_sign(duration);
// a. If InternalDurationSign(duration) < 0, let sign be -1; else let sign be 1.
auto sign = internal_duration_sign(duration) < 0 ? -1 : 1;
// b. Let record be ? NudgeToCalendarUnit(sign, duration, destEpochNs, isoDateTime, timeZone, calendar, 1, unit, TRUNC).
auto record = TRY(nudge_to_calendar_unit(vm, sign, duration, dest_epoch_ns, iso_date_time, time_zone, calendar, 1, unit, RoundingMode::Trunc));

View File

@ -17,6 +17,14 @@ describe("correct behavior", () => {
}
});
test("blank duration", () => {
const duration = new Temporal.Duration();
const relativeTo = new Temporal.ZonedDateTime(1n, "UTC");
const result = duration.total({ unit: "years", relativeTo: relativeTo });
expect(result).toBe(0);
});
test("relative to plain date", () => {
const duration = new Temporal.Duration(0, 0, 0, 31);