From c1a1370c2a4ee85bf9eb1ea7071550227777c877 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 11 Jan 2022 11:41:22 -0500 Subject: [PATCH] LibJS: Use new LibUnicode API to format time zone names --- .../LibJS/Runtime/Intl/DateTimeFormat.cpp | 2 +- .../LibJS/Runtime/Intl/DateTimeFormat.h | 6 ++++ .../DateTimeFormat.prototype.format.js | 29 ++++++++++++++----- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp index 846c45cfa5..63bd48aa86 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp +++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.cpp @@ -938,7 +938,7 @@ ThrowCompletionOr> format_date_time_pattern(GlobalObjec // The String value may also depend on the value of the [[InDST]] field of tm if f is "short", "long", "shortOffset", or "longOffset". // If the implementation does not have a localized representation of f, then use the String value of v itself. // FIXME: This should take [[InDST]] into account. - auto formatted_value = Unicode::get_time_zone_name(data_locale, value, style).value_or(value); + auto formatted_value = Unicode::format_time_zone(data_locale, value, style, local_time.time_since_epoch()); // iv. Append a new Record { [[Type]]: p, [[Value]]: fv } as the last element of the list result. result.append({ "timeZoneName"sv, move(formatted_value) }); diff --git a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h index a8dbc75ddb..518b6aebab 100644 --- a/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h +++ b/Userland/Libraries/LibJS/Runtime/Intl/DateTimeFormat.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -161,6 +162,11 @@ enum class OptionDefaults { // Table 5: Record returned by ToLocalTime, https://tc39.es/ecma402/#table-datetimeformat-tolocaltime-record struct LocalTime { + AK::Time time_since_epoch() const + { + return AK::Time::from_timestamp(year, month + 1, day + 1, hour, minute, second, millisecond); + } + int weekday { 0 }; // [[Weekday]] Unicode::Era era {}; // [[Era]] i32 year { 0 }; // [[Year]] diff --git a/Userland/Libraries/LibJS/Tests/builtins/Intl/DateTimeFormat/DateTimeFormat.prototype.format.js b/Userland/Libraries/LibJS/Tests/builtins/Intl/DateTimeFormat/DateTimeFormat.prototype.format.js index 91383b0331..da599067b1 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Intl/DateTimeFormat/DateTimeFormat.prototype.format.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Intl/DateTimeFormat/DateTimeFormat.prototype.format.js @@ -383,21 +383,34 @@ describe("fractionalSecondDigits", () => { describe("timeZoneName", () => { // prettier-ignore const data = [ - { timeZoneName: "short", en0: "12/7/2021, 5:40 PM UTC", en1: "1/23/1989, 7:08 AM UTC", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م UTC", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص UTC" }, - { timeZoneName: "long", en0: "12/7/2021, 5:40 PM Coordinated Universal Time", en1: "1/23/1989, 7:08 AM Coordinated Universal Time", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م التوقيت العالمي المنسق", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص التوقيت العالمي المنسق" }, - { timeZoneName: "shortOffset", en0: "12/7/2021, 5:40 PM GMT", en1: "1/23/1989, 7:08 AM GMT", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش" }, - { timeZoneName: "longOffset", en0: "12/7/2021, 5:40 PM GMT", en1: "1/23/1989, 7:08 AM GMT", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش" }, - { timeZoneName: "shortGeneric", en0: "12/7/2021, 5:40 PM GMT", en1: "1/23/1989, 7:08 AM GMT", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش" }, - { timeZoneName: "longGeneric", en0: "12/7/2021, 5:40 PM GMT", en1: "1/23/1989, 7:08 AM GMT", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش" }, + { timeZone: "UTC", timeZoneName: "short", en0: "12/7/2021, 5:40 PM UTC", en1: "1/23/1989, 7:08 AM UTC", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م UTC", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص UTC" }, + { timeZone: "UTC", timeZoneName: "long", en0: "12/7/2021, 5:40 PM Coordinated Universal Time", en1: "1/23/1989, 7:08 AM Coordinated Universal Time", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م التوقيت العالمي المنسق", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص التوقيت العالمي المنسق" }, + { timeZone: "UTC", timeZoneName: "shortOffset", en0: "12/7/2021, 5:40 PM GMT", en1: "1/23/1989, 7:08 AM GMT", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش" }, + { timeZone: "UTC", timeZoneName: "longOffset", en0: "12/7/2021, 5:40 PM GMT", en1: "1/23/1989, 7:08 AM GMT", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش" }, + { timeZone: "UTC", timeZoneName: "shortGeneric", en0: "12/7/2021, 5:40 PM GMT", en1: "1/23/1989, 7:08 AM GMT", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش" }, + { timeZone: "UTC", timeZoneName: "longGeneric", en0: "12/7/2021, 5:40 PM GMT", en1: "1/23/1989, 7:08 AM GMT", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش" }, + + // FIXME: The time stamps on the below cases are incorrect as they do not adjust the time based on the GMT offset. + // Update these once the LocalTZA AO is implemented and ToLocalTime uses it. + { timeZone: "America/New_York", timeZoneName: "shortOffset", en0: "12/7/2021, 5:40 PM GMT-5", en1: "1/23/1989, 7:08 AM GMT-5", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش-٥", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش-٥" }, + { timeZone: "America/New_York", timeZoneName: "longOffset", en0: "12/7/2021, 5:40 PM GMT-05:00", en1: "1/23/1989, 7:08 AM GMT-05:00", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش-٠٥:٠٠", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش-٠٥:٠٠" }, + { timeZone: "America/New_York", timeZoneName: "shortGeneric", en0: "12/7/2021, 5:40 PM ET", en1: "1/23/1989, 7:08 AM ET", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م غرينتش-٥", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص غرينتش-٥" }, + { timeZone: "America/New_York", timeZoneName: "longGeneric", en0: "12/7/2021, 5:40 PM Eastern Time", en1: "1/23/1989, 7:08 AM Eastern Time", ar0: "٧‏/١٢‏/٢٠٢١, ٥:٤٠ م التوقيت الشرقي لأمريكا الشمالية", ar1: "٢٣‏/١‏/١٩٨٩, ٧:٠٨ ص التوقيت الشرقي لأمريكا الشمالية" }, ]; test("all", () => { data.forEach(d => { - const en = new Intl.DateTimeFormat("en", { timeZoneName: d.timeZoneName }); + const en = new Intl.DateTimeFormat("en", { + timeZone: d.timeZone, + timeZoneName: d.timeZoneName, + }); expect(en.format(d0)).toBe(d.en0); expect(en.format(d1)).toBe(d.en1); - const ar = new Intl.DateTimeFormat("ar", { timeZoneName: d.timeZoneName }); + const ar = new Intl.DateTimeFormat("ar", { + timeZone: d.timeZone, + timeZoneName: d.timeZoneName, + }); expect(ar.format(d0)).toBe(d.ar0); expect(ar.format(d1)).toBe(d.ar1); });