LibJS: Disallow negative day lengths in ZonedDateTime.protoype.round

This is a normative change in the Temporal spec.

See: https://github.com/tc39/proposal-temporal/commit/6f04074
This commit is contained in:
Luke Wilde 2022-07-22 16:08:32 +01:00 committed by Linus Groh
parent 114120852d
commit 61847b3cef
3 changed files with 34 additions and 5 deletions

View file

@ -273,7 +273,8 @@
M(TemporalPropertyMustBeFinite, "Property must not be Infinity") \
M(TemporalPropertyMustBePositiveInteger, "Property must be a positive integer") \
M(TemporalTimeZoneOffsetStringMismatch, "Time zone offset string mismatch: '{}' is not equal to '{}'") \
M(TemporalZonedDateTimeRoundZeroLengthDay, "Cannot round a ZonedDateTime in a calendar that has zero-length days") \
M(TemporalZonedDateTimeRoundZeroOrNegativeLengthDay, "Cannot round a ZonedDateTime in a calendar or time zone that has zero or " \
"negative length days") \
M(ThisHasNotBeenInitialized, "|this| has not been initialized") \
M(ThisIsAlreadyInitialized, "|this| is already initialized") \
M(ToObjectNullOrUndefined, "ToObject on null or undefined") \

View file

@ -1018,10 +1018,10 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::round)
// 18. Let dayLengthNs be (endNs - startNs).
auto day_length_ns = end_ns->big_integer().minus(start_ns.big_integer()).to_double();
// 19. If dayLengthNs is 0, then
if (day_length_ns == 0) {
// 19. If dayLengthNs 0, then
if (day_length_ns <= 0) {
// a. Throw a RangeError exception.
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalZonedDateTimeRoundZeroLengthDay);
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalZonedDateTimeRoundZeroOrNegativeLengthDay);
}
// 20. Let roundResult be ! RoundISODateTime(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], roundingIncrement, smallestUnit, roundingMode, dayLengthNs).

View file

@ -112,7 +112,35 @@ describe("errors", () => {
zonedDateTime.round({ smallestUnit: "second" });
}).toThrowWithMessage(
RangeError,
"Cannot round a ZonedDateTime in a calendar that has zero-length days"
"Cannot round a ZonedDateTime in a calendar or time zone that has zero or negative length days"
);
});
test("time zone with negative length days", () => {
class CustomTimeZone extends Temporal.TimeZone {
constructor() {
super("UTC");
this.getPossibleInstantsForCallCount = 0;
}
getPossibleInstantsFor(temporalDateTime) {
this.getPossibleInstantsForCallCount++;
if (this.getPossibleInstantsForCallCount === 2) {
return [new Temporal.Instant(-1n)];
}
return super.getPossibleInstantsFor(temporalDateTime);
}
}
const zonedDateTime = new Temporal.ZonedDateTime(1n, new CustomTimeZone());
expect(() => {
zonedDateTime.round({ smallestUnit: "second" });
}).toThrowWithMessage(
RangeError,
"Cannot round a ZonedDateTime in a calendar or time zone that has zero or negative length days"
);
});
});