1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-09 09:34:57 +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:
Timothy Flynn 2025-06-01 08:22:19 -04:00 committed by Tim Flynn
parent 8d33a97630
commit 8ded0c65dc
Notes: github-actions[bot] 2025-06-01 22:50:05 +00:00
4 changed files with 34 additions and 33 deletions

View file

@ -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())
return vm.throw_completion<JS::InternalError>(MUST(String::formatted("Could not set time zone: {}", result.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;
}

View file

@ -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());
}
}