mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:38:11 +00:00
LibCore+LibTimeZone: Support time zone names in Core::DateTime::parse
LibCore currently cannot depend on LibTimeZone directly. All build-time code generators depend on LibCore, so there'd be a circular dependency: LibCore -> LibTimeZone -> GenerateTZData -> LibCore. So to support parsing time zone names and applying their offsets, add a couple of weakly-defined helper functions. These work similar to the way AK::String declares some methods that LibUnicode defines. Any user who wants to parse time zone names (from outside of LibCore itself) can link against LibTimeZone to receive full support.
This commit is contained in:
parent
fd0075083a
commit
350fdf1e43
7 changed files with 169 additions and 4 deletions
85
Tests/LibCore/TestLibCoreDateTime.cpp
Normal file
85
Tests/LibCore/TestLibCoreDateTime.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <LibCore/DateTime.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibTest/TestCase.h>
|
||||
#include <time.h>
|
||||
|
||||
class TimeZoneGuard {
|
||||
public:
|
||||
explicit TimeZoneGuard(StringView time_zone)
|
||||
{
|
||||
if (auto const* current_time_zone = getenv("TZ"))
|
||||
m_time_zone = MUST(String::from_utf8({ current_time_zone, strlen(current_time_zone) }));
|
||||
|
||||
update(time_zone);
|
||||
}
|
||||
|
||||
~TimeZoneGuard()
|
||||
{
|
||||
if (m_time_zone.has_value())
|
||||
TRY_OR_FAIL(Core::System::setenv("TZ"sv, *m_time_zone, true));
|
||||
else
|
||||
TRY_OR_FAIL(Core::System::unsetenv("TZ"sv));
|
||||
|
||||
tzset();
|
||||
}
|
||||
|
||||
void update(StringView time_zone)
|
||||
{
|
||||
TRY_OR_FAIL(Core::System::setenv("TZ"sv, time_zone, true));
|
||||
tzset();
|
||||
}
|
||||
|
||||
private:
|
||||
Optional<String> m_time_zone;
|
||||
};
|
||||
|
||||
TEST_CASE(parse_time_zone_name)
|
||||
{
|
||||
EXPECT(!Core::DateTime::parse("%Z"sv, ""sv).has_value());
|
||||
EXPECT(!Core::DateTime::parse("%Z"sv, "123"sv).has_value());
|
||||
EXPECT(!Core::DateTime::parse("%Z"sv, "notatimezone"sv).has_value());
|
||||
|
||||
auto test = [](auto format, auto time, u32 year, u32 month, u32 day, u32 hour, u32 minute) {
|
||||
auto result = Core::DateTime::parse(format, time);
|
||||
VERIFY(result.has_value());
|
||||
|
||||
EXPECT_EQ(year, result->year());
|
||||
EXPECT_EQ(month, result->month());
|
||||
EXPECT_EQ(day, result->day());
|
||||
EXPECT_EQ(hour, result->hour());
|
||||
EXPECT_EQ(minute, result->minute());
|
||||
};
|
||||
|
||||
TimeZoneGuard guard { "UTC"sv };
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 UTC"sv, 2023, 01, 23, 10, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 America/New_York"sv, 2023, 01, 23, 15, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 Europe/Paris"sv, 2023, 01, 23, 9, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 Australia/Perth"sv, 2023, 01, 23, 2, 50);
|
||||
|
||||
guard.update("America/New_York"sv);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 UTC"sv, 2023, 01, 23, 5, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 America/New_York"sv, 2023, 01, 23, 10, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 Europe/Paris"sv, 2023, 01, 23, 4, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 Australia/Perth"sv, 2023, 01, 22, 21, 50);
|
||||
|
||||
guard.update("Europe/Paris"sv);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 UTC"sv, 2023, 01, 23, 11, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 America/New_York"sv, 2023, 01, 23, 16, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 Europe/Paris"sv, 2023, 01, 23, 10, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 Australia/Perth"sv, 2023, 01, 23, 3, 50);
|
||||
|
||||
guard.update("Australia/Perth"sv);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 UTC"sv, 2023, 01, 23, 18, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 America/New_York"sv, 2023, 01, 23, 23, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 Europe/Paris"sv, 2023, 01, 23, 17, 50);
|
||||
test("%Y/%m/%d %R %Z"sv, "2023/01/23 10:50 Australia/Perth"sv, 2023, 01, 23, 10, 50);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue