mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-07 08:39:22 +00:00
LibUnicode: Cache all created icu::TimeZone objects
This cache works exactly the same as the existing icu::Locale cache.
This commit is contained in:
parent
6becd13a83
commit
d392c38a73
Notes:
github-actions[bot]
2024-09-03 17:26:56 +00:00
Author: https://github.com/trflynn89
Commit: d392c38a73
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1266
5 changed files with 45 additions and 7 deletions
|
@ -622,9 +622,9 @@ static void apply_time_zone_to_formatter(icu::SimpleDateFormat& formatter, icu::
|
||||||
{
|
{
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
|
||||||
auto* time_zone = icu::TimeZone::createTimeZone(icu_string(time_zone_identifier));
|
auto time_zone_data = TimeZoneData::for_time_zone(time_zone_identifier);
|
||||||
|
|
||||||
auto* calendar = icu::Calendar::createInstance(time_zone, locale, status);
|
auto* calendar = icu::Calendar::createInstance(time_zone_data->time_zone(), locale, status);
|
||||||
VERIFY(icu_success(status));
|
VERIFY(icu_success(status));
|
||||||
|
|
||||||
if (calendar->getDynamicClassID() == icu::GregorianCalendar::getStaticClassID()) {
|
if (calendar->getDynamicClassID() == icu::GregorianCalendar::getStaticClassID()) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
namespace Unicode {
|
namespace Unicode {
|
||||||
|
|
||||||
static HashMap<String, OwnPtr<LocaleData>> s_locale_cache;
|
static HashMap<String, OwnPtr<LocaleData>> s_locale_cache;
|
||||||
|
static HashMap<String, OwnPtr<TimeZoneData>> s_time_zone_cache;
|
||||||
|
|
||||||
Optional<LocaleData&> LocaleData::for_locale(StringView locale)
|
Optional<LocaleData&> LocaleData::for_locale(StringView locale)
|
||||||
{
|
{
|
||||||
|
@ -113,6 +114,30 @@ icu::TimeZoneNames& LocaleData::time_zone_names()
|
||||||
return *m_time_zone_names;
|
return *m_time_zone_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Optional<TimeZoneData&> TimeZoneData::for_time_zone(StringView time_zone)
|
||||||
|
{
|
||||||
|
auto time_zone_data = s_time_zone_cache.get(time_zone);
|
||||||
|
|
||||||
|
if (!time_zone_data.has_value()) {
|
||||||
|
time_zone_data = s_time_zone_cache.ensure(MUST(String::from_utf8(time_zone)), [&]() -> OwnPtr<TimeZoneData> {
|
||||||
|
auto icu_time_zone = adopt_own_if_nonnull(icu::TimeZone::createTimeZone(icu_string(time_zone)));
|
||||||
|
if (!icu_time_zone || *icu_time_zone == icu::TimeZone::getUnknown())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return adopt_own(*new TimeZoneData { icu_time_zone.release_nonnull() });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_zone_data.value())
|
||||||
|
return *time_zone_data.value();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeZoneData::TimeZoneData(NonnullOwnPtr<icu::TimeZone> time_zone)
|
||||||
|
: m_time_zone(move(time_zone))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Vector<icu::UnicodeString> icu_string_list(ReadonlySpan<String> strings)
|
Vector<icu::UnicodeString> icu_string_list(ReadonlySpan<String> strings)
|
||||||
{
|
{
|
||||||
Vector<icu::UnicodeString> result;
|
Vector<icu::UnicodeString> result;
|
||||||
|
|
|
@ -24,6 +24,7 @@ U_NAMESPACE_BEGIN
|
||||||
class DateTimePatternGenerator;
|
class DateTimePatternGenerator;
|
||||||
class LocaleDisplayNames;
|
class LocaleDisplayNames;
|
||||||
class NumberingSystem;
|
class NumberingSystem;
|
||||||
|
class TimeZone;
|
||||||
class TimeZoneNames;
|
class TimeZoneNames;
|
||||||
U_NAMESPACE_END
|
U_NAMESPACE_END
|
||||||
|
|
||||||
|
@ -63,6 +64,18 @@ private:
|
||||||
Optional<DigitalFormat> m_digital_format;
|
Optional<DigitalFormat> m_digital_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TimeZoneData {
|
||||||
|
public:
|
||||||
|
static Optional<TimeZoneData&> for_time_zone(StringView time_zone);
|
||||||
|
|
||||||
|
ALWAYS_INLINE icu::TimeZone& time_zone() { return *m_time_zone; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit TimeZoneData(NonnullOwnPtr<icu::TimeZone>);
|
||||||
|
|
||||||
|
NonnullOwnPtr<icu::TimeZone> m_time_zone;
|
||||||
|
};
|
||||||
|
|
||||||
constexpr bool icu_success(UErrorCode code)
|
constexpr bool icu_success(UErrorCode code)
|
||||||
{
|
{
|
||||||
return static_cast<bool>(U_SUCCESS(code));
|
return static_cast<bool>(U_SUCCESS(code));
|
||||||
|
|
|
@ -131,14 +131,14 @@ Optional<TimeZoneOffset> time_zone_offset(StringView time_zone, UnixDateTime tim
|
||||||
{
|
{
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
|
||||||
auto icu_time_zone = adopt_own_if_nonnull(icu::TimeZone::createTimeZone(icu_string(time_zone)));
|
auto time_zone_data = TimeZoneData::for_time_zone(time_zone);
|
||||||
if (!icu_time_zone || *icu_time_zone == icu::TimeZone::getUnknown())
|
if (!time_zone_data.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
i32 raw_offset = 0;
|
i32 raw_offset = 0;
|
||||||
i32 dst_offset = 0;
|
i32 dst_offset = 0;
|
||||||
|
|
||||||
icu_time_zone->getOffset(static_cast<UDate>(time.milliseconds_since_epoch()), 0, raw_offset, dst_offset, status);
|
time_zone_data->time_zone().getOffset(static_cast<UDate>(time.milliseconds_since_epoch()), 0, raw_offset, dst_offset, status);
|
||||||
if (icu_failure(status))
|
if (icu_failure(status))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Optional.h>
|
#include <AK/Optional.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Time.h>
|
#include <AK/Time.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Unicode {
|
namespace Unicode {
|
||||||
|
|
||||||
struct TimeZoneOffset {
|
struct TimeZoneOffset {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue