ladybird/Libraries/LibUnicode/DateTimeFormat.h
Andreas Kling b6bef6b688 Libraries: Use UTF-16 for JS-visible runtime strings
Produce JS-visible string results as UTF-16 at their source, including
numeric formatting, BigInt and BigFraction formatting, URI encoding,
console formatting, parser errors, regular expression errors, Intl and
Temporal records, LibUnicode locale boundaries, and LibWeb bindings.

Handle fractional radix formatting through the UTF-16 builder view.
2026-06-22 19:51:25 +02:00

181 lines
4.8 KiB
C++

/*
* Copyright (c) 2021-2026, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/IterationDecision.h>
#include <AK/Optional.h>
#include <AK/String.h>
#include <AK/StringView.h>
#include <AK/Time.h>
#include <AK/Types.h>
#include <AK/Utf16String.h>
#include <AK/Utf16View.h>
#include <AK/Vector.h>
#include <LibUnicode/Forward.h>
namespace Unicode {
enum class DateTimeStyle {
Full,
Long,
Medium,
Short,
};
DateTimeStyle date_time_style_from_string(Utf16View);
Utf16String 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(Utf16View hour_cycle);
Utf16String hour_cycle_to_string(HourCycle hour_cycle);
Optional<HourCycle> default_hour_cycle(Utf16View locale);
enum class CalendarPatternStyle {
Narrow,
Short,
Long,
Numeric,
TwoDigit,
ShortOffset,
LongOffset,
ShortGeneric,
LongGeneric,
};
CalendarPatternStyle calendar_pattern_style_from_string(Utf16View style);
Utf16String 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(String);
String to_pattern() const;
template<typename Callback>
void for_each_calendar_field_zipped_with(CalendarPattern& other, ReadonlySpan<Field> 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<HourCycle> hour_cycle;
Optional<bool> hour12;
// https://unicode.org/reports/tr35/tr35-dates.html#Calendar_Fields
Optional<CalendarPatternStyle> era;
Optional<CalendarPatternStyle> year;
Optional<CalendarPatternStyle> month;
Optional<CalendarPatternStyle> weekday;
Optional<CalendarPatternStyle> day;
Optional<CalendarPatternStyle> day_period;
Optional<CalendarPatternStyle> hour;
Optional<CalendarPatternStyle> minute;
Optional<CalendarPatternStyle> second;
Optional<u8> fractional_second_digits;
Optional<CalendarPatternStyle> time_zone_name;
Optional<String> pattern;
};
class DateTimeFormat {
public:
static NonnullOwnPtr<DateTimeFormat> create_for_date_and_time_style(
StringView locale,
StringView time_zone_identifier,
Optional<HourCycle> const& hour_cycle,
Optional<bool> const& hour12,
Optional<DateTimeStyle> const& date_style,
Optional<DateTimeStyle> const& time_style);
static NonnullOwnPtr<DateTimeFormat> create_for_pattern_options(
StringView locale,
StringView time_zone_identifier,
CalendarPattern const&);
virtual ~DateTimeFormat() = default;
struct Partition {
Utf16String type;
Utf16String value;
Utf16String source;
};
virtual CalendarPattern const& chosen_pattern() const = 0;
virtual Utf16String format(double) const = 0;
virtual Vector<Partition> format_to_parts(double) const = 0;
virtual Utf16String format_range(double, double) const = 0;
virtual Vector<Partition> format_range_to_parts(double, double) const = 0;
protected:
DateTimeFormat() = default;
};
struct WeekInfo {
u8 minimal_days_in_first_week { 1 };
Optional<Weekday> first_day_of_week;
Vector<Weekday> weekend_days;
};
WeekInfo week_info_of_locale(Utf16View locale);
}