mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-08 05:27:14 +09:00
LibJS: Require strict matching with a precise ZonedDateTime offset
This is a normative change in the Temporal proposal. See:
1117eaf
This commit is contained in:
parent
f091047159
commit
c8b4dc4847
Notes:
github-actions[bot]
2025-06-02 21:10:33 +00:00
Author: https://github.com/trflynn89
Commit: c8b4dc4847
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4966
3 changed files with 70 additions and 6 deletions
|
@ -630,6 +630,19 @@ ThrowCompletionOr<RelativeTo> get_temporal_relative_to_option(VM& vm, Object con
|
|||
|
||||
// iv. Set matchBehaviour to MATCH-MINUTES.
|
||||
match_behavior = MatchBehavior::MatchMinutes;
|
||||
|
||||
// v. If offsetString is not EMPTY, then
|
||||
if (offset_string.has_value()) {
|
||||
// 1. Let offsetParseResult be ParseText(StringToCodePoints(offsetString), UTCOffset[+SubMinutePrecision]).
|
||||
auto offset_parse_result = parse_utc_offset(*offset_string, SubMinutePrecision::Yes);
|
||||
|
||||
// 2. Assert: offsetParseResult is a Parse Node.
|
||||
VERIFY(offset_parse_result.has_value());
|
||||
|
||||
// 3. If offsetParseResult contains more than one MinuteSecond Parse Node, set matchBehaviour to MATCH-EXACTLY.
|
||||
if (offset_parse_result->seconds.has_value())
|
||||
match_behavior = MatchBehavior::MatchExactly;
|
||||
}
|
||||
}
|
||||
|
||||
// g. Let calendar be result.[[Calendar]].
|
||||
|
|
|
@ -262,22 +262,35 @@ ThrowCompletionOr<GC::Ref<ZonedDateTime>> to_temporal_zoned_date_time(VM& vm, Va
|
|||
// l. Set matchBehaviour to MATCH-MINUTES.
|
||||
match_behavior = MatchBehavior::MatchMinutes;
|
||||
|
||||
// m. Let resolvedOptions be ? GetOptionsObject(options).
|
||||
// m. If offsetString is not EMPTY, then
|
||||
if (offset_string.has_value()) {
|
||||
// i. Let offsetParseResult be ParseText(StringToCodePoints(offsetString), UTCOffset[+SubMinutePrecision]).
|
||||
auto offset_parse_result = parse_utc_offset(*offset_string, SubMinutePrecision::Yes);
|
||||
|
||||
// ii. Assert: offsetParseResult is a Parse Node.
|
||||
VERIFY(offset_parse_result.has_value());
|
||||
|
||||
// iii. If offsetParseResult contains more than one MinuteSecond Parse Node, set matchBehaviour to MATCH-EXACTLY.
|
||||
if (offset_parse_result->seconds.has_value())
|
||||
match_behavior = MatchBehavior::MatchExactly;
|
||||
}
|
||||
|
||||
// n. Let resolvedOptions be ? GetOptionsObject(options).
|
||||
auto resolved_options = TRY(get_options_object(vm, options));
|
||||
|
||||
// n. Let disambiguation be ? GetTemporalDisambiguationOption(resolvedOptions).
|
||||
// o. Let disambiguation be ? GetTemporalDisambiguationOption(resolvedOptions).
|
||||
disambiguation = TRY(get_temporal_disambiguation_option(vm, resolved_options));
|
||||
|
||||
// o. Let offsetOption be ? GetTemporalOffsetOption(resolvedOptions, REJECT).
|
||||
// p. Let offsetOption be ? GetTemporalOffsetOption(resolvedOptions, REJECT).
|
||||
offset_option = TRY(get_temporal_offset_option(vm, resolved_options, OffsetOption::Reject));
|
||||
|
||||
// p. Perform ? GetTemporalOverflowOption(resolvedOptions).
|
||||
// q. Perform ? GetTemporalOverflowOption(resolvedOptions).
|
||||
TRY(get_temporal_overflow_option(vm, resolved_options));
|
||||
|
||||
// q. Let isoDate be CreateISODateRecord(result.[[Year]], result.[[Month]], result.[[Day]]).
|
||||
// r. Let isoDate be CreateISODateRecord(result.[[Year]], result.[[Month]], result.[[Day]]).
|
||||
iso_date = create_iso_date_record(*result.year, result.month, result.day);
|
||||
|
||||
// r. Let time be result.[[Time]].
|
||||
// s. Let time be result.[[Time]].
|
||||
time = result.time;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,21 @@ describe("correct behavior", () => {
|
|||
});
|
||||
expect(result).toBe(-1);
|
||||
});
|
||||
|
||||
test("sub-minute time zone offset", () => {
|
||||
const duration1 = new Temporal.Duration(0, 0, 0, 31);
|
||||
const duration2 = new Temporal.Duration(0, 1);
|
||||
|
||||
let result = Temporal.Duration.compare(duration1, duration2, {
|
||||
relativeTo: "1970-01-01T00:00:00-00:45[Africa/Monrovia]",
|
||||
});
|
||||
expect(result).toBe(0);
|
||||
|
||||
result = Temporal.Duration.compare(duration1, duration2, {
|
||||
relativeTo: "1970-01-01T00:00:00-00:44:30[Africa/Monrovia]",
|
||||
});
|
||||
expect(result).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors", () => {
|
||||
|
@ -132,4 +147,27 @@ describe("errors", () => {
|
|||
"A starting point is required for comparing calendar units"
|
||||
);
|
||||
});
|
||||
|
||||
test("sub-minute time zone offset mismatch", () => {
|
||||
const duration1 = new Temporal.Duration(0, 0, 0, 31);
|
||||
const duration2 = new Temporal.Duration(0, 1);
|
||||
|
||||
expect(() => {
|
||||
Temporal.Duration.compare(duration1, duration2, {
|
||||
relativeTo: "1970-01-01T00:00:00-00:44:40[Africa/Monrovia]",
|
||||
});
|
||||
}).toThrowWithMessage(
|
||||
RangeError,
|
||||
"Invalid offset for the provided date and time in the current time zone"
|
||||
);
|
||||
|
||||
expect(() => {
|
||||
Temporal.Duration.compare(duration1, duration2, {
|
||||
relativeTo: "1970-01-01T00:00:00-00:45:00[Africa/Monrovia]",
|
||||
});
|
||||
}).toThrowWithMessage(
|
||||
RangeError,
|
||||
"Invalid offset for the provided date and time in the current time zone"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue