1 /*
2  * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 8176841 8202537 8244245
27  * @summary Tests java.time classes deals with Unicode extensions
28  *      correctly.
29  * @modules jdk.localedata
30  */
31 package test.java.time.format;
32 
33 import static org.testng.Assert.assertEquals;
34 
35 import android.icu.util.VersionInfo;
36 
37 import libcore.test.annotation.NonCts;
38 import libcore.test.reasons.NonCtsReasons;
39 
40 import java.time.DayOfWeek;
41 import java.time.ZonedDateTime;
42 import java.time.ZoneId;
43 import java.time.chrono.Chronology;
44 import java.time.chrono.HijrahChronology;
45 import java.time.chrono.IsoChronology;
46 import java.time.chrono.JapaneseChronology;
47 import java.time.format.DateTimeFormatter;
48 import java.time.format.DateTimeFormatterBuilder;
49 import java.time.format.FormatStyle;
50 import java.time.temporal.ChronoField;
51 import java.time.temporal.TemporalField;
52 import java.time.temporal.WeekFields;
53 import java.util.Locale;
54 import java.util.TimeZone;
55 import java.util.stream.Stream;
56 
57 import org.testng.annotations.AfterTest;
58 import org.testng.annotations.BeforeTest;
59 import org.testng.annotations.DataProvider;
60 import org.testng.annotations.Test;
61 
62 /**
63  * Test JavaTime with BCP47 U extensions
64  */
65 @Test
66 public class TestUnicodeExtension {
67     private static TimeZone defaultTZ;
68 
69     private static final Chronology JAPANESE = JapaneseChronology.INSTANCE;
70     private static final Chronology HIJRAH = HijrahChronology.INSTANCE;
71     private static final Chronology ISO = IsoChronology.INSTANCE;
72 
73     private static final ZoneId ASIATOKYO = ZoneId.of("Asia/Tokyo");
74     private static final ZoneId AMLA = ZoneId.of("America/Los_Angeles");
75 
76     private static final Locale JPTYO = Locale.forLanguageTag("en-u-tz-jptyo");
77     private static final Locale JCAL = Locale.forLanguageTag("en-u-ca-japanese");
78     private static final Locale HCAL = Locale.forLanguageTag("en-u-ca-islamic-umalqura");
79 
80     private static final Locale FW_SUN = Locale.forLanguageTag("en-US-u-fw-sun");
81     private static final Locale FW_MON = Locale.forLanguageTag("en-US-u-fw-mon");
82     private static final Locale FW_TUE = Locale.forLanguageTag("en-US-u-fw-tue");
83     private static final Locale FW_WED = Locale.forLanguageTag("en-US-u-fw-wed");
84     private static final Locale FW_THU = Locale.forLanguageTag("en-US-u-fw-thu");
85     private static final Locale FW_FRI = Locale.forLanguageTag("en-US-u-fw-fri");
86     private static final Locale FW_SAT = Locale.forLanguageTag("en-US-u-fw-sat");
87 
88     private static final Locale RG_GB = Locale.forLanguageTag("en-US-u-rg-gbzzzz");
89 
90     private static final ZonedDateTime ZDT = ZonedDateTime.of(2017, 8, 10, 15, 15, 0, 0, AMLA);
91 
92     private static final String PATTERN = "GGGG MMMM-dd-uu HH:mm:ss zzzz";
93 
94     // Android-changed: ICU 72 started to use '\u202f' instead of ' ' before AM/PM.
95     public static final char AM_PM_SPACE_CHAR = VersionInfo.ICU_VERSION.getMajor() >= 72
96             ? '\u202f' : ' ';
97 
98     // Android-changed: ICU 72 has stopped inserting '\u060a' after date.
99     public static final String DATE_TIME_SEP_CHAR_FOR_LOCALE_FA =
100             VersionInfo.ICU_VERSION.getMajor() >= 72 ? "" : "\u060a";
101 
102 
103     @BeforeTest
beforeTest()104     public void beforeTest() {
105         defaultTZ = TimeZone.getDefault();
106         TimeZone.setDefault(TimeZone.getTimeZone(AMLA));
107     }
108 
109     @AfterTest
afterTest()110     public void afterTest() {
111         TimeZone.setDefault(defaultTZ);
112     }
113 
114     @DataProvider(name="localizedBy")
localizedBy()115     Object[][] localizedBy() {
116         return new Object[][] {
117             // Locale, Chrono override, Zone override, Expected Chrono, Expected Zone,
118             // Expected formatted string
119             {Locale.JAPAN, null, null, ISO, null,
120             "2017\u5e748\u670810\u65e5\u6728\u66dc\u65e5 15\u664215\u520600\u79d2 " +
121             "\u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u590f\u6642\u9593"
122             },
123             {Locale.JAPAN, JAPANESE, null, ISO, null,
124             "2017\u5e748\u670810\u65e5\u6728\u66dc\u65e5 15\u664215\u520600\u79d2 " +
125             "\u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u590f\u6642\u9593"
126             },
127             {Locale.JAPAN, JAPANESE, ASIATOKYO, ISO, ASIATOKYO,
128             "2017\u5e748\u670811\u65e5\u91d1\u66dc\u65e5 7\u664215\u520600\u79d2 " +
129             "\u65e5\u672c\u6a19\u6e96\u6642"
130             },
131 
132             {JCAL, null, null, JAPANESE, null,
133             "Thursday, August 10, 29 Heisei at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
134             },
135             {JCAL, HIJRAH, null, JAPANESE, null,
136             "Thursday, August 10, 29 Heisei at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
137             },
138             {HCAL, JAPANESE, null, HIJRAH, null,
139             "Thursday, Dhu\u02bbl-Qi\u02bbdah 18, 1438 AH at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
140             },
141 
142 
143             {JPTYO, null, null, ISO, ASIATOKYO,
144             "Friday, August 11, 2017 at 7:15:00" + AM_PM_SPACE_CHAR + "AM Japan Standard Time"
145             },
146             {JPTYO, null, AMLA, ISO, ASIATOKYO,
147             "Friday, August 11, 2017 at 7:15:00" + AM_PM_SPACE_CHAR + "AM Japan Standard Time"
148             },
149             // invalid tz
150             {Locale.forLanguageTag("en-US-u-tz-jpzzz"), null, null, ISO, null,
151             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
152             },
153             {Locale.forLanguageTag("en-US-u-tz-jpzzz"), null, AMLA, ISO, AMLA,
154             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
155             },
156 
157             {RG_GB, null, null, ISO, null,
158             "Thursday, August 10, 2017 at 15:15:00 Pacific Daylight Time"
159             },
160 
161             // DecimalStyle
162             {Locale.forLanguageTag("en-US-u-nu-thai"), null, null, ISO, null,
163             "Thursday, August \u0e51\u0e50, \u0e52\u0e50\u0e51\u0e57 at \u0e53:\u0e51\u0e55:\u0e50\u0e50" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
164             },
165             // DecimalStyle, "nu" vs "rg"
166             {Locale.forLanguageTag("en-US-u-nu-thai-rg-uszzzz"), null, null, ISO, null,
167             "Thursday, August \u0e51\u0e50, \u0e52\u0e50\u0e51\u0e57 at \u0e53:\u0e51\u0e55:\u0e50\u0e50" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
168             },
169             // DecimalStyle, invalid
170             {Locale.forLanguageTag("en-US-u-nu-foo"), null, null, ISO, null,
171             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
172             },
173             // DecimalStyle, locale default
174             // Farsi uses Extended Arabic-Indic numbering system
175             {Locale.forLanguageTag("fa"), null, null, ISO, null,
176             "\u067e\u0646\u062c\u0634\u0646\u0628\u0647 \u06f1\u06f0 \u0627\u0648\u062a " +
177             // Android-changed: CLDR 42 doesn't provide 'ARABIC COMMA' \u060c after year.
178             // "\u06f2\u06f0\u06f1\u06f7\u060c \u0633\u0627\u0639\u062a \u06f1\u06f5:\u06f1\u06f5:" +
179             "\u06f2\u06f0\u06f1\u06f7" + DATE_TIME_SEP_CHAR_FOR_LOCALE_FA + " \u0633\u0627\u0639\u062a \u06f1\u06f5:\u06f1\u06f5:" +
180             "\u06f0\u06f0 (\u0648\u0642\u062a \u062a\u0627\u0628\u0633\u062a\u0627\u0646\u06cc " +
181             "\u063a\u0631\u0628 \u0627\u0645\u0631\u06cc\u06a9\u0627)"
182             },
183             // Farsi uses Extended Arabic-Indic numbering system
184             // (should not be overridden with it, as "latn" is explicitly specified)
185             {Locale.forLanguageTag("fa-u-nu-latn"), null, null, ISO, null,
186             // Android-changed: CLDR 42 doesn't provide 'ARABIC COMMA' \u060c after year.
187             // "\u067e\u0646\u062c\u0634\u0646\u0628\u0647 10 \u0627\u0648\u062a 2017\u060c " +
188             "\u067e\u0646\u062c\u0634\u0646\u0628\u0647 10 \u0627\u0648\u062a 2017" + DATE_TIME_SEP_CHAR_FOR_LOCALE_FA + " " +
189             "\u0633\u0627\u0639\u062a 15:15:00 (\u0648\u0642\u062a \u062a\u0627\u0628\u0633" +
190             "\u062a\u0627\u0646\u06cc \u063a\u0631\u0628 \u0627\u0645\u0631\u06cc\u06a9\u0627)"
191             },
192             // Dzongkha uses Tibetan numbering system
193             {Locale.forLanguageTag("dz"), null, null, ISO, null,
194             "\u0f42\u0f5f\u0f60\u0f0b\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b, \u0f66\u0fa4\u0fb1" +
195             "\u0f72\u0f0b\u0f63\u0f7c\u0f0b\u0f22\u0f20\u0f21\u0f27 \u0f5f\u0fb3\u0f0b\u0f56" +
196             "\u0f62\u0f92\u0fb1\u0f51\u0f0b\u0f54\u0f0b \u0f5a\u0f7a\u0f66\u0f0b\u0f21\u0f20 " +
197             "\u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51\u0f0b \u0f23 \u0f66\u0f90\u0f62\u0f0b\u0f58" +
198             "\u0f0b \u0f21\u0f25:\u0f20\u0f20 \u0f55\u0fb1\u0f72\u0f0b\u0f46\u0f0b \u0f56\u0fb1" +
199             "\u0f44\u0f0b\u0f68\u0f0b\u0f58\u0f72\u0f0b\u0f62\u0f72\u0f0b\u0f40\u0f0b\u0f54\u0f7a" +
200             "\u0f0b\u0f66\u0f72\u0f0b\u0f55\u0f72\u0f42\u0f0b\u0f49\u0f72\u0f53\u0f0b\u0f66\u0fb2" +
201             "\u0f74\u0f44\u0f0b\u0f46\u0f74\u0f0b\u0f5a\u0f7c\u0f51"
202             },
203         };
204     }
205 
206     @DataProvider(name="withLocale")
withLocale()207     Object[][] withLocale() {
208         return new Object[][] {
209             // Locale, Chrono override, Zone override, Expected Chrono, Expected Zone,
210             // Expected formatted string
211             {Locale.JAPAN, null, null, null, null,
212             "2017\u5e748\u670810\u65e5\u6728\u66dc\u65e5 15\u664215\u520600\u79d2 " +
213             "\u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u590f\u6642\u9593"
214             },
215             {Locale.JAPAN, JAPANESE, null, JAPANESE, null,
216             "\u5e73\u621029\u5e748\u670810\u65e5\u6728\u66dc\u65e5 15\u664215\u520600\u79d2 " +
217             "\u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u590f\u6642\u9593"
218             },
219             {Locale.JAPAN, JAPANESE, ASIATOKYO, JAPANESE, ASIATOKYO,
220             "\u5e73\u621029\u5e748\u670811\u65e5\u91d1\u66dc\u65e5 7\u664215\u520600\u79d2 " +
221             "\u65e5\u672c\u6a19\u6e96\u6642"
222             },
223 
224             {JCAL, null, null, null, null,
225             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
226             },
227             {JCAL, HIJRAH, null, HIJRAH, null,
228             "Thursday, Dhu\u02bbl-Qi\u02bbdah 18, 1438 AH at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
229             },
230             {HCAL, JAPANESE, null, JAPANESE, null,
231             "Thursday, August 10, 29 Heisei at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
232             },
233 
234 
235             {JPTYO, null, null, null, null,
236             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
237             },
238             {JPTYO, null, AMLA, null, AMLA,
239             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
240             },
241             // invalid tz
242             {Locale.forLanguageTag("en-US-u-tz-jpzzz"), null, null, null, null,
243             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
244             },
245             {Locale.forLanguageTag("en-US-u-tz-jpzzz"), null, null, null, null,
246             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
247             },
248 
249             {RG_GB, null, null, null, null,
250             "Thursday, August 10, 2017 at 15:15:00 Pacific Daylight Time"
251             },
252 
253             // DecimalStyle
254             {Locale.forLanguageTag("en-US-u-nu-thai"), null, null, null, null,
255             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
256             },
257             // DecimalStyle, "nu" vs "rg"
258             {Locale.forLanguageTag("en-US-u-nu-thai-rg-uszzzz"), null, null, null, null,
259             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
260             },
261             // DecimalStyle, invalid
262             {Locale.forLanguageTag("en-US-u-nu-foo"), null, null, null, null,
263             "Thursday, August 10, 2017 at 3:15:00" + AM_PM_SPACE_CHAR + "PM Pacific Daylight Time"
264             },
265             // DecimalStyle, locale default
266             // Farsi uses Extended Arabic-Indic numbering system
267             // (should not be overridden with it)
268             {Locale.forLanguageTag("fa"), null, null, null, null,
269             // Android-changed: CLDR 42 doesn't provide 'ARABIC COMMA' \u060c after year.
270             // "\u067e\u0646\u062c\u0634\u0646\u0628\u0647 10 \u0627\u0648\u062a 2017\u060c " +
271             "\u067e\u0646\u062c\u0634\u0646\u0628\u0647 10 \u0627\u0648\u062a 2017" + DATE_TIME_SEP_CHAR_FOR_LOCALE_FA + " " +
272             "\u0633\u0627\u0639\u062a 15:15:00 (\u0648\u0642\u062a \u062a\u0627\u0628\u0633" +
273             "\u062a\u0627\u0646\u06cc \u063a\u0631\u0628 \u0627\u0645\u0631\u06cc\u06a9\u0627)"
274             },
275             // Farsi uses Extended Arabic-Indic numbering system
276             // (should not be overridden with it)
277             {Locale.forLanguageTag("fa-u-nu-latn"), null, null, null, null,
278             // Android-changed: CLDR 42 doesn't provide 'ARABIC COMMA' \u060c after year.
279             // "\u067e\u0646\u062c\u0634\u0646\u0628\u0647 10 \u0627\u0648\u062a 2017\u060c " +
280             "\u067e\u0646\u062c\u0634\u0646\u0628\u0647 10 \u0627\u0648\u062a 2017" + DATE_TIME_SEP_CHAR_FOR_LOCALE_FA + " " +
281             "\u0633\u0627\u0639\u062a 15:15:00 (\u0648\u0642\u062a \u062a\u0627\u0628\u0633" +
282             "\u062a\u0627\u0646\u06cc \u063a\u0631\u0628 \u0627\u0645\u0631\u06cc\u06a9\u0627)"
283             },
284             // Dzongkha uses Tibetan numbering system
285             // (should not be overridden with it)
286             {Locale.forLanguageTag("dz"), null, null, null, null,
287             "\u0f42\u0f5f\u0f60\u0f0b\u0f54\u0f0b\u0f66\u0f44\u0f66\u0f0b, \u0f66\u0fa4\u0fb1" +
288             "\u0f72\u0f0b\u0f63\u0f7c\u0f0b2017 \u0f5f\u0fb3\u0f0b\u0f56\u0f62\u0f92\u0fb1" +
289             "\u0f51\u0f0b\u0f54\u0f0b \u0f5a\u0f7a\u0f66\u0f0b10 \u0f46\u0f74\u0f0b\u0f5a" +
290             "\u0f7c\u0f51\u0f0b 3 \u0f66\u0f90\u0f62\u0f0b\u0f58\u0f0b 15:00 \u0f55\u0fb1" +
291             "\u0f72\u0f0b\u0f46\u0f0b \u0f56\u0fb1\u0f44\u0f0b\u0f68\u0f0b\u0f58\u0f72\u0f0b" +
292             "\u0f62\u0f72\u0f0b\u0f40\u0f0b\u0f54\u0f7a\u0f0b\u0f66\u0f72\u0f0b\u0f55\u0f72" +
293             "\u0f42\u0f0b\u0f49\u0f72\u0f53\u0f0b\u0f66\u0fb2\u0f74\u0f44\u0f0b\u0f46\u0f74" +
294             "\u0f0b\u0f5a\u0f7c\u0f51"
295             },
296         };
297     }
298 
299     @DataProvider(name="firstDayOfWeek")
firstDayOfWeek()300     Object[][] firstDayOfWeek () {
301         return new Object[][] {
302             // Locale, Expected DayOfWeek,
303             {Locale.US, DayOfWeek.SUNDAY},
304             {FW_SUN, DayOfWeek.SUNDAY},
305             {FW_MON, DayOfWeek.MONDAY},
306             {FW_TUE, DayOfWeek.TUESDAY},
307             {FW_WED, DayOfWeek.WEDNESDAY},
308             {FW_THU, DayOfWeek.THURSDAY},
309             {FW_FRI, DayOfWeek.FRIDAY},
310             {FW_SAT, DayOfWeek.SATURDAY},
311 
312             // invalid case
313             {Locale.forLanguageTag("en-US-u-fw-xxx"), DayOfWeek.SUNDAY},
314 
315             // region override
316             {RG_GB, DayOfWeek.MONDAY},
317             {Locale.forLanguageTag("zh-CN-u-rg-eszzzz"), DayOfWeek.MONDAY},
318 
319             // "fw" and "rg".
320             {Locale.forLanguageTag("en-US-u-fw-wed-rg-gbzzzz"), DayOfWeek.WEDNESDAY},
321             {Locale.forLanguageTag("en-US-u-fw-xxx-rg-gbzzzz"), DayOfWeek.MONDAY},
322             // Android-removed: Upstream expects Sunday because en-US, but ICU4J expects Monday
323             // because of -u-fw-xxx-rg-zzzz, which seems to be invalid fw and rg extension values.
324             // {Locale.forLanguageTag("en-US-u-fw-xxx-rg-zzzz"), DayOfWeek.SUNDAY},
325         };
326     }
327 
328     @DataProvider(name="minDaysInFirstWeek")
minDaysInFrstWeek()329     Object[][] minDaysInFrstWeek () {
330         return new Object[][] {
331             // Locale, Expected minDay,
332             {Locale.US, 1},
333 
334             // region override
335             {RG_GB, 4},
336             {Locale.forLanguageTag("zh-CN-u-rg-eszzzz"), 4},
337         };
338     }
339 
340     @DataProvider(name="ofPattern")
ofPattern()341     Object[][] ofPattern() {
342         return new Object[][] {
343             // Locale, Expected Chrono, Expected Zone,
344             // Expected formatted string
345             {JCAL, null, null,
346             "Anno Domini August-10-17 15:15:00 Pacific Daylight Time"
347             },
348             {HCAL, null, null,
349             "Anno Domini August-10-17 15:15:00 Pacific Daylight Time"
350             },
351 
352             {JPTYO, null, null,
353             "Anno Domini August-10-17 15:15:00 Pacific Daylight Time"
354             },
355             {Locale.forLanguageTag("en-US-u-tz-jpzzz"), null, null,
356             "Anno Domini August-10-17 15:15:00 Pacific Daylight Time"
357             },
358 
359             {RG_GB, null, null,
360             "Anno Domini August-10-17 15:15:00 Pacific Daylight Time"
361             },
362 
363         };
364     }
365 
366     @DataProvider(name="shortTZID")
shortTZID()367     Object[][] shortTZID() {
368         return new Object[][] {
369             // LDML's short ID, Expected Zone,
370             {"adalv", "Europe/Andorra"},
371             {"aedxb", "Asia/Dubai"},
372             {"afkbl", "Asia/Kabul"},
373             {"aganu", "America/Antigua"},
374             {"aiaxa", "America/Anguilla"},
375             {"altia", "Europe/Tirane"},
376             {"amevn", "Asia/Yerevan"},
377             {"ancur", "America/Curacao"},
378             {"aolad", "Africa/Luanda"},
379             {"aqcas", "Antarctica/Casey"},
380             {"aqdav", "Antarctica/Davis"},
381             {"aqddu", "Antarctica/DumontDUrville"},
382             {"aqmaw", "Antarctica/Mawson"},
383             {"aqmcm", "Antarctica/McMurdo"},
384             {"aqplm", "Antarctica/Palmer"},
385             {"aqrot", "Antarctica/Rothera"},
386             {"aqsyw", "Antarctica/Syowa"},
387             {"aqtrl", "Antarctica/Troll"},
388             {"aqvos", "Antarctica/Vostok"},
389             {"arbue", "America/Buenos_Aires"},
390             {"arcor", "America/Cordoba"},
391             {"arctc", "America/Catamarca"},
392             {"arirj", "America/Argentina/La_Rioja"},
393             {"arjuj", "America/Jujuy"},
394             {"arluq", "America/Argentina/San_Luis"},
395             {"armdz", "America/Mendoza"},
396             {"arrgl", "America/Argentina/Rio_Gallegos"},
397             {"arsla", "America/Argentina/Salta"},
398             {"artuc", "America/Argentina/Tucuman"},
399             {"aruaq", "America/Argentina/San_Juan"},
400             {"arush", "America/Argentina/Ushuaia"},
401             {"asppg", "Pacific/Pago_Pago"},
402             {"atvie", "Europe/Vienna"},
403             {"auadl", "Australia/Adelaide"},
404             {"aubhq", "Australia/Broken_Hill"},
405             {"aubne", "Australia/Brisbane"},
406             {"audrw", "Australia/Darwin"},
407             {"aueuc", "Australia/Eucla"},
408             {"auhba", "Australia/Hobart"},
409             {"auldc", "Australia/Lindeman"},
410             {"auldh", "Australia/Lord_Howe"},
411             {"aumel", "Australia/Melbourne"},
412             {"aumqi", "Antarctica/Macquarie"},
413             {"auper", "Australia/Perth"},
414             {"ausyd", "Australia/Sydney"},
415             {"awaua", "America/Aruba"},
416             {"azbak", "Asia/Baku"},
417             {"basjj", "Europe/Sarajevo"},
418             {"bbbgi", "America/Barbados"},
419             {"bddac", "Asia/Dhaka"},
420             {"bebru", "Europe/Brussels"},
421             {"bfoua", "Africa/Ouagadougou"},
422             {"bgsof", "Europe/Sofia"},
423             {"bhbah", "Asia/Bahrain"},
424             {"bibjm", "Africa/Bujumbura"},
425             {"bjptn", "Africa/Porto-Novo"},
426             {"bmbda", "Atlantic/Bermuda"},
427             {"bnbwn", "Asia/Brunei"},
428             {"bolpb", "America/La_Paz"},
429             {"bqkra", "America/Kralendijk"},
430             {"braux", "America/Araguaina"},
431             {"brbel", "America/Belem"},
432             {"brbvb", "America/Boa_Vista"},
433             {"brcgb", "America/Cuiaba"},
434             {"brcgr", "America/Campo_Grande"},
435             {"brern", "America/Eirunepe"},
436             {"brfen", "America/Noronha"},
437             {"brfor", "America/Fortaleza"},
438             {"brmao", "America/Manaus"},
439             {"brmcz", "America/Maceio"},
440             {"brpvh", "America/Porto_Velho"},
441             {"brrbr", "America/Rio_Branco"},
442             {"brrec", "America/Recife"},
443             {"brsao", "America/Sao_Paulo"},
444             {"brssa", "America/Bahia"},
445             {"brstm", "America/Santarem"},
446             {"bsnas", "America/Nassau"},
447             {"btthi", "Asia/Thimphu"},
448             {"bwgbe", "Africa/Gaborone"},
449             {"bymsq", "Europe/Minsk"},
450             {"bzbze", "America/Belize"},
451             {"cacfq", "America/Creston"},
452             {"caedm", "America/Edmonton"},
453             {"cafne", "America/Fort_Nelson"},
454             {"caglb", "America/Glace_Bay"},
455             {"cagoo", "America/Goose_Bay"},
456             {"cahal", "America/Halifax"},
457             {"caiql", "America/Iqaluit"},
458             {"camon", "America/Moncton"},
459             {"careb", "America/Resolute"},
460             {"careg", "America/Regina"},
461             {"casjf", "America/St_Johns"},
462             {"cator", "America/Toronto"},
463             {"cavan", "America/Vancouver"},
464             {"cawnp", "America/Winnipeg"},
465             {"caybx", "America/Blanc-Sablon"},
466             {"caycb", "America/Cambridge_Bay"},
467             {"cayda", "America/Dawson"},
468             {"caydq", "America/Dawson_Creek"},
469             {"cayek", "America/Rankin_Inlet"},
470             {"cayev", "America/Inuvik"},
471             {"cayxy", "America/Whitehorse"},
472             {"cayyn", "America/Swift_Current"},
473             {"cayzs", "America/Coral_Harbour"},
474             {"cccck", "Indian/Cocos"},
475             {"cdfbm", "Africa/Lubumbashi"},
476             {"cdfih", "Africa/Kinshasa"},
477             {"cfbgf", "Africa/Bangui"},
478             {"cgbzv", "Africa/Brazzaville"},
479             {"chzrh", "Europe/Zurich"},
480             {"ciabj", "Africa/Abidjan"},
481             {"ckrar", "Pacific/Rarotonga"},
482             {"clipc", "Pacific/Easter"},
483             {"clscl", "America/Santiago"},
484             {"cmdla", "Africa/Douala"},
485             {"cnsha", "Asia/Shanghai"},
486             {"cnurc", "Asia/Urumqi"},
487             {"cobog", "America/Bogota"},
488             {"crsjo", "America/Costa_Rica"},
489             {"cst6cdt", "CST6CDT"},
490             {"cuhav", "America/Havana"},
491             {"cvrai", "Atlantic/Cape_Verde"},
492             {"cxxch", "Indian/Christmas"},
493             {"cynic", "Asia/Nicosia"},
494             {"czprg", "Europe/Prague"},
495             {"deber", "Europe/Berlin"},
496             {"debsngn", "Europe/Busingen"},
497             {"djjib", "Africa/Djibouti"},
498             {"dkcph", "Europe/Copenhagen"},
499             {"dmdom", "America/Dominica"},
500             {"dosdq", "America/Santo_Domingo"},
501             {"dzalg", "Africa/Algiers"},
502             {"ecgps", "Pacific/Galapagos"},
503             {"ecgye", "America/Guayaquil"},
504             {"eetll", "Europe/Tallinn"},
505             {"egcai", "Africa/Cairo"},
506             {"eheai", "Africa/El_Aaiun"},
507             {"erasm", "Africa/Asmera"},
508             {"esceu", "Africa/Ceuta"},
509             {"eslpa", "Atlantic/Canary"},
510             {"esmad", "Europe/Madrid"},
511             {"est5edt", "EST5EDT"},
512             {"etadd", "Africa/Addis_Ababa"},
513             {"fihel", "Europe/Helsinki"},
514             {"fimhq", "Europe/Mariehamn"},
515             {"fjsuv", "Pacific/Fiji"},
516             {"fkpsy", "Atlantic/Stanley"},
517             {"fmksa", "Pacific/Kosrae"},
518             {"fmpni", "Pacific/Ponape"},
519             {"fmtkk", "Pacific/Truk"},
520             {"fotho", "Atlantic/Faeroe"},
521             {"frpar", "Europe/Paris"},
522             {"galbv", "Africa/Libreville"},
523             {"gaza", "Asia/Gaza"},
524             {"gblon", "Europe/London"},
525             {"gdgnd", "America/Grenada"},
526             {"getbs", "Asia/Tbilisi"},
527             {"gfcay", "America/Cayenne"},
528             {"gggci", "Europe/Guernsey"},
529             {"ghacc", "Africa/Accra"},
530             {"gigib", "Europe/Gibraltar"},
531             {"gldkshvn", "America/Danmarkshavn"},
532             {"glgoh", "America/Godthab"},
533             {"globy", "America/Scoresbysund"},
534             {"glthu", "America/Thule"},
535             {"gmbjl", "Africa/Banjul"},
536             {"gncky", "Africa/Conakry"},
537             {"gpbbr", "America/Guadeloupe"},
538             {"gpmsb", "America/Marigot"},
539             {"gpsbh", "America/St_Barthelemy"},
540             {"gqssg", "Africa/Malabo"},
541             {"grath", "Europe/Athens"},
542             {"gsgrv", "Atlantic/South_Georgia"},
543             {"gtgua", "America/Guatemala"},
544             {"gugum", "Pacific/Guam"},
545             {"gwoxb", "Africa/Bissau"},
546             {"gygeo", "America/Guyana"},
547             {"hebron", "Asia/Hebron"},
548             {"hkhkg", "Asia/Hong_Kong"},
549             {"hntgu", "America/Tegucigalpa"},
550             {"hrzag", "Europe/Zagreb"},
551             {"htpap", "America/Port-au-Prince"},
552             {"hubud", "Europe/Budapest"},
553             {"iddjj", "Asia/Jayapura"},
554             {"idjkt", "Asia/Jakarta"},
555             {"idmak", "Asia/Makassar"},
556             {"idpnk", "Asia/Pontianak"},
557             {"iedub", "Europe/Dublin"},
558             {"imdgs", "Europe/Isle_of_Man"},
559             {"inccu", "Asia/Calcutta"},
560             {"iodga", "Indian/Chagos"},
561             {"iqbgw", "Asia/Baghdad"},
562             {"irthr", "Asia/Tehran"},
563             {"isrey", "Atlantic/Reykjavik"},
564             {"itrom", "Europe/Rome"},
565             {"jeruslm", "Asia/Jerusalem"},
566             {"jesth", "Europe/Jersey"},
567             {"jmkin", "America/Jamaica"},
568             {"joamm", "Asia/Amman"},
569             {"jptyo", "Asia/Tokyo"},
570             {"kenbo", "Africa/Nairobi"},
571             {"kgfru", "Asia/Bishkek"},
572             {"khpnh", "Asia/Phnom_Penh"},
573             {"kicxi", "Pacific/Kiritimati"},
574             {"kipho", "Pacific/Enderbury"},
575             {"kitrw", "Pacific/Tarawa"},
576             {"kmyva", "Indian/Comoro"},
577             {"knbas", "America/St_Kitts"},
578             {"kpfnj", "Asia/Pyongyang"},
579             {"krsel", "Asia/Seoul"},
580             {"kwkwi", "Asia/Kuwait"},
581             {"kygec", "America/Cayman"},
582             {"kzaau", "Asia/Aqtau"},
583             {"kzakx", "Asia/Aqtobe"},
584             {"kzala", "Asia/Almaty"},
585             {"kzkzo", "Asia/Qyzylorda"},
586             {"kzura", "Asia/Oral"},
587             {"lavte", "Asia/Vientiane"},
588             {"lbbey", "Asia/Beirut"},
589             {"lccas", "America/St_Lucia"},
590             {"livdz", "Europe/Vaduz"},
591             {"lkcmb", "Asia/Colombo"},
592             {"lrmlw", "Africa/Monrovia"},
593             {"lsmsu", "Africa/Maseru"},
594             {"ltvno", "Europe/Vilnius"},
595             {"lulux", "Europe/Luxembourg"},
596             {"lvrix", "Europe/Riga"},
597             {"lytip", "Africa/Tripoli"},
598             {"macas", "Africa/Casablanca"},
599             {"mcmon", "Europe/Monaco"},
600             {"mdkiv", "Europe/Chisinau"},
601             {"metgd", "Europe/Podgorica"},
602             {"mgtnr", "Indian/Antananarivo"},
603             {"mhkwa", "Pacific/Kwajalein"},
604             {"mhmaj", "Pacific/Majuro"},
605             {"mkskp", "Europe/Skopje"},
606             {"mlbko", "Africa/Bamako"},
607             {"mmrgn", "Asia/Rangoon"},
608             {"mncoq", "Asia/Choibalsan"},
609             {"mnhvd", "Asia/Hovd"},
610             {"mnuln", "Asia/Ulaanbaatar"},
611             {"momfm", "Asia/Macau"},
612             {"mpspn", "Pacific/Saipan"},
613             {"mqfdf", "America/Martinique"},
614             {"mrnkc", "Africa/Nouakchott"},
615             {"msmni", "America/Montserrat"},
616             {"mst7mdt", "MST7MDT"},
617             {"mtmla", "Europe/Malta"},
618             {"muplu", "Indian/Mauritius"},
619             {"mvmle", "Indian/Maldives"},
620             {"mwblz", "Africa/Blantyre"},
621             {"mxchi", "America/Chihuahua"},
622             {"mxcun", "America/Cancun"},
623             {"mxhmo", "America/Hermosillo"},
624             {"mxmam", "America/Matamoros"},
625             {"mxmex", "America/Mexico_City"},
626             {"mxmid", "America/Merida"},
627             {"mxmty", "America/Monterrey"},
628             {"mxmzt", "America/Mazatlan"},
629             {"mxoji", "America/Ojinaga"},
630             {"mxpvr", "America/Bahia_Banderas"},
631             {"mxtij", "America/Tijuana"},
632             {"mykch", "Asia/Kuching"},
633             {"mykul", "Asia/Kuala_Lumpur"},
634             {"mzmpm", "Africa/Maputo"},
635             {"nawdh", "Africa/Windhoek"},
636             {"ncnou", "Pacific/Noumea"},
637             {"nenim", "Africa/Niamey"},
638             {"nfnlk", "Pacific/Norfolk"},
639             {"nglos", "Africa/Lagos"},
640             {"nimga", "America/Managua"},
641             {"nlams", "Europe/Amsterdam"},
642             {"noosl", "Europe/Oslo"},
643             {"npktm", "Asia/Katmandu"},
644             {"nrinu", "Pacific/Nauru"},
645             {"nuiue", "Pacific/Niue"},
646             {"nzakl", "Pacific/Auckland"},
647             {"nzcht", "Pacific/Chatham"},
648             {"ommct", "Asia/Muscat"},
649             {"papty", "America/Panama"},
650             {"pelim", "America/Lima"},
651             {"pfgmr", "Pacific/Gambier"},
652             {"pfnhv", "Pacific/Marquesas"},
653             {"pfppt", "Pacific/Tahiti"},
654             {"pgpom", "Pacific/Port_Moresby"},
655             {"pgraw", "Pacific/Bougainville"},
656             {"phmnl", "Asia/Manila"},
657             {"pkkhi", "Asia/Karachi"},
658             {"plwaw", "Europe/Warsaw"},
659             {"pmmqc", "America/Miquelon"},
660             {"pnpcn", "Pacific/Pitcairn"},
661             {"prsju", "America/Puerto_Rico"},
662             {"pst8pdt", "PST8PDT"},
663             {"ptfnc", "Atlantic/Madeira"},
664             {"ptlis", "Europe/Lisbon"},
665             {"ptpdl", "Atlantic/Azores"},
666             {"pwror", "Pacific/Palau"},
667             {"pyasu", "America/Asuncion"},
668             {"qadoh", "Asia/Qatar"},
669             {"rereu", "Indian/Reunion"},
670             {"robuh", "Europe/Bucharest"},
671             {"rsbeg", "Europe/Belgrade"},
672             {"ruchita", "Asia/Chita"},
673             {"rudyr", "Asia/Anadyr"},
674             {"rugdx", "Asia/Magadan"},
675             {"ruikt", "Asia/Irkutsk"},
676             {"rukgd", "Europe/Kaliningrad"},
677             {"rukhndg", "Asia/Khandyga"},
678             {"rukra", "Asia/Krasnoyarsk"},
679             {"rukuf", "Europe/Samara"},
680             {"rumow", "Europe/Moscow"},
681             {"runoz", "Asia/Novokuznetsk"},
682             {"ruoms", "Asia/Omsk"},
683             {"ruovb", "Asia/Novosibirsk"},
684             {"rupkc", "Asia/Kamchatka"},
685             {"rusred", "Asia/Srednekolymsk"},
686             {"ruunera", "Asia/Ust-Nera"},
687             {"ruuus", "Asia/Sakhalin"},
688             {"ruvog", "Europe/Volgograd"},
689             {"ruvvo", "Asia/Vladivostok"},
690             {"ruyek", "Asia/Yekaterinburg"},
691             {"ruyks", "Asia/Yakutsk"},
692             {"rwkgl", "Africa/Kigali"},
693             {"saruh", "Asia/Riyadh"},
694             {"sbhir", "Pacific/Guadalcanal"},
695             {"scmaw", "Indian/Mahe"},
696             {"sdkrt", "Africa/Khartoum"},
697             {"sesto", "Europe/Stockholm"},
698             {"sgsin", "Asia/Singapore"},
699             {"shshn", "Atlantic/St_Helena"},
700             {"silju", "Europe/Ljubljana"},
701             {"sjlyr", "Arctic/Longyearbyen"},
702             {"skbts", "Europe/Bratislava"},
703             {"slfna", "Africa/Freetown"},
704             {"smsai", "Europe/San_Marino"},
705             {"sndkr", "Africa/Dakar"},
706             {"somgq", "Africa/Mogadishu"},
707             {"srpbm", "America/Paramaribo"},
708             {"ssjub", "Africa/Juba"},
709             {"sttms", "Africa/Sao_Tome"},
710             {"svsal", "America/El_Salvador"},
711             {"sxphi", "America/Lower_Princes"},
712             {"sydam", "Asia/Damascus"},
713             {"szqmn", "Africa/Mbabane"},
714             {"tcgdt", "America/Grand_Turk"},
715             {"tdndj", "Africa/Ndjamena"},
716             {"tfpfr", "Indian/Kerguelen"},
717             {"tglfw", "Africa/Lome"},
718             {"thbkk", "Asia/Bangkok"},
719             {"tjdyu", "Asia/Dushanbe"},
720             {"tkfko", "Pacific/Fakaofo"},
721             {"tldil", "Asia/Dili"},
722             {"tmasb", "Asia/Ashgabat"},
723             {"tntun", "Africa/Tunis"},
724             {"totbu", "Pacific/Tongatapu"},
725             {"trist", "Europe/Istanbul"},
726             {"ttpos", "America/Port_of_Spain"},
727             {"tvfun", "Pacific/Funafuti"},
728             {"twtpe", "Asia/Taipei"},
729             {"tzdar", "Africa/Dar_es_Salaam"},
730             {"uaiev", "Europe/Kiev"},
731             {"uasip", "Europe/Simferopol"},
732             {"ugkla", "Africa/Kampala"},
733             {"umawk", "Pacific/Wake"},
734             {"ummdy", "Pacific/Midway"},
735 //            {"unk", "Etc/Unknown"},
736             {"usadk", "America/Adak"},
737             {"usaeg", "America/Indiana/Marengo"},
738             {"usanc", "America/Anchorage"},
739             {"usboi", "America/Boise"},
740             {"uschi", "America/Chicago"},
741             {"usden", "America/Denver"},
742             {"usdet", "America/Detroit"},
743             {"ushnl", "Pacific/Honolulu"},
744             {"usind", "America/Indianapolis"},
745             {"usinvev", "America/Indiana/Vevay"},
746             {"usjnu", "America/Juneau"},
747             {"usknx", "America/Indiana/Knox"},
748             {"uslax", "America/Los_Angeles"},
749             {"uslui", "America/Louisville"},
750             {"usmnm", "America/Menominee"},
751             {"usmtm", "America/Metlakatla"},
752             {"usmoc", "America/Kentucky/Monticello"},
753             {"usndcnt", "America/North_Dakota/Center"},
754             {"usndnsl", "America/North_Dakota/New_Salem"},
755             {"usnyc", "America/New_York"},
756             {"usoea", "America/Indiana/Vincennes"},
757             {"usome", "America/Nome"},
758             {"usphx", "America/Phoenix"},
759             {"ussit", "America/Sitka"},
760             {"ustel", "America/Indiana/Tell_City"},
761             {"uswlz", "America/Indiana/Winamac"},
762             {"uswsq", "America/Indiana/Petersburg"},
763             {"usxul", "America/North_Dakota/Beulah"},
764             {"usyak", "America/Yakutat"},
765             {"utc", "Etc/UTC"},
766             {"utce01", "Etc/GMT-1"},
767             {"utce02", "Etc/GMT-2"},
768             {"utce03", "Etc/GMT-3"},
769             {"utce04", "Etc/GMT-4"},
770             {"utce05", "Etc/GMT-5"},
771             {"utce06", "Etc/GMT-6"},
772             {"utce07", "Etc/GMT-7"},
773             {"utce08", "Etc/GMT-8"},
774             {"utce09", "Etc/GMT-9"},
775             {"utce10", "Etc/GMT-10"},
776             {"utce11", "Etc/GMT-11"},
777             {"utce12", "Etc/GMT-12"},
778             {"utce13", "Etc/GMT-13"},
779             {"utce14", "Etc/GMT-14"},
780             {"utcw01", "Etc/GMT+1"},
781             {"utcw02", "Etc/GMT+2"},
782             {"utcw03", "Etc/GMT+3"},
783             {"utcw04", "Etc/GMT+4"},
784             {"utcw05", "Etc/GMT+5"},
785             {"utcw06", "Etc/GMT+6"},
786             {"utcw07", "Etc/GMT+7"},
787             {"utcw08", "Etc/GMT+8"},
788             {"utcw09", "Etc/GMT+9"},
789             {"utcw10", "Etc/GMT+10"},
790             {"utcw11", "Etc/GMT+11"},
791             {"utcw12", "Etc/GMT+12"},
792             {"uymvd", "America/Montevideo"},
793             {"uzskd", "Asia/Samarkand"},
794             {"uztas", "Asia/Tashkent"},
795             {"vavat", "Europe/Vatican"},
796             {"vcsvd", "America/St_Vincent"},
797             {"veccs", "America/Caracas"},
798             {"vgtov", "America/Tortola"},
799             {"vistt", "America/St_Thomas"},
800             {"vnsgn", "Asia/Saigon"},
801             {"vuvli", "Pacific/Efate"},
802             {"wfmau", "Pacific/Wallis"},
803             {"wsapw", "Pacific/Apia"},
804             {"yeade", "Asia/Aden"},
805             {"ytmam", "Indian/Mayotte"},
806             {"zajnb", "Africa/Johannesburg"},
807             {"zmlun", "Africa/Lusaka"},
808             {"zwhre", "Africa/Harare"},
809 
810         };
811     }
812 
813     @DataProvider(name="getLocalizedDateTimePattern")
getLocalizedDateTimePattern()814     Object[][] getLocalizedDateTimePattern() {
815         return new Object[][] {
816             // Locale, Expected pattern,
817             {Locale.US, FormatStyle.FULL, "EEEE, MMMM d, y 'at' h:mm:ss a zzzz"},
818             {Locale.US, FormatStyle.LONG, "MMMM d, y 'at' h:mm:ss a z"},
819             {Locale.US, FormatStyle.MEDIUM, "MMM d, y, h:mm:ss a"},
820             {Locale.US, FormatStyle.SHORT, "M/d/yy, h:mm a"},
821             {RG_GB, FormatStyle.FULL, "EEEE, d MMMM y 'at' HH:mm:ss zzzz"},
822             {RG_GB, FormatStyle.LONG, "d MMMM y 'at' HH:mm:ss z"},
823             {RG_GB, FormatStyle.MEDIUM, "d MMM y, HH:mm:ss"},
824             {RG_GB, FormatStyle.SHORT, "dd/MM/y, HH:mm"},
825         };
826     }
827 
828     @DataProvider(name="getDisplayName")
getDisplayName()829     Object[][] getDisplayName() {
830         return new Object[][] {
831             // Locale, field, Expected name,
832             {Locale.US, ChronoField.AMPM_OF_DAY, "AM/PM"},
833             // Android-changed: Android uses CLDR data.
834             // {RG_GB, ChronoField.AMPM_OF_DAY, "am/pm"},
835             {RG_GB, ChronoField.AMPM_OF_DAY, "AM/PM"},
836         };
837     }
838 
839     @NonCts(bug = 286802267, reason = NonCtsReasons.CLDR_DATA_DEPENDENCY)
840     @Test(dataProvider="localizedBy")
test_localizedBy(Locale locale, Chronology chrono, ZoneId zone, Chronology chronoExpected, ZoneId zoneExpected, String formatExpected)841     public void test_localizedBy(Locale locale, Chronology chrono, ZoneId zone,
842                                 Chronology chronoExpected, ZoneId zoneExpected,
843                                 String formatExpected) {
844         // Skip this test if older ICU provides the locale data.
845         if (VersionInfo.ICU_VERSION.getMajor() < 74) {
846             return;
847         }
848         // try this test both with the implicit default locale, and explicit default locale ja-JP
849         Locale def = Locale.getDefault();
850         try {
851             Stream.of(def, Locale.JAPAN).forEach(l -> {
852                 System.out.println("    Testing with the default locale: " + l);
853                 Locale.setDefault(l);
854 
855                 DateTimeFormatter dtf =
856                         DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL)
857                                 .withChronology(chrono).withZone(zone).localizedBy(locale);
858                 assertEquals(dtf.getChronology(), chronoExpected);
859                 assertEquals(dtf.getZone(), zoneExpected);
860                 String formatted = dtf.format(ZDT);
861                 assertEquals(formatted, formatExpected);
862                 assertEquals(dtf.parse(formatted, ZonedDateTime::from),
863                         zoneExpected != null ? ZDT.withZoneSameInstant(zoneExpected) : ZDT);
864             });
865         } finally {
866             Locale.setDefault(def);
867         }
868     }
869 
870     @Test(dataProvider="withLocale")
test_withLocale(Locale locale, Chronology chrono, ZoneId zone, Chronology chronoExpected, ZoneId zoneExpected, String formatExpected)871     public void test_withLocale(Locale locale, Chronology chrono, ZoneId zone,
872                                 Chronology chronoExpected, ZoneId zoneExpected,
873                                 String formatExpected) {
874         // Skip this test if older ICU provides the locale data.
875         if (VersionInfo.ICU_VERSION.getMajor() < 74) {
876             return;
877         }
878         DateTimeFormatter dtf =
879             DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL)
880                 .withChronology(chrono).withZone(zone).withLocale(locale);
881         assertEquals(dtf.getChronology(), chronoExpected);
882         assertEquals(dtf.getZone(), zoneExpected);
883         String formatted = dtf.format(ZDT);
884         // Android-changed: print locale.toString() in case of the test failure.
885         assertEquals(formatted, formatExpected, locale.toString());
886         assertEquals(dtf.parse(formatted, ZonedDateTime::from),
887             zoneExpected != null ? ZDT.withZoneSameInstant(zoneExpected) : ZDT, locale.toString());
888     }
889 
890     @Test(dataProvider="firstDayOfWeek")
test_firstDayOfWeek(Locale locale, DayOfWeek dowExpected)891     public void test_firstDayOfWeek(Locale locale, DayOfWeek dowExpected) {
892         DayOfWeek dow = WeekFields.of(locale).getFirstDayOfWeek();
893         assertEquals(dow, dowExpected);
894     }
895 
896     @Test(dataProvider="minDaysInFirstWeek")
test_minDaysInFirstWeek(Locale locale, int minDaysExpected)897     public void test_minDaysInFirstWeek(Locale locale, int minDaysExpected) {
898         int minDays = WeekFields.of(locale).getMinimalDaysInFirstWeek();
899         assertEquals(minDays, minDaysExpected);
900     }
901 
902     @Test(dataProvider="ofPattern")
test_ofPattern(Locale locale, Chronology chronoExpected, ZoneId zoneExpected, String formatExpected)903     public void test_ofPattern(Locale locale,
904                                 Chronology chronoExpected, ZoneId zoneExpected,
905                                 String formatExpected) {
906         DateTimeFormatter dtf =
907             DateTimeFormatter.ofPattern(PATTERN, locale);
908         assertEquals(dtf.getChronology(), chronoExpected);
909         assertEquals(dtf.getZone(), zoneExpected);
910         String formatted = dtf.format(ZDT);
911         assertEquals(formatted, formatExpected);
912         assertEquals(dtf.parse(formatted, ZonedDateTime::from),
913             zoneExpected != null ? ZDT.withZoneSameInstant(zoneExpected) : ZDT);
914     }
915 
916     @Test(dataProvider="ofPattern")
test_toFormatter(Locale locale, Chronology chronoExpected, ZoneId zoneExpected, String formatExpected)917     public void test_toFormatter(Locale locale,
918                                 Chronology chronoExpected, ZoneId zoneExpected,
919                                 String formatExpected) {
920         DateTimeFormatter dtf =
921             new DateTimeFormatterBuilder().appendPattern(PATTERN).toFormatter(locale);
922         assertEquals(dtf.getChronology(), chronoExpected);
923         assertEquals(dtf.getZone(), zoneExpected);
924         String formatted = dtf.format(ZDT);
925         assertEquals(formatted, formatExpected);
926         assertEquals(dtf.parse(formatted, ZonedDateTime::from),
927             zoneExpected != null ? ZDT.withZoneSameInstant(zoneExpected) : ZDT);
928     }
929 
930     @Test(dataProvider="shortTZID")
test_shortTZID(String shortID, String expectedZone)931     public void test_shortTZID(String shortID, String expectedZone) {
932         Locale l = Locale.forLanguageTag("en-US-u-tz-" + shortID);
933         DateTimeFormatter dtf =
934             DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL)
935                 .localizedBy(l);
936         assertEquals(dtf.getZone(), ZoneId.of(expectedZone));
937     }
938 
939     // Android-changed: Android doesn't support "rg" extension yet.
940     @Test(dataProvider="getLocalizedDateTimePattern", enabled = false)
test_getLocalizedDateTimePattern(Locale l, FormatStyle s, String expectedPattern)941     public void test_getLocalizedDateTimePattern(Locale l, FormatStyle s, String expectedPattern) {
942         DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
943         assertEquals(dtfb.getLocalizedDateTimePattern(s, s, IsoChronology.INSTANCE, l),
944             expectedPattern);
945     }
946 
947     @Test(dataProvider="getDisplayName")
test_getDisplayName(Locale l, TemporalField f, String expectedName)948     public void test_getDisplayName(Locale l, TemporalField f, String expectedName) {
949         assertEquals(f.getDisplayName(l), expectedName);
950     }
951 }
952