diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-01-24 11:19:35 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-01-25 18:39:36 +0000 |
commit | fc0c88344b04c7b1a849f1f1e0fe63558112db7b (patch) | |
tree | 6a33b9fdcb5a0ca6c3164fa635aaf100fed3b66e /Meta | |
parent | ef0155932b41bd18f2a689fd758d458c40f2b25c (diff) | |
download | serenity-fc0c88344b04c7b1a849f1f1e0fe63558112db7b.zip |
LibTimeZone: Slightly refactor the generated DST rule finding method
This just splits up the method to find the active DST rule for specified
time and time zone. This is to allow re-using the now split-off function
in upcoming commits.
Diffstat (limited to 'Meta')
-rw-r--r-- | Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp b/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp index 7e89bd46ff..47bf85b275 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp @@ -427,6 +427,14 @@ struct TimeZoneOffset { }; struct DaylightSavingsOffset { + AK::Time time_in_effect(AK::Time time) const + { + auto in_effect = this->in_effect; + in_effect.year = seconds_since_epoch_to_year(time.to_seconds()); + + return in_effect.time_since_epoch(); + } + i64 offset { 0 }; u16 year_from { 0 }; u16 year_to { 0 }; @@ -489,25 +497,18 @@ static constexpr Array<@type@, @size@> @name@ { { append_string_conversions("DaylightSavingsRule"sv, "daylight_savings_rule"sv, time_zone_data.dst_offset_names); generator.append(R"~~~( -static Offset get_dst_offset(TimeZoneOffset const& time_zone_offset, AK::Time time) +static Array<DaylightSavingsOffset const*, 2> find_dst_offsets(TimeZoneOffset const& time_zone_offset, AK::Time time) { auto const& dst_rules = s_dst_offsets[time_zone_offset.dst_rule]; DaylightSavingsOffset const* standard_offset = nullptr; DaylightSavingsOffset const* daylight_offset = nullptr; - auto time_in_effect_for_rule = [&](auto const& dst_rule) { - auto in_effect = dst_rule.in_effect; - in_effect.year = seconds_since_epoch_to_year(time.to_seconds()); - - return in_effect.time_since_epoch(); - }; - auto preferred_rule = [&](auto* current_offset, auto& new_offset) { if (!current_offset) return &new_offset; - auto new_time_in_effect = time_in_effect_for_rule(new_offset); + auto new_time_in_effect = new_offset.time_in_effect(time); return (time >= new_time_in_effect) ? &new_offset : current_offset; }; @@ -525,18 +526,31 @@ static Offset get_dst_offset(TimeZoneOffset const& time_zone_offset, AK::Time ti daylight_offset = preferred_rule(daylight_offset, dst_rule); } - if (!standard_offset || !daylight_offset) - return {}; + // In modern times, there will always be a standard rule in the TZDB, but that isn't true in + // all time zones in or before the early 1900s. For example, the "US" rules begin in 1918. + if (!standard_offset) { + static DaylightSavingsOffset const empty_offset {}; + return { &empty_offset, &empty_offset }; + } + + return { standard_offset, daylight_offset ? daylight_offset : standard_offset }; +} + +static Offset get_active_dst_offset(TimeZoneOffset const& time_zone_offset, AK::Time time) +{ + auto offsets = find_dst_offsets(time_zone_offset, time); + if (offsets[0] == offsets[1]) + return { offsets[0]->offset, InDST::No }; - auto standard_time_in_effect = time_in_effect_for_rule(*standard_offset); - auto daylight_time_in_effect = time_in_effect_for_rule(*daylight_offset); + auto standard_time_in_effect = offsets[0]->time_in_effect(time); + auto daylight_time_in_effect = offsets[1]->time_in_effect(time); if ((time < daylight_time_in_effect) || (time >= standard_time_in_effect)) - return { standard_offset->offset, InDST::No }; - return { daylight_offset->offset, InDST::Yes }; + return { offsets[0]->offset, InDST::No }; + return { offsets[1]->offset, InDST::Yes }; } -Optional<Offset> get_time_zone_offset(TimeZone time_zone, AK::Time time) +static TimeZoneOffset const& find_time_zone_offset(TimeZone time_zone, AK::Time time) { auto const& time_zone_offsets = s_time_zone_offsets[to_underlying(time_zone)]; @@ -549,11 +563,16 @@ Optional<Offset> get_time_zone_offset(TimeZone time_zone, AK::Time time) } VERIFY(index < time_zone_offsets.size()); - auto const& time_zone_offset = time_zone_offsets[index]; + return time_zone_offsets[index]; +} + +Optional<Offset> get_time_zone_offset(TimeZone time_zone, AK::Time time) +{ + auto const& time_zone_offset = find_time_zone_offset(time_zone, time); Offset dst_offset {}; if (time_zone_offset.dst_rule != -1) { - dst_offset = get_dst_offset(time_zone_offset, time); + dst_offset = get_active_dst_offset(time_zone_offset, time); } else { auto in_dst = time_zone_offset.dst_offset == 0 ? InDST::No : InDST::Yes; dst_offset = { time_zone_offset.dst_offset, in_dst }; |