summaryrefslogtreecommitdiff
path: root/Meta/Lagom
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-01-24 11:19:35 -0500
committerLinus Groh <mail@linusgroh.de>2022-01-25 18:39:36 +0000
commitfc0c88344b04c7b1a849f1f1e0fe63558112db7b (patch)
tree6a33b9fdcb5a0ca6c3164fa635aaf100fed3b66e /Meta/Lagom
parentef0155932b41bd18f2a689fd758d458c40f2b25c (diff)
downloadserenity-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/Lagom')
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibTimeZone/GenerateTimeZoneData.cpp55
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 };