LibCore+LibJS+LibUnicode: Port retrieving available time zones to ICU

This required updating some LibJS spec steps to their latest versions,
as the data expected by the old steps does not quite match the APIs that
are available with the ICU. The new spec steps are much more aligned.
This commit is contained in:
Timothy Flynn 2024-06-25 11:06:08 -04:00 committed by Andreas Kling
commit 4fc0fba646
Notes: sideshowbarker 2024-07-17 18:06:52 +09:00
15 changed files with 259 additions and 103 deletions

View file

@ -6,11 +6,14 @@
#define AK_DONT_REPLACE_STD
#include <AK/Array.h>
#include <AK/NonnullOwnPtr.h>
#include <AK/QuickSort.h>
#include <LibUnicode/ICU.h>
#include <LibUnicode/TimeZone.h>
#include <unicode/timezone.h>
#include <unicode/ucal.h>
namespace Unicode {
@ -34,4 +37,76 @@ String current_time_zone()
return icu_string_to_string(time_zone_name);
}
// https://github.com/unicode-org/icu/blob/main/icu4c/source/tools/tzcode/icuzones
static constexpr bool is_legacy_non_iana_time_zone(StringView time_zone)
{
constexpr auto legacy_zones = to_array({
"ACT"sv,
"AET"sv,
"AGT"sv,
"ART"sv,
"AST"sv,
"BET"sv,
"BST"sv,
"Canada/East-Saskatchewan"sv,
"CAT"sv,
"CNT"sv,
"CST"sv,
"CTT"sv,
"EAT"sv,
"ECT"sv,
"IET"sv,
"IST"sv,
"JST"sv,
"MIT"sv,
"NET"sv,
"NST"sv,
"PLT"sv,
"PNT"sv,
"PRT"sv,
"PST"sv,
"SST"sv,
"US/Pacific-New"sv,
"VST"sv,
});
if (time_zone.starts_with("SystemV/"sv))
return true;
return legacy_zones.contains_slow(time_zone);
}
Vector<String> const& available_time_zones()
{
static auto time_zones = []() -> Vector<String> {
UErrorCode status = U_ZERO_ERROR;
auto time_zone_enumerator = adopt_own_if_nonnull(icu::TimeZone::createEnumeration(status));
if (icu_failure(status))
return { "UTC"_string };
auto time_zones = icu_string_enumeration_to_list(move(time_zone_enumerator), [](char const* zone) {
return !is_legacy_non_iana_time_zone({ zone, strlen(zone) });
});
quick_sort(time_zones);
return time_zones;
}();
return time_zones;
}
Optional<String> resolve_primary_time_zone(StringView time_zone)
{
UErrorCode status = U_ZERO_ERROR;
icu::UnicodeString iana_id;
icu::TimeZone::getIanaID(icu_string(time_zone), iana_id, status);
if (icu_failure(status))
return {};
return icu_string_to_string(iana_id);
}
}

View file

@ -4,12 +4,16 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Optional.h>
#include <AK/String.h>
#include <AK/Vector.h>
#pragma once
namespace Unicode {
String current_time_zone();
Vector<String> const& available_time_zones();
Optional<String> resolve_primary_time_zone(StringView time_zone);
}