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