/* * Copyright (c) 2021-2024, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include namespace Unicode { enum class DateTimeStyle { Full, Long, Medium, Short, }; DateTimeStyle date_time_style_from_string(StringView); StringView date_time_style_to_string(DateTimeStyle); enum class Weekday { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, }; enum class HourCycle { H11, H12, H23, H24, }; HourCycle hour_cycle_from_string(StringView hour_cycle); StringView hour_cycle_to_string(HourCycle hour_cycle); Optional default_hour_cycle(StringView locale); enum class CalendarPatternStyle { Narrow, Short, Long, Numeric, TwoDigit, ShortOffset, LongOffset, ShortGeneric, LongGeneric, }; CalendarPatternStyle calendar_pattern_style_from_string(StringView style); StringView calendar_pattern_style_to_string(CalendarPatternStyle style); struct CalendarPattern { enum class Field { Era, Year, Month, Weekday, Day, DayPeriod, Hour, Minute, Second, FractionalSecondDigits, TimeZoneName, }; static CalendarPattern create_from_pattern(StringView); String to_pattern() const; template void for_each_calendar_field_zipped_with(CalendarPattern& other, ReadonlySpan filter, Callback&& callback) const { auto invoke_callback_for_field = [&](auto field) { switch (field) { case Field::Era: return callback(era, other.era); case Field::Year: return callback(year, other.year); case Field::Month: return callback(month, other.month); case Field::Weekday: return callback(weekday, other.weekday); case Field::Day: return callback(day, other.day); case Field::DayPeriod: return callback(day_period, other.day_period); case Field::Hour: return callback(hour, other.hour); case Field::Minute: return callback(minute, other.minute); case Field::Second: return callback(second, other.second); case Field::FractionalSecondDigits: return callback(fractional_second_digits, other.fractional_second_digits); case Field::TimeZoneName: return callback(time_zone_name, other.time_zone_name); } VERIFY_NOT_REACHED(); }; for (auto field : filter) { if (invoke_callback_for_field(field) == IterationDecision::Break) break; } } Optional hour_cycle; Optional hour12; // https://unicode.org/reports/tr35/tr35-dates.html#Calendar_Fields Optional era; Optional year; Optional month; Optional weekday; Optional day; Optional day_period; Optional hour; Optional minute; Optional second; Optional fractional_second_digits; Optional time_zone_name; }; class DateTimeFormat { public: static NonnullOwnPtr create_for_date_and_time_style( StringView locale, StringView time_zone_identifier, Optional const& hour_cycle, Optional const& hour12, Optional const& date_style, Optional const& time_style); static NonnullOwnPtr create_for_pattern_options( StringView locale, StringView time_zone_identifier, CalendarPattern const&); virtual ~DateTimeFormat() = default; struct Partition { StringView type; String value; StringView source; }; virtual CalendarPattern const& chosen_pattern() const = 0; virtual String format(double) const = 0; virtual Vector format_to_parts(double) const = 0; virtual String format_range(double, double) const = 0; virtual Vector format_range_to_parts(double, double) const = 0; protected: DateTimeFormat() = default; }; struct WeekInfo { u8 minimal_days_in_first_week { 1 }; Optional first_day_of_week; Vector weekend_days; }; WeekInfo week_info_of_locale(StringView locale); }