From 9643a5c63f61741f82f91a49821f9b6b5d2e4e68 Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Thu, 25 Aug 2022 22:11:10 +0100 Subject: [PATCH] LibJS: Accept and ignore calendar annotation in Instant strings This is a normative change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/3cd9669 --- .../LibJS/Runtime/Temporal/ISO8601.cpp | 3 ++- .../builtins/Temporal/Instant/Instant.from.js | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp index f6f1bc6fe9..125e406dec 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp @@ -1592,13 +1592,14 @@ bool ISO8601Parser::parse_duration() bool ISO8601Parser::parse_temporal_instant_string() { // TemporalInstantString : - // Date TimeSpecSeparator[opt] TimeZoneOffsetRequired + // Date TimeSpecSeparator[opt] TimeZoneOffsetRequired Calendar[opt] StateTransaction transaction { *this }; if (!parse_date()) return false; (void)parse_time_spec_separator(); if (!parse_time_zone_offset_required()) return false; + (void)parse_calendar(); transaction.commit(); return true; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js index 177dd000ab..99e9740e8d 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Instant/Instant.from.js @@ -23,6 +23,22 @@ describe("correct behavior", () => { Temporal.Instant.from("1975-02-02T14:25:36.123456789Z[Custom/TimeZone]") .epochNanoseconds ).toBe(160583136123456789n); + + // Accepts but ignores the calendar. + let result = null; + expect(() => { + result = Temporal.Instant.from("1970-01-01T00:00Z[u-ca=UTC]"); + }).not.toThrow(); + expect(result).toBeInstanceOf(Temporal.Instant); + expect(result.epochNanoseconds).toBe(0n); + + // Does not validate calendar name, it only checks that the calendar name matches the grammar. + result = null; + expect(() => { + result = Temporal.Instant.from("1970-01-01T00:00Z[u-ca=aAaAaAaA-bBbBbBb]"); + }).not.toThrow(); + expect(result).toBeInstanceOf(Temporal.Instant); + expect(result.epochNanoseconds).toBe(0n); }); }); @@ -48,4 +64,13 @@ describe("errors", () => { "Invalid epoch nanoseconds value, must be in range -86400 * 10^17 to 86400 * 10^17" ); }); + + test("calendar annotation must match calendar grammar even though it's ignored", () => { + expect(() => { + Temporal.Instant.from("1970-01-01T00:00Z[u-ca=SerenityOS]"); + }).toThrowWithMessage( + RangeError, + "Invalid instant string '1970-01-01T00:00Z[u-ca=SerenityOS]'" + ); + }); });