mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 04:25:13 +00:00
LibTimeZone: Parse and generate DST rule links for each ZONE entry
Each ZONE entry contains a RULES segment with one of the following: * A DST rule name, which links the ZONE to a RULE entry holding the DST rules to apply. * A static offset to be applied to the STDOFF offset. This implicitly means that the time zone is in DST during that time frame. * A "-" string, meaning no offset is applied to the STDOFF offset, and the time zone is in standard time during that time frame.
This commit is contained in:
parent
0e58b04b5c
commit
9dd4602636
Notes:
sideshowbarker
2024-07-17 20:37:51 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/9dd46026360 Pull-request: https://github.com/SerenityOS/serenity/pull/12008 Reviewed-by: https://github.com/linusg ✅
1 changed files with 36 additions and 2 deletions
|
@ -33,6 +33,10 @@ struct DateTime {
|
|||
struct TimeZoneOffset {
|
||||
i64 offset { 0 };
|
||||
Optional<DateTime> until;
|
||||
|
||||
Optional<String> dst_rule;
|
||||
Optional<i32> dst_rule_index;
|
||||
i64 dst_offset { 0 };
|
||||
};
|
||||
|
||||
struct DaylightSavingsOffset {
|
||||
|
@ -76,10 +80,12 @@ struct AK::Formatter<TimeZoneOffset> : Formatter<FormatString> {
|
|||
ErrorOr<void> format(FormatBuilder& builder, TimeZoneOffset const& time_zone_offset)
|
||||
{
|
||||
return Formatter<FormatString>::format(builder,
|
||||
"{{ {}, {}, {} }}",
|
||||
"{{ {}, {}, {}, {}, {} }}",
|
||||
time_zone_offset.offset,
|
||||
time_zone_offset.until.value_or({}),
|
||||
time_zone_offset.until.has_value());
|
||||
time_zone_offset.until.has_value(),
|
||||
time_zone_offset.dst_rule_index.value_or(-1),
|
||||
time_zone_offset.dst_offset);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -158,6 +164,14 @@ static i64 parse_time_offset(StringView segment)
|
|||
return (hours * 3600) + sign * ((minutes * 60) + seconds);
|
||||
}
|
||||
|
||||
static void parse_dst_rule(StringView segment, TimeZoneOffset& time_zone)
|
||||
{
|
||||
if (segment.contains(':'))
|
||||
time_zone.dst_offset = parse_time_offset(segment);
|
||||
else if (segment != "-"sv)
|
||||
time_zone.dst_rule = segment;
|
||||
}
|
||||
|
||||
static Vector<TimeZoneOffset>& parse_zone(StringView zone_line, TimeZoneData& time_zone_data)
|
||||
{
|
||||
auto segments = zone_line.split_view_if([](char ch) { return (ch == '\t') || (ch == ' '); });
|
||||
|
@ -168,6 +182,7 @@ static Vector<TimeZoneOffset>& parse_zone(StringView zone_line, TimeZoneData& ti
|
|||
|
||||
TimeZoneOffset time_zone {};
|
||||
time_zone.offset = parse_time_offset(segments[2]);
|
||||
parse_dst_rule(segments[3], time_zone);
|
||||
|
||||
if (segments.size() > 5)
|
||||
time_zone.until = parse_date_time(segments.span().slice(5));
|
||||
|
@ -188,6 +203,7 @@ static void parse_zone_continuation(StringView zone_line, Vector<TimeZoneOffset>
|
|||
// STDOFF RULES FORMAT [UNTIL]
|
||||
TimeZoneOffset time_zone {};
|
||||
time_zone.offset = parse_time_offset(segments[0]);
|
||||
parse_dst_rule(segments[1], time_zone);
|
||||
|
||||
if (segments.size() > 3)
|
||||
time_zone.until = parse_date_time(segments.span().slice(3));
|
||||
|
@ -265,6 +281,19 @@ static ErrorOr<void> parse_time_zones(StringView time_zone_path, TimeZoneData& t
|
|||
return {};
|
||||
}
|
||||
|
||||
static void set_dst_rule_indices(TimeZoneData& time_zone_data)
|
||||
{
|
||||
for (auto& time_zone : time_zone_data.time_zones) {
|
||||
for (auto& time_zone_offset : time_zone.value) {
|
||||
if (!time_zone_offset.dst_rule.has_value())
|
||||
continue;
|
||||
|
||||
auto dst_rule_index = time_zone_data.dst_offset_names.find_first_index(*time_zone_offset.dst_rule);
|
||||
time_zone_offset.dst_rule_index = static_cast<i32>(dst_rule_index.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String format_identifier(StringView owner, String identifier)
|
||||
{
|
||||
constexpr auto gmt_time_zones = Array { "Etc/GMT"sv, "GMT"sv };
|
||||
|
@ -318,6 +347,8 @@ static void generate_time_zone_data_implementation(Core::File& file, TimeZoneDat
|
|||
StringBuilder builder;
|
||||
SourceGenerator generator { builder };
|
||||
|
||||
set_dst_rule_indices(time_zone_data);
|
||||
|
||||
generator.append(R"~~~(
|
||||
#include <AK/Array.h>
|
||||
#include <AK/BinarySearch.h>
|
||||
|
@ -355,6 +386,9 @@ struct TimeZoneOffset {
|
|||
|
||||
DateTime until {};
|
||||
bool has_until { false };
|
||||
|
||||
i32 dst_rule { -1 };
|
||||
i64 dst_offset { 0 };
|
||||
};
|
||||
|
||||
struct DaylightSavingsOffset {
|
||||
|
|
Loading…
Add table
Reference in a new issue