mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 09:51:57 -05:00
LibJS+LibUnicode: Generate missing patterns with fractionalSecondDigits
TR-35's Matching Skeleton algorithm dictates how user requests including fractional second digits should be handled when the CLDR format pattern does not include that field. When the format pattern contains {second}, but does not contain {fractionalSecondDigits}, generate a second pattern which appends "{decimal}{fractionalSecondDigits}" to the {second} field.
This commit is contained in:
parent
6ace4000bf
commit
9f7c727720
3 changed files with 46 additions and 7 deletions
|
@ -466,6 +466,13 @@ static void generate_missing_patterns(Calendar& calendar, Vector<CalendarPattern
|
||||||
return locale_data.unique_strings.ensure(move(new_pattern));
|
return locale_data.unique_strings.ensure(move(new_pattern));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto inject_fractional_second_digits = [&](auto format) {
|
||||||
|
auto pattern = locale_data.unique_strings.get(format);
|
||||||
|
|
||||||
|
auto new_pattern = pattern.replace("{second}"sv, "{second}{decimal}{fractionalSecondDigits}"sv);
|
||||||
|
return locale_data.unique_strings.ensure(move(new_pattern));
|
||||||
|
};
|
||||||
|
|
||||||
auto append_if_unique = [&](auto format) {
|
auto append_if_unique = [&](auto format) {
|
||||||
auto format_index = locale_data.unique_patterns.ensure(move(format));
|
auto format_index = locale_data.unique_patterns.ensure(move(format));
|
||||||
|
|
||||||
|
@ -473,11 +480,28 @@ static void generate_missing_patterns(Calendar& calendar, Vector<CalendarPattern
|
||||||
calendar.available_formats.append(format_index);
|
calendar.available_formats.append(format_index);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Vector<CalendarPattern> time_formats_with_fractional_second_digits;
|
||||||
|
|
||||||
for (auto const& format : date_formats)
|
for (auto const& format : date_formats)
|
||||||
append_if_unique(format);
|
append_if_unique(format);
|
||||||
for (auto const& format : time_formats)
|
for (auto const& format : time_formats) {
|
||||||
append_if_unique(format);
|
append_if_unique(format);
|
||||||
|
|
||||||
|
if (format.second.has_value() && !format.fractional_second_digits.has_value()) {
|
||||||
|
auto new_format = format;
|
||||||
|
new_format.fractional_second_digits = 2;
|
||||||
|
|
||||||
|
new_format.pattern_index = inject_fractional_second_digits(new_format.pattern_index);
|
||||||
|
if (new_format.pattern12_index != 0)
|
||||||
|
new_format.pattern12_index = inject_fractional_second_digits(new_format.pattern12_index);
|
||||||
|
|
||||||
|
time_formats_with_fractional_second_digits.append(new_format);
|
||||||
|
append_if_unique(move(new_format));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
time_formats.extend(move(time_formats_with_fractional_second_digits));
|
||||||
|
|
||||||
for (auto const& date_format : date_formats) {
|
for (auto const& date_format : date_formats) {
|
||||||
CalendarPatternIndexType date_time_format_index = 0;
|
CalendarPatternIndexType date_time_format_index = 0;
|
||||||
|
|
||||||
|
|
|
@ -659,9 +659,18 @@ Optional<Unicode::CalendarPattern> basic_format_matcher(Unicode::CalendarPattern
|
||||||
//
|
//
|
||||||
// Rather than generating an prohibitively large amount of nearly-duplicate patterns, which only
|
// Rather than generating an prohibitively large amount of nearly-duplicate patterns, which only
|
||||||
// differ by field length, we expand the field lengths here.
|
// differ by field length, we expand the field lengths here.
|
||||||
best_format->for_each_calendar_field_zipped_with(options, [](auto& best_format_field, auto const& option_field, auto) {
|
best_format->for_each_calendar_field_zipped_with(options, [&](auto& best_format_field, auto const& option_field, auto field_type) {
|
||||||
if (best_format_field.has_value() && option_field.has_value())
|
switch (field_type) {
|
||||||
best_format_field = option_field;
|
case Unicode::CalendarPattern::Field::FractionalSecondDigits:
|
||||||
|
if (best_format->second.has_value() && option_field.has_value())
|
||||||
|
best_format_field = option_field;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (best_format_field.has_value() && option_field.has_value())
|
||||||
|
best_format_field = option_field;
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 11. Return bestFormat.
|
// 11. Return bestFormat.
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
// NOTE: We cannot yet test the fractionalSecondDigits option. There aren't any patterns in the CLDR
|
|
||||||
// with this field ('S' in https://unicode.org/reports/tr35/tr35-dates.html#dfst-second). We
|
|
||||||
// will need to figure out how this field should be generated.
|
|
||||||
describe("correct behavior", () => {
|
describe("correct behavior", () => {
|
||||||
test("length is 0", () => {
|
test("length is 0", () => {
|
||||||
expect(Intl.DateTimeFormat.prototype.resolvedOptions).toHaveLength(0);
|
expect(Intl.DateTimeFormat.prototype.resolvedOptions).toHaveLength(0);
|
||||||
|
@ -179,6 +176,15 @@ describe("correct behavior", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("fractionalSecondDigits", () => {
|
||||||
|
[1, 2, 3].forEach(fractionalSecondDigits => {
|
||||||
|
const en = new Intl.DateTimeFormat("en", {
|
||||||
|
fractionalSecondDigits: fractionalSecondDigits,
|
||||||
|
});
|
||||||
|
expect(en.resolvedOptions().fractionalSecondDigits).toBe(fractionalSecondDigits);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test("timeZoneName", () => {
|
test("timeZoneName", () => {
|
||||||
["short", "long"].forEach(timeZoneName => {
|
["short", "long"].forEach(timeZoneName => {
|
||||||
const en = new Intl.DateTimeFormat("en", { timeZoneName: timeZoneName });
|
const en = new Intl.DateTimeFormat("en", { timeZoneName: timeZoneName });
|
||||||
|
|
Loading…
Add table
Reference in a new issue