Explorar o código

LibJS: Support IANA legacy names in the Temporal ISO 8601 grammar

This is a normative change in the Temporal spec.

See: https://github.com/tc39/proposal-temporal/commit/2419680
Linus Groh %!s(int64=3) %!d(string=hai) anos
pai
achega
6850f25840

+ 26 - 0
Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp

@@ -895,12 +895,37 @@ bool ISO8601Parser::parse_time_zone_iana_name_tail()
     return true;
 }
 
+// https://tc39.es/proposal-temporal/#prod-TimeZoneIANALegacyName
+bool ISO8601Parser::parse_time_zone_iana_legacy_name()
+{
+    // TimeZoneIANALegacyName :
+    //     Etc/GMT0
+    //     GMT0
+    //     GMT-0
+    //     GMT+0
+    //     EST5EDT
+    //     CST6CDT
+    //     MST7MDT
+    //     PST8PDT
+    return m_state.lexer.consume_specific("Etc/GMT0"sv)
+        || m_state.lexer.consume_specific("GMT0"sv)
+        || m_state.lexer.consume_specific("GMT-0"sv)
+        || m_state.lexer.consume_specific("GMT+0"sv)
+        || m_state.lexer.consume_specific("EST5EDT"sv)
+        || m_state.lexer.consume_specific("CST6CDT"sv)
+        || m_state.lexer.consume_specific("MST7MDT"sv)
+        || m_state.lexer.consume_specific("PST8PDT"sv);
+}
+
 // https://tc39.es/proposal-temporal/#prod-TimeZoneIANAName
 bool ISO8601Parser::parse_time_zone_iana_name()
 {
     // TimeZoneIANAName :
     //     Etc/GMT ASCIISign UnpaddedHour
     //     TimeZoneIANANameTail but not Etc/GMT ASCIISign UnpaddedHour
+    //     TimeZoneIANALegacyName
+    // NOTE: Reverse order here because `TimeZoneIANANameTail` can be a subset of `TimeZoneIANALegacyName`,
+    // so we'd not attempt to parse that but may not exhaust the input string.
     auto parse_etc_gmt_with_offset = [this] {
         StateTransaction transaction { *this };
         if (!m_state.lexer.consume_specific("Etc/GMT"sv))
@@ -913,6 +938,7 @@ bool ISO8601Parser::parse_time_zone_iana_name()
         return true;
     };
     return parse_etc_gmt_with_offset()
+        || parse_time_zone_iana_legacy_name()
         || parse_time_zone_iana_name_tail();
 }
 

+ 1 - 0
Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h

@@ -136,6 +136,7 @@ public:
     [[nodiscard]] bool parse_tz_char();
     [[nodiscard]] bool parse_time_zone_iana_component();
     [[nodiscard]] bool parse_time_zone_iana_name_tail();
+    [[nodiscard]] bool parse_time_zone_iana_legacy_name();
     [[nodiscard]] bool parse_time_zone_iana_name();
     [[nodiscard]] bool parse_time_zone_identifier();
     [[nodiscard]] bool parse_time_zone_bracketed_annotation();

+ 3 - 0
Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.from.js

@@ -18,6 +18,9 @@ describe("normal behavior", () => {
             ["GMT", "UTC"],
             ["Etc/UTC", "UTC"],
             ["Etc/GMT", "UTC"],
+            ["Etc/GMT0", "UTC"], // IANA legacy name
+            ["Etc/GMT+0", "UTC"], // IANA legacy name
+            ["Etc/GMT-0", "UTC"], // IANA legacy name
             ["Etc/GMT+6", "Etc/GMT+6"],
             ["Etc/GMT-6", "Etc/GMT-6"],
             ["Etc/GMT+12", "Etc/GMT+12"],