Skip to content

Commit 90be99f

Browse files
committed
[intl] Revert date formatting behavior change from ICU 72
Replace U+202F with U+0020 after formatting date. This lets websites continue to work without any changes. This matches Firefox behavior, according to https://bugzilla.mozilla.org/show_bug.cgi?id=1806042#c17. Bug: chromium:1414292, chromium:1401829, chromium:1392814 Change-Id: I7c2b58414d0890f8705e737f903403dc54e5fe57 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4237675 Commit-Queue: Adam Klein <[email protected]> Reviewed-by: Shu-yu Guo <[email protected]> Cr-Commit-Position: refs/heads/main@{#85757}
1 parent 7fd7835 commit 90be99f

11 files changed

Lines changed: 59 additions & 31 deletions

src/objects/js-date-time-format.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,11 @@ MaybeHandle<String> FormatDateTime(Isolate* isolate,
13951395
icu::UnicodeString result;
13961396
date_format.format(date_value, result);
13971397

1398+
// Revert ICU 72 change that introduced U+202F instead of U+0020
1399+
// to separate time from AM/PM. See https://crbug.com/1414292.
1400+
result = result.findAndReplace(icu::UnicodeString(0x202f),
1401+
icu::UnicodeString(0x20));
1402+
13981403
return Intl::ToString(isolate, result);
13991404
}
14001405

test/intl/date-format/date_style_time_style_hour_cycle.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ let noon = new Date(2019, 3, 4, 12);
88
let df_11_dt = new Intl.DateTimeFormat(
99
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h11"})
1010
assertEquals("h11", df_11_dt.resolvedOptions().hourCycle);
11-
assertEquals("4/4/19, 0:00\u202fAM", df_11_dt.format(midnight));
12-
assertEquals("4/4/19, 0:00\u202fPM", df_11_dt.format(noon));
11+
assertEquals("4/4/19, 0:00 AM", df_11_dt.format(midnight));
12+
assertEquals("4/4/19, 0:00 PM", df_11_dt.format(noon));
1313

1414
let df_12_dt = new Intl.DateTimeFormat(
1515
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h12"})
1616
assertEquals("h12", df_12_dt.resolvedOptions().hourCycle);
17-
assertEquals("4/4/19, 12:00\u202fAM", df_12_dt.format(midnight));
18-
assertEquals("4/4/19, 12:00\u202fPM", df_12_dt.format(noon));
17+
assertEquals("4/4/19, 12:00 AM", df_12_dt.format(midnight));
18+
assertEquals("4/4/19, 12:00 PM", df_12_dt.format(noon));
1919

2020
let df_23_dt = new Intl.DateTimeFormat(
2121
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h23"})

test/intl/date-format/format_range_hour_cycle.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,38 @@ let noon = new Date(2019, 3, 4, 12);
77
let df_11 = new Intl.DateTimeFormat(
88
"en", {hour: "numeric", minute: "numeric", hourCycle: "h11"})
99
assertEquals("h11", df_11.resolvedOptions().hourCycle);
10-
assertEquals("0:00\u202fAM", df_11.formatRange(midnight, midnight));
11-
assertEquals("0:00\u202fPM", df_11.formatRange(noon, noon));
10+
assertEquals("0:00 AM", df_11.formatRange(midnight, midnight));
11+
assertEquals("0:00 PM", df_11.formatRange(noon, noon));
1212

1313
let df_11_t = new Intl.DateTimeFormat(
1414
"en", {timeStyle: "short", hourCycle: "h11"})
1515
assertEquals("h11", df_11_t.resolvedOptions().hourCycle);
16-
assertEquals("0:00\u202fAM", df_11_t.formatRange(midnight, midnight));
17-
assertEquals("0:00\u202fPM", df_11_t.formatRange(noon, noon));
16+
assertEquals("0:00 AM", df_11_t.formatRange(midnight, midnight));
17+
assertEquals("0:00 PM", df_11_t.formatRange(noon, noon));
1818

1919
let df_11_dt = new Intl.DateTimeFormat(
2020
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h11"})
2121
assertEquals("h11", df_11_dt.resolvedOptions().hourCycle);
22-
assertEquals("4/4/19, 0:00\u202fAM", df_11_dt.formatRange(midnight, midnight));
23-
assertEquals("4/4/19, 0:00\u202fPM", df_11_dt.formatRange(noon, noon));
22+
assertEquals("4/4/19, 0:00 AM", df_11_dt.formatRange(midnight, midnight));
23+
assertEquals("4/4/19, 0:00 PM", df_11_dt.formatRange(noon, noon));
2424

2525
let df_12 = new Intl.DateTimeFormat(
2626
"en", {hour: "numeric", minute: "numeric", hourCycle: "h12"})
2727
assertEquals("h12", df_12.resolvedOptions().hourCycle);
28-
assertEquals("12:00\u202fAM", df_12.formatRange(midnight, midnight));
29-
assertEquals("12:00\u202fPM", df_12.formatRange(noon, noon));
28+
assertEquals("12:00 AM", df_12.formatRange(midnight, midnight));
29+
assertEquals("12:00 PM", df_12.formatRange(noon, noon));
3030

3131
let df_12_t = new Intl.DateTimeFormat(
3232
"en", {timeStyle: "short", hourCycle: "h12"})
3333
assertEquals("h12", df_12_t.resolvedOptions().hourCycle);
34-
assertEquals("12:00\u202fAM", df_12_t.formatRange(midnight, midnight));
35-
assertEquals("12:00\u202fPM", df_12_t.formatRange(noon, noon));
34+
assertEquals("12:00 AM", df_12_t.formatRange(midnight, midnight));
35+
assertEquals("12:00 PM", df_12_t.formatRange(noon, noon));
3636

3737
let df_12_dt = new Intl.DateTimeFormat(
3838
"en", {timeStyle: "short", dateStyle: "short", hourCycle: "h12"})
3939
assertEquals("h12", df_12_dt.resolvedOptions().hourCycle);
40-
assertEquals("4/4/19, 12:00\u202fAM", df_12_dt.formatRange(midnight, midnight));
41-
assertEquals("4/4/19, 12:00\u202fPM", df_12_dt.formatRange(noon, noon));
40+
assertEquals("4/4/19, 12:00 AM", df_12_dt.formatRange(midnight, midnight));
41+
assertEquals("4/4/19, 12:00 PM", df_12_dt.formatRange(noon, noon));
4242

4343
let df_23 = new Intl.DateTimeFormat(
4444
"en", {hour: "numeric", minute: "numeric", hourCycle: "h23"})

test/intl/date-format/hour_cycle.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ let noon = new Date(2019, 3, 4, 12);
77
let df_11 = new Intl.DateTimeFormat(
88
"en", {hour: "numeric", minute: "numeric", hourCycle: "h11"})
99
assertEquals("h11", df_11.resolvedOptions().hourCycle);
10-
assertEquals("0:00\u202fAM", df_11.format(midnight));
11-
assertEquals("0:00\u202fPM", df_11.format(noon));
10+
assertEquals("0:00 AM", df_11.format(midnight));
11+
assertEquals("0:00 PM", df_11.format(noon));
1212

1313
let df_12 = new Intl.DateTimeFormat(
1414
"en", {hour: "numeric", minute: "numeric", hourCycle: "h12"})
1515
assertEquals("h12", df_12.resolvedOptions().hourCycle);
16-
assertEquals("12:00\u202fAM", df_12.format(midnight));
17-
assertEquals("12:00\u202fPM", df_12.format(noon));
16+
assertEquals("12:00 AM", df_12.format(midnight));
17+
assertEquals("12:00 PM", df_12.format(noon));
1818

1919
let df_23 = new Intl.DateTimeFormat(
2020
"en", {hour: "numeric", minute: "numeric", hourCycle: "h23"})

test/intl/date-format/time_style_hour_cycle.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ let noon = new Date(2019, 3, 4, 12);
88
let df_11_t = new Intl.DateTimeFormat(
99
"en", {timeStyle: "short", hourCycle: "h11"})
1010
assertEquals("h11", df_11_t.resolvedOptions().hourCycle);
11-
assertEquals("0:00\u202fAM", df_11_t.format(midnight));
12-
assertEquals("0:00\u202fPM", df_11_t.format(noon));
11+
assertEquals("0:00 AM", df_11_t.format(midnight));
12+
assertEquals("0:00 PM", df_11_t.format(noon));
1313

1414
let df_12_t = new Intl.DateTimeFormat(
1515
"en", {timeStyle: "short", hourCycle: "h12"})
1616
assertEquals("h12", df_12_t.resolvedOptions().hourCycle);
17-
assertEquals("12:00\u202fAM", df_12_t.format(midnight));
18-
assertEquals("12:00\u202fPM", df_12_t.format(noon));
17+
assertEquals("12:00 AM", df_12_t.format(midnight));
18+
assertEquals("12:00 PM", df_12_t.format(noon));
1919

2020
let df_23_t = new Intl.DateTimeFormat(
2121
"en", {timeStyle: "short", hourCycle: "h23"})

test/intl/regress-1074578.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ const d1 = new Date("2020-05-25T00:00:00.000Z");
1818
const d2 = new Date("2020-05-31T00:00:00.000Z");
1919

2020
// Before tz2020a change will get "May 25, 2020 at 1:00:00 AM GMT+1"
21-
assertEquals("May 25, 2020 at 12:00:00\u202fAM GMT", df1.format(d1));
21+
assertEquals("May 25, 2020 at 12:00:00 AM GMT", df1.format(d1));
2222

2323
// Before tz2020a change will get "May 31, 2020 at 1:00:00 AM GMT+1"
24-
assertEquals("May 31, 2020 at 12:00:00\u202fAM GMT", df1.format(d2));
24+
assertEquals("May 31, 2020 at 12:00:00 AM GMT", df1.format(d2));
2525

2626
// B. Test Canada's Yukon advanced to -07 year-round on 2020-03-08.
2727
const df2 = new Intl.DateTimeFormat(
@@ -33,11 +33,11 @@ const d4 = new Date("2021-03-09T00:00Z");
3333
// Before tz2020a change will get "March 8, 2020 at 5:00:00 PM PDT"
3434
// In tz2020a it should be "March 8, 2020 at 5:00:00 PM MST"
3535
// but tz2020b roll this back.
36-
assertEquals("March 8, 2020 at 5:00:00\u202fPM PDT", df2.format(d3));
36+
assertEquals("March 8, 2020 at 5:00:00 PM PDT", df2.format(d3));
3737

3838
// Before tz2020a change will get "March 8, 2021 at 4:00:00 PM PST"
3939
// After tz2021a1 it now become "March 8, 2021 at 5:00:00 PM GMT-7".
40-
assertEquals("March 8, 2021 at 5:00:00\u202fPM GMT-7", df2.format(d4));
40+
assertEquals("March 8, 2021 at 5:00:00 PM GMT-7", df2.format(d4));
4141

4242
// C. Test America/Nuuk renamed from America/Godthab.
4343

test/intl/regress-527926.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ assertEquals("03:00", fmt.format(date));
1616

1717
fmt = new Intl.DateTimeFormat(
1818
'ru', {hour:'2-digit', minute: '2-digit', hour12: true});
19-
assertEquals("03:00\u202fAM", fmt.format(date));
19+
assertEquals("03:00 AM", fmt.format(date));

test/mjsunit/mjsunit.status

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,9 @@
524524

525525
# Non-BMP characters currently aren't considered identifiers in no_i18n
526526
'harmony/private-name-surrogate-pair': [PASS,FAIL],
527+
528+
# Tests ICU-specific behavior.
529+
'regress/regress-crbug-1414292': [SKIP],
527530
}], # 'no_i18n'
528531

529532
##############################################################################
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2023 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
const date = new Date("Wed Feb 15 2023 00:00:00 GMT+0100");
6+
const localeString = date.toLocaleString("en-US");
7+
// No narrow-width space should be found
8+
assertEquals(-1, localeString.search('\u202f'));
9+
// Regular space should match the character between time and AM/PM.
10+
assertMatches(/:\d\d:\d\d [AP]M$/, localeString);
11+
12+
const formatter = new Intl.DateTimeFormat('en', {timeStyle: "long"})
13+
const formattedString = formatter.format(date)
14+
// No narrow-width space should be found
15+
assertEquals(-1, formattedString.search('\u202f'));
16+
// Regular space should match the character between time and AM/PM.
17+
assertMatches(/:\d\d:\d\d [AP]M$/, localeString);

test/test262/test262.status

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,10 @@
11241124
'language/expressions/assignmenttargettype/direct-callexpression-arguments': [FAIL],
11251125
'language/expressions/assignmenttargettype/parenthesized-callexpression-arguments': [FAIL],
11261126

1127+
# We replace U+202F (narrow-width space) with U+0020 (regular space).
1128+
# https://crbug.com/1414292
1129+
'intl402/DateTimeFormat/prototype/format/timedatestyle-en': [FAIL],
1130+
11271131
############################ INVALID TESTS #############################
11281132

11291133
# Test makes unjustified assumptions about the number of calls to SortCompare.

0 commit comments

Comments
 (0)