diff options
author | Linus Groh <mail@linusgroh.de> | 2022-03-30 18:36:16 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-03-31 17:09:10 +0100 |
commit | b020b8eea25471b371af2466ace2b80b8cd691ee (patch) | |
tree | 3ec0674105a8e58472ab948898ba2855be981d74 /Userland/Libraries/LibJS/Runtime/Temporal | |
parent | b5392f9e39d9bbf88fc84c3781baeb41ec28cf4a (diff) | |
download | serenity-b020b8eea25471b371af2466ace2b80b8cd691ee.zip |
LibJS: Handle Etc/GMT timezones properly in TimeZone{IANA,Bracketed}Name
This is a normative change in the Temporal spec.
See: https://github.com/tc39/proposal-temporal/commit/8c73780
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/Temporal')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp | 51 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h | 1 |
2 files changed, 44 insertions, 8 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp index f55e215686..cca5fb9370 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp @@ -75,6 +75,32 @@ bool ISO8601Parser::parse_sign() return true; } +// https://tc39.es/proposal-temporal/#prod-UnpaddedHour +bool ISO8601Parser::parse_unpadded_hour() +{ + // UnpaddedHour : + // DecimalDigit + // 1 DecimalDigit + // 20 + // 21 + // 22 + // 23 + StateTransaction transaction { *this }; + auto success = m_state.lexer.consume_specific("20"sv) + || m_state.lexer.consume_specific("21"sv) + || m_state.lexer.consume_specific("22"sv) + || m_state.lexer.consume_specific("23"sv); + if (!success) { + // This could be either of the first two productions. + if (m_state.lexer.consume_specific('1')) + (void)parse_decimal_digit(); + else if (!parse_decimal_digit()) + return false; + } + transaction.commit(); + return true; +} + // https://tc39.es/proposal-temporal/#prod-Hour bool ISO8601Parser::parse_hour() { @@ -900,10 +926,25 @@ bool ISO8601Parser::parse_time_zone_iana_name_tail() bool ISO8601Parser::parse_time_zone_iana_name() { // TimeZoneIANAName : - // TimeZoneIANANameTail + // Etc/GMT ASCIISign UnpaddedHour + // TimeZoneIANANameTail but not Etc/GMT ASCIISign UnpaddedHour + auto parse_etc_gmt_with_offset = [this] { + StateTransaction transaction { *this }; + if (!m_state.lexer.consume_specific("Etc/GMT"sv)) + return false; + if (!parse_ascii_sign()) + return false; + if (!parse_unpadded_hour()) + return false; + transaction.commit(); + return true; + }; StateTransaction transaction { *this }; - if (!parse_time_zone_iana_name_tail()) + if (parse_etc_gmt_with_offset()) { + // no-op. + } else if (!parse_time_zone_iana_name_tail()) { return false; + } m_state.parse_result.time_zone_iana_name = transaction.parsed_string_view(); transaction.commit(); return true; @@ -914,16 +955,10 @@ bool ISO8601Parser::parse_time_zone_bracketed_name() { // TimeZoneBracketedName : // TimeZoneIANAName - // Etc/GMT ASCIISign Hour // TimeZoneUTCOffsetName StateTransaction transaction { *this }; if (parse_time_zone_iana_name()) { // no-op. - } else if (m_state.lexer.consume_specific("Etc/GMT"sv)) { - if (!parse_ascii_sign()) - return false; - if (!parse_hour()) - return false; } else if (!parse_time_zone_utc_offset_name()) { return false; } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h index 5b631bac3d..81425f3d89 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h @@ -88,6 +88,7 @@ public: [[nodiscard]] bool parse_non_zero_digit(); [[nodiscard]] bool parse_ascii_sign(); [[nodiscard]] bool parse_sign(); + [[nodiscard]] bool parse_unpadded_hour(); [[nodiscard]] bool parse_hour(); [[nodiscard]] bool parse_minute_second(); [[nodiscard]] bool parse_decimal_separator(); |