mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 12:05:15 +00:00
LibTimeZone: Parse and generate a list of time zones used by region
The zone1970.tab file in the TZDB contains regional time zone data, some of which we already parse for the system time zone settings map. This parses the region names from that file and generates a list of time zones which are used in each of those regions.
This commit is contained in:
parent
f6aa6a480c
commit
fa005bd276
Notes:
sideshowbarker
2024-07-17 23:00:03 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/fa005bd276 Pull-request: https://github.com/SerenityOS/serenity/pull/14501 Reviewed-by: https://github.com/linusg ✅
4 changed files with 65 additions and 2 deletions
|
@ -18,8 +18,8 @@
|
|||
|
||||
namespace {
|
||||
|
||||
using StringIndexType = u8;
|
||||
constexpr auto s_string_index_type = "u8"sv;
|
||||
using StringIndexType = u16;
|
||||
constexpr auto s_string_index_type = "u16"sv;
|
||||
|
||||
struct DateTime {
|
||||
u16 year { 0 };
|
||||
|
@ -67,6 +67,9 @@ struct TimeZoneData {
|
|||
Vector<String> dst_offset_names;
|
||||
|
||||
HashMap<String, TimeZone::Location> time_zone_coordinates;
|
||||
|
||||
HashMap<String, Vector<StringIndexType>> time_zone_regions;
|
||||
Vector<String> time_zone_region_names;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -379,6 +382,7 @@ static ErrorOr<void> parse_time_zone_coordinates(Core::Stream::BufferedFile& fil
|
|||
continue;
|
||||
|
||||
auto segments = line.split_view('\t');
|
||||
auto regions = segments[0];
|
||||
auto coordinates = segments[1];
|
||||
auto zone = segments[2];
|
||||
|
||||
|
@ -389,6 +393,14 @@ static ErrorOr<void> parse_time_zone_coordinates(Core::Stream::BufferedFile& fil
|
|||
auto longitude = parse_coordinate(coordinates.substring_view(index));
|
||||
|
||||
time_zone_data.time_zone_coordinates.set(zone, { latitude, longitude });
|
||||
|
||||
regions.for_each_split_view(',', false, [&](auto region) {
|
||||
auto index = time_zone_data.unique_strings.ensure(zone);
|
||||
time_zone_data.time_zone_regions.ensure(region).append(index);
|
||||
|
||||
if (!time_zone_data.time_zone_region_names.contains_slow(region))
|
||||
time_zone_data.time_zone_region_names.append(region);
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -447,6 +459,7 @@ namespace TimeZone {
|
|||
|
||||
generate_enum(generator, format_identifier, "TimeZone"sv, {}, time_zone_data.time_zone_names, time_zone_data.time_zone_aliases);
|
||||
generate_enum(generator, format_identifier, "DaylightSavingsRule"sv, {}, time_zone_data.dst_offset_names);
|
||||
generate_enum(generator, format_identifier, "Region"sv, {}, time_zone_data.time_zone_region_names);
|
||||
|
||||
generator.append(R"~~~(
|
||||
}
|
||||
|
@ -556,6 +569,26 @@ static constexpr Array<@type@, @size@> @name@ { {
|
|||
append_offsets(name, "DaylightSavingsOffset"sv, dst_offsets);
|
||||
});
|
||||
|
||||
generate_mapping(generator, time_zone_data.time_zone_region_names, s_string_index_type, "s_regional_time_zones"sv, "s_regional_time_zones_{}", format_identifier,
|
||||
[&](auto const& name, auto const& value) {
|
||||
auto const& time_zones = time_zone_data.time_zone_regions.find(value)->value;
|
||||
|
||||
generator.set("name", name);
|
||||
generator.set("size", String::number(time_zones.size()));
|
||||
|
||||
generator.append(R"~~~(
|
||||
static constexpr Array<@string_index_type@, @size@> @name@ { {)~~~");
|
||||
|
||||
bool first = true;
|
||||
for (auto const& time_zone : time_zones) {
|
||||
generator.append(first ? " " : ", ");
|
||||
generator.append(String::number(time_zone));
|
||||
first = false;
|
||||
}
|
||||
|
||||
generator.append(" } };");
|
||||
});
|
||||
|
||||
generator.set("size", String::number(time_zone_data.time_zone_names.size()));
|
||||
generator.append(R"~~~(
|
||||
static constexpr Array<Location, @size@> s_time_zone_locations { {
|
||||
|
@ -590,6 +623,7 @@ static constexpr Array<Location, @size@> s_time_zone_locations { {
|
|||
|
||||
append_string_conversions("TimeZone"sv, "time_zone"sv, time_zone_data.time_zone_names, time_zone_data.time_zone_aliases);
|
||||
append_string_conversions("DaylightSavingsRule"sv, "daylight_savings_rule"sv, time_zone_data.dst_offset_names);
|
||||
append_string_conversions("Region"sv, "region"sv, time_zone_data.time_zone_region_names);
|
||||
|
||||
generator.append(R"~~~(
|
||||
static Array<DaylightSavingsOffset const*, 2> find_dst_offsets(TimeZoneOffset const& time_zone_offset, AK::Time time)
|
||||
|
@ -727,6 +761,25 @@ Optional<Location> get_time_zone_location(TimeZone time_zone)
|
|||
return location;
|
||||
return {};
|
||||
}
|
||||
|
||||
Vector<StringView> time_zones_in_region(StringView region)
|
||||
{
|
||||
auto region_value = region_from_string(region);
|
||||
if (!region_value.has_value())
|
||||
return {};
|
||||
|
||||
auto region_index = to_underlying(*region_value);
|
||||
|
||||
auto const& regional_time_zones = s_regional_time_zones[region_index];
|
||||
|
||||
Vector<StringView> time_zones;
|
||||
time_zones.ensure_capacity(regional_time_zones.size());
|
||||
|
||||
for (auto time_zone : regional_time_zones)
|
||||
time_zones.unchecked_append(s_string_list[time_zone]);
|
||||
|
||||
return time_zones;
|
||||
}
|
||||
)~~~");
|
||||
|
||||
generate_available_values(generator, "all_time_zones"sv, time_zone_data.time_zone_names);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
namespace TimeZone {
|
||||
|
||||
enum class DaylightSavingsRule : u8;
|
||||
enum class Region : u8;
|
||||
enum class TimeZone : u16;
|
||||
|
||||
}
|
||||
|
|
|
@ -192,4 +192,8 @@ Optional<Location> get_time_zone_location(StringView time_zone)
|
|||
return {};
|
||||
}
|
||||
|
||||
Optional<Region> __attribute__((weak)) region_from_string(StringView) { return {}; }
|
||||
StringView __attribute__((weak)) region_to_string(Region) { return {}; }
|
||||
Vector<StringView> __attribute__((weak)) time_zones_in_region(StringView) { return {}; }
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <AK/StringView.h>
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibTimeZone/Forward.h>
|
||||
|
||||
namespace TimeZone {
|
||||
|
@ -68,4 +69,8 @@ Optional<Array<NamedOffset, 2>> get_named_time_zone_offsets(StringView time_zone
|
|||
Optional<Location> get_time_zone_location(TimeZone time_zone);
|
||||
Optional<Location> get_time_zone_location(StringView time_zone);
|
||||
|
||||
Optional<Region> region_from_string(StringView region);
|
||||
StringView region_to_string(Region region);
|
||||
Vector<StringView> time_zones_in_region(StringView region);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue