From 9feac465dc39fdb284da2ce39dd7e29f133580c2 Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Mon, 19 Dec 2022 01:44:14 +0100 Subject: [PATCH] LibCore: Convert explicit timezone to local in `DateTime::parse` When we encounter an explicit timezone, we shift the time to UTC. Because we rely on `mktime`, we need to shift it to the local time before proceeding. If no explicit timezone is provided, local timezone is assumed. This fixes the "timezone-offset extension" LibJS test running on machines with a non-UTC timezone offset. Co-authored-by: Timothy Flynn --- Userland/Libraries/LibCore/DateTime.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Userland/Libraries/LibCore/DateTime.cpp b/Userland/Libraries/LibCore/DateTime.cpp index 25df6ca1cf..09e36addf2 100644 --- a/Userland/Libraries/LibCore/DateTime.cpp +++ b/Userland/Libraries/LibCore/DateTime.cpp @@ -283,6 +283,7 @@ Optional DateTime::parse(StringView format, DeprecatedString const& st struct tm tm = {}; auto parsing_failed = false; + auto tm_represents_utc_time = false; auto parse_number = [&] { if (string_pos >= string.length()) { @@ -487,6 +488,7 @@ Optional DateTime::parse(StringView format, DeprecatedString const& st break; } case 'z': { + tm_represents_utc_time = true; if (string[string_pos] == 'Z') { // UTC time string_pos++; @@ -538,6 +540,13 @@ Optional DateTime::parse(StringView format, DeprecatedString const& st return {}; } + // If an explicit timezone was present, the time in tm was shifted to UTC. + // Convert it to local time, since that is what `mktime` expects. + if (tm_represents_utc_time) { + auto utc_time = timegm(&tm); + localtime_r(&utc_time, &tm); + } + return DateTime::from_timestamp(mktime(&tm)); } }