mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-08 05:27:14 +09:00
LibJS+LibUnicode: Change time zones in a way that works on Windows
On Windows, ICU does not look at the TZ environment variable at all. So to support changing time zones in test-js, let's set ICU's default time zone directly. Note that we no longer deal with "null" time zone strings. We just cache whatever ICU thinks is the current time zone before attempting to change it, for which we never have a null result. Co-authored-by: Andrew Kaster <andrew@ladybird.org>
This commit is contained in:
parent
8d33a97630
commit
8ded0c65dc
Notes:
github-actions[bot]
2025-06-01 22:50:05 +00:00
Author: https://github.com/trflynn89
Commit: 8ded0c65dc
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4955
Reviewed-by: https://github.com/ADKaster ✅
4 changed files with 34 additions and 33 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -24,8 +24,8 @@ String current_time_zone()
|
|||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
auto time_zone = adopt_own_if_nonnull(icu::TimeZone::detectHostTimeZone());
|
||||
if (!time_zone)
|
||||
auto time_zone = adopt_own_if_nonnull(icu::TimeZone::createDefault());
|
||||
if (!time_zone || *time_zone == icu::TimeZone::getUnknown())
|
||||
return "UTC"_string;
|
||||
|
||||
icu::UnicodeString time_zone_id;
|
||||
|
@ -46,6 +46,18 @@ void clear_system_time_zone_cache()
|
|||
cached_system_time_zone.clear();
|
||||
}
|
||||
|
||||
ErrorOr<void> set_current_time_zone(StringView time_zone)
|
||||
{
|
||||
auto time_zone_data = TimeZoneData::for_time_zone(time_zone);
|
||||
if (!time_zone_data.has_value())
|
||||
return Error::from_string_literal("Unable to find the provided time zone");
|
||||
|
||||
icu::TimeZone::setDefault(time_zone_data->time_zone());
|
||||
clear_system_time_zone_cache();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Time.h>
|
||||
|
@ -24,6 +25,7 @@ struct TimeZoneOffset {
|
|||
};
|
||||
|
||||
String current_time_zone();
|
||||
ErrorOr<void> set_current_time_zone(StringView);
|
||||
void clear_system_time_zone_cache();
|
||||
Vector<String> const& available_time_zones();
|
||||
Vector<String> available_time_zones_in_region(StringView region);
|
||||
|
|
|
@ -6,14 +6,11 @@
|
|||
*/
|
||||
|
||||
#include <AK/Enumerate.h>
|
||||
#include <LibCore/Environment.h>
|
||||
#include <LibJS/Runtime/ArrayBuffer.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
#include <LibJS/Runtime/TypedArray.h>
|
||||
#include <LibTest/JavaScriptTestRunner.h>
|
||||
#include <LibUnicode/TimeZone.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
TEST_ROOT("Libraries/LibJS/Tests");
|
||||
|
||||
|
@ -111,23 +108,13 @@ TESTJS_GLOBAL_FUNCTION(detach_array_buffer, detachArrayBuffer)
|
|||
|
||||
TESTJS_GLOBAL_FUNCTION(set_time_zone, setTimeZone)
|
||||
{
|
||||
auto current_time_zone = JS::js_null();
|
||||
auto current_time_zone = JS::PrimitiveString::create(vm, Unicode::current_time_zone());
|
||||
auto time_zone = TRY(vm.argument(0).to_string(vm));
|
||||
|
||||
if (auto time_zone = Core::Environment::get("TZ"sv); time_zone.has_value())
|
||||
current_time_zone = JS::PrimitiveString::create(vm, *time_zone);
|
||||
|
||||
if (auto time_zone = vm.argument(0); time_zone.is_null()) {
|
||||
if (auto result = Core::Environment::unset("TZ"sv); result.is_error())
|
||||
return vm.throw_completion<JS::InternalError>(MUST(String::formatted("Could not unset time zone: {}", result.error())));
|
||||
} else {
|
||||
if (auto result = Core::Environment::set("TZ"sv, TRY(time_zone.to_string(vm)), Core::Environment::Overwrite::Yes); result.is_error())
|
||||
if (auto result = Unicode::set_current_time_zone(time_zone); result.is_error())
|
||||
return vm.throw_completion<JS::InternalError>(MUST(String::formatted("Could not set time zone: {}", result.error())));
|
||||
}
|
||||
|
||||
JS::clear_system_time_zone_cache();
|
||||
Unicode::clear_system_time_zone_cache();
|
||||
tzset();
|
||||
|
||||
return current_time_zone;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
* Copyright (c) 2024-2025, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -7,29 +7,25 @@
|
|||
#include <LibTest/TestCase.h>
|
||||
|
||||
#include <AK/StringView.h>
|
||||
#include <LibCore/Environment.h>
|
||||
#include <LibUnicode/TimeZone.h>
|
||||
|
||||
class TimeZoneGuard {
|
||||
public:
|
||||
explicit TimeZoneGuard(StringView time_zone)
|
||||
: m_time_zone(Core::Environment::get("TZ"sv))
|
||||
: m_time_zone(Unicode::current_time_zone())
|
||||
{
|
||||
MUST(Core::Environment::set("TZ"sv, time_zone, Core::Environment::Overwrite::Yes));
|
||||
Unicode::clear_system_time_zone_cache();
|
||||
(void)Unicode::set_current_time_zone(time_zone);
|
||||
}
|
||||
|
||||
~TimeZoneGuard()
|
||||
{
|
||||
if (m_time_zone.has_value())
|
||||
MUST(Core::Environment::set("TZ"sv, *m_time_zone, Core::Environment::Overwrite::Yes));
|
||||
else
|
||||
MUST(Core::Environment::unset("TZ"sv));
|
||||
Unicode::clear_system_time_zone_cache();
|
||||
MUST(Unicode::set_current_time_zone(m_time_zone));
|
||||
}
|
||||
|
||||
String const& time_zone() const { return m_time_zone; }
|
||||
|
||||
private:
|
||||
Optional<StringView> m_time_zone;
|
||||
String m_time_zone;
|
||||
};
|
||||
|
||||
TEST_CASE(current_time_zone)
|
||||
|
@ -38,9 +34,13 @@ TEST_CASE(current_time_zone)
|
|||
TimeZoneGuard guard { "America/New_York"sv };
|
||||
EXPECT_EQ(Unicode::current_time_zone(), "America/New_York"sv);
|
||||
}
|
||||
{
|
||||
TimeZoneGuard guard { "America/Los_Angeles"sv };
|
||||
EXPECT_EQ(Unicode::current_time_zone(), "America/Los_Angeles"sv);
|
||||
}
|
||||
{
|
||||
TimeZoneGuard guard { "ladybird"sv };
|
||||
EXPECT_EQ(Unicode::current_time_zone(), "UTC"sv);
|
||||
EXPECT_EQ(Unicode::current_time_zone(), guard.time_zone());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue