LibJS+LibUnicode: Port Intl.DateTimeFormat to UTF-16 strings

This commit is contained in:
Timothy Flynn 2025-07-23 14:24:25 -04:00 committed by Andreas Kling
commit ee01f857d1
Notes: github-actions[bot] 2025-07-24 08:41:42 +00:00
6 changed files with 26 additions and 18 deletions

View file

@ -119,11 +119,11 @@ ThrowCompletionOr<Vector<Unicode::DateTimeFormat::Partition>> partition_date_tim
// 11.5.7 FormatDateTime ( dateTimeFormat, x ), https://tc39.es/ecma402/#sec-formatdatetime
// 15.9.6 FormatDateTime ( dateTimeFormat, x ), https://tc39.es/proposal-temporal/#sec-formatdatetime
ThrowCompletionOr<String> format_date_time(VM& vm, DateTimeFormat& date_time_format, FormattableDateTime const& time)
ThrowCompletionOr<Utf16String> format_date_time(VM& vm, DateTimeFormat& date_time_format, FormattableDateTime const& time)
{
// 1. Let parts be ? PartitionDateTimePattern(dateTimeFormat, x).
// 2. Let result be the empty String.
String result;
Utf16String result;
// NOTE: We short-circuit PartitionDateTimePattern as we do not need individual partitions.
{
@ -196,11 +196,11 @@ ThrowCompletionOr<Vector<Unicode::DateTimeFormat::Partition>> partition_date_tim
// 11.5.10 FormatDateTimeRange ( dateTimeFormat, x, y ), https://tc39.es/ecma402/#sec-formatdatetimerange
// 15.9.9 FormatDateTimeRange ( dateTimeFormat, x, y ), https://tc39.es/proposal-temporal/#sec-formatdatetimerange
ThrowCompletionOr<String> format_date_time_range(VM& vm, DateTimeFormat& date_time_format, FormattableDateTime const& start, FormattableDateTime const& end)
ThrowCompletionOr<Utf16String> format_date_time_range(VM& vm, DateTimeFormat& date_time_format, FormattableDateTime const& start, FormattableDateTime const& end)
{
// 1. Let parts be ? PartitionDateTimeRangePattern(dateTimeFormat, x, y).
// 2. Let result be the empty String.
String result;
Utf16String result;
// NOTE: We short-circuit PartitionDateTimeRangePattern as we do not need individual partitions.
{

View file

@ -137,10 +137,10 @@ struct ValueFormat {
Vector<Unicode::DateTimeFormat::Partition> format_date_time_pattern(ValueFormat const&);
ThrowCompletionOr<Vector<Unicode::DateTimeFormat::Partition>> partition_date_time_pattern(VM&, DateTimeFormat&, FormattableDateTime const&);
ThrowCompletionOr<String> format_date_time(VM&, DateTimeFormat&, FormattableDateTime const&);
ThrowCompletionOr<Utf16String> format_date_time(VM&, DateTimeFormat&, FormattableDateTime const&);
ThrowCompletionOr<GC::Ref<Array>> format_date_time_to_parts(VM&, DateTimeFormat&, FormattableDateTime const&);
ThrowCompletionOr<Vector<Unicode::DateTimeFormat::Partition>> partition_date_time_range_pattern(VM&, DateTimeFormat&, FormattableDateTime const& start, FormattableDateTime const& end);
ThrowCompletionOr<String> format_date_time_range(VM&, DateTimeFormat&, FormattableDateTime const& start, FormattableDateTime const& end);
ThrowCompletionOr<Utf16String> format_date_time_range(VM&, DateTimeFormat&, FormattableDateTime const& start, FormattableDateTime const& end);
ThrowCompletionOr<GC::Ref<Array>> format_date_time_range_to_parts(VM&, DateTimeFormat&, FormattableDateTime const& start, FormattableDateTime const& end);
Optional<Unicode::CalendarPattern> get_date_time_format(Unicode::CalendarPattern const& options, OptionRequired, OptionDefaults, OptionInherit);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -672,13 +672,13 @@ public:
virtual CalendarPattern const& chosen_pattern() const override { return m_pattern; }
virtual String format(double time) const override
virtual Utf16String format(double time) const override
{
auto formatted_time = format_impl(time);
if (!formatted_time.has_value())
return {};
return icu_string_to_string(*formatted_time);
return icu_string_to_utf16_string(*formatted_time);
}
virtual Vector<Partition> format_to_parts(double time) const override
@ -694,7 +694,7 @@ public:
auto create_partition = [&](i32 field, i32 begin, i32 end) {
Partition partition;
partition.type = icu_date_time_format_field_to_string(field);
partition.value = icu_string_to_string(formatted_time->tempSubStringBetween(begin, end));
partition.value = icu_string_to_utf16_string(formatted_time->tempSubStringBetween(begin, end));
partition.source = "shared"sv;
result.append(move(partition));
};
@ -717,7 +717,7 @@ public:
return result;
}
virtual String format_range(double start, double end) const override
virtual Utf16String format_range(double start, double end) const override
{
UErrorCode status = U_ZERO_ERROR;
@ -733,7 +733,7 @@ public:
return {};
normalize_spaces(formatted_time);
return icu_string_to_string(formatted_time);
return icu_string_to_utf16_string(formatted_time);
}
virtual Vector<Partition> format_range_to_parts(double start, double end) const override
@ -763,7 +763,7 @@ public:
auto create_partition = [&](i32 field, i32 begin, i32 end) {
Partition partition;
partition.type = icu_date_time_format_field_to_string(field);
partition.value = icu_string_to_string(formatted_time.tempSubStringBetween(begin, end));
partition.value = icu_string_to_utf16_string(formatted_time.tempSubStringBetween(begin, end));
if (start_range.has_value() && start_range->contains(begin))
partition.source = "startRange"sv;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, Tim Flynn <trflynn89@serenityos.org>
* Copyright (c) 2021-2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -8,10 +8,10 @@
#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/Vector.h>
#include <LibUnicode/Forward.h>
@ -151,16 +151,16 @@ public:
struct Partition {
StringView type;
String value;
Utf16String value;
StringView source;
};
virtual CalendarPattern const& chosen_pattern() const = 0;
virtual String format(double) const = 0;
virtual Utf16String format(double) const = 0;
virtual Vector<Partition> format_to_parts(double) const = 0;
virtual String format_range(double, double) const = 0;
virtual Utf16String format_range(double, double) const = 0;
virtual Vector<Partition> format_range_to_parts(double, double) const = 0;
protected:

View file

@ -162,6 +162,11 @@ String icu_string_to_string(UChar const* string, i32 length)
return MUST(Utf16View { string, static_cast<size_t>(length) }.to_utf8());
}
Utf16String icu_string_to_utf16_string(icu::UnicodeString const& string)
{
return Utf16String::from_utf16_without_validation({ string.getBuffer(), static_cast<size_t>(string.length()) });
}
UCharIterator icu_string_iterator(Utf16View const& string)
{
UCharIterator iterator;

View file

@ -10,6 +10,7 @@
#include <AK/OwnPtr.h>
#include <AK/String.h>
#include <AK/StringView.h>
#include <AK/Utf16String.h>
#include <AK/Vector.h>
#include <LibUnicode/DurationFormat.h>
@ -103,6 +104,8 @@ Vector<icu::UnicodeString> icu_string_list(ReadonlySpan<String> strings);
String icu_string_to_string(icu::UnicodeString const& string);
String icu_string_to_string(UChar const*, i32 length);
Utf16String icu_string_to_utf16_string(icu::UnicodeString const& string);
UCharIterator icu_string_iterator(Utf16View const&);
template<typename Filter>