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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package test.java.time.chrono;
27 
28 import android.icu.util.VersionInfo;
29 import java.time.*;
30 import java.time.chrono.*;
31 import java.time.format.*;
32 import java.util.Arrays;
33 import java.util.Locale;
34 import java.util.stream.Stream;
35 
36 import org.testng.annotations.DataProvider;
37 import org.testng.annotations.Test;
38 import static org.testng.Assert.assertEquals;
39 import static org.testng.Assert.assertFalse;
40 
41 import dalvik.annotation.compat.VersionCodes;
42 
43 import libcore.test.annotation.NonMts;
44 import libcore.test.reasons.NonMtsReasons;
45 
46 /**
47  * Tests Era.getDisplayName() correctly returns the name based on each
48  * chrono implementation.
49  * Note: The exact result may depend on locale data provider's implementation.
50  *
51  * @bug 8171049 8224105 8240626
52  */
53 @Test
54 public class TestEraDisplayName {
55     private static final Locale THAI = Locale.forLanguageTag("th-TH");
56     private static final Locale EGYPT = Locale.forLanguageTag("ar-EG");
57 
58     private static final LocalDate REIWA_1ST = LocalDate.of(2019, 5, 1);
59     private static final DateTimeFormatter JAPANESE_FORMATTER =
60          DateTimeFormatter.ofPattern("yyyy MM dd GGGG G GGGGG")
61             .withChronology(JapaneseChronology.INSTANCE);
62 
63     @DataProvider(name="eraDisplayName")
eraDisplayName()64     Object[][] eraDisplayName() {
65         return new Object[][] {
66             // Era, text style, displyay locale, expected name
67             // IsoEra
68             { IsoEra.BCE,   TextStyle.FULL,     Locale.US,      "Before Christ" },
69             { IsoEra.CE,    TextStyle.FULL,     Locale.US,      "Anno Domini" },
70             { IsoEra.BCE,   TextStyle.FULL,     Locale.JAPAN,   "\u7d00\u5143\u524d" },
71             { IsoEra.CE,    TextStyle.FULL,     Locale.JAPAN,   "\u897f\u66a6" },
72             { IsoEra.BCE,   TextStyle.SHORT,    Locale.US,      "BC" },
73             { IsoEra.CE,    TextStyle.SHORT,    Locale.US,      "AD" },
74             { IsoEra.BCE,   TextStyle.SHORT,    Locale.JAPAN,   "\u7d00\u5143\u524d" },
75             { IsoEra.CE,    TextStyle.SHORT,    Locale.JAPAN,   "\u897f\u66a6" },
76             { IsoEra.BCE,   TextStyle.NARROW,   Locale.US,      "B" },
77             { IsoEra.CE,    TextStyle.NARROW,   Locale.US,      "A" },
78             { IsoEra.BCE,   TextStyle.NARROW,   Locale.JAPAN,   "BC" },
79             { IsoEra.CE,    TextStyle.NARROW,   Locale.JAPAN,   "AD" },
80 
81             // JapaneseEra
82             { JapaneseEra.MEIJI,    TextStyle.FULL,     Locale.US,      "Meiji" },
83             { JapaneseEra.TAISHO,   TextStyle.FULL,     Locale.US,      "Taish\u014d" },
84             { JapaneseEra.SHOWA,    TextStyle.FULL,     Locale.US,      "Sh\u014dwa" },
85             { JapaneseEra.HEISEI,   TextStyle.FULL,     Locale.US,      "Heisei" },
86             { JapaneseEra.REIWA,    TextStyle.FULL,     Locale.US,      "Reiwa" },
87             { JapaneseEra.MEIJI,    TextStyle.FULL,     Locale.JAPAN,   "\u660e\u6cbb" },
88             { JapaneseEra.TAISHO,   TextStyle.FULL,     Locale.JAPAN,   "\u5927\u6b63" },
89             { JapaneseEra.SHOWA,    TextStyle.FULL,     Locale.JAPAN,   "\u662d\u548c" },
90             { JapaneseEra.HEISEI,   TextStyle.FULL,     Locale.JAPAN,   "\u5e73\u6210" },
91             { JapaneseEra.REIWA,    TextStyle.FULL,     Locale.JAPAN,   "\u4ee4\u548c" },
92             { JapaneseEra.MEIJI,    TextStyle.SHORT,    Locale.US,      "Meiji" },
93             { JapaneseEra.TAISHO,   TextStyle.SHORT,    Locale.US,      "Taish\u014d" },
94             { JapaneseEra.SHOWA,    TextStyle.SHORT,    Locale.US,      "Sh\u014dwa" },
95             { JapaneseEra.HEISEI,   TextStyle.SHORT,    Locale.US,      "Heisei" },
96             { JapaneseEra.REIWA,    TextStyle.SHORT,    Locale.US,      "Reiwa" },
97             { JapaneseEra.MEIJI,    TextStyle.SHORT,    Locale.JAPAN,   "\u660e\u6cbb" },
98             { JapaneseEra.TAISHO,   TextStyle.SHORT,    Locale.JAPAN,   "\u5927\u6b63" },
99             { JapaneseEra.SHOWA,    TextStyle.SHORT,    Locale.JAPAN,   "\u662d\u548c" },
100             { JapaneseEra.HEISEI,   TextStyle.SHORT,    Locale.JAPAN,   "\u5e73\u6210" },
101             { JapaneseEra.REIWA,    TextStyle.SHORT,    Locale.JAPAN,   "\u4ee4\u548c" },
102             { JapaneseEra.MEIJI,    TextStyle.NARROW,   Locale.US,      "M" },
103             { JapaneseEra.TAISHO,   TextStyle.NARROW,   Locale.US,      "T" },
104             { JapaneseEra.SHOWA,    TextStyle.NARROW,   Locale.US,      "S" },
105             { JapaneseEra.HEISEI,   TextStyle.NARROW,   Locale.US,      "H" },
106             { JapaneseEra.REIWA,    TextStyle.NARROW,   Locale.US,      "R" },
107             { JapaneseEra.MEIJI,    TextStyle.NARROW,   Locale.JAPAN,   "M" },
108             { JapaneseEra.TAISHO,   TextStyle.NARROW,   Locale.JAPAN,   "T" },
109             { JapaneseEra.SHOWA,    TextStyle.NARROW,   Locale.JAPAN,   "S" },
110             { JapaneseEra.HEISEI,   TextStyle.NARROW,   Locale.JAPAN,   "H" },
111             { JapaneseEra.REIWA,    TextStyle.NARROW,   Locale.JAPAN,   "R" },
112 
113             // ThaiBuddhistEra
114             // Android-changed: Android uses CLDR data.
115             // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, Locale.US,      "BC" },
116             // { ThaiBuddhistEra.BE,           TextStyle.FULL, Locale.US,      "BE" },
117             // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, THAI,           "BC" },
118             // { ThaiBuddhistEra.BE,           TextStyle.FULL, THAI,
119             //   "\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a" },
120             // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, Locale.US,     "BC" },
121             // { ThaiBuddhistEra.BE,           TextStyle.SHORT, Locale.US,     "BE" },
122             // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, THAI,          "BC" },
123             // { ThaiBuddhistEra.BE,           TextStyle.SHORT, THAI,  "\u0e1e.\u0e28." },
124             // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, Locale.US,    "BC" },
125             // { ThaiBuddhistEra.BE,           TextStyle.NARROW, Locale.US,    "BE" },
126             // { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, THAI,         "BC" },
127             // { ThaiBuddhistEra.BE,           TextStyle.NARROW, THAI,         "\u0e1e.\u0e28." },
128             { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, Locale.US,      "0" },
129             { ThaiBuddhistEra.BE,           TextStyle.FULL, Locale.US,      "BE" },
130             { ThaiBuddhistEra.BEFORE_BE,    TextStyle.FULL, THAI,           "0" },
131             { ThaiBuddhistEra.BE,           TextStyle.FULL, THAI,
132                 "\u0e1e\u0e38\u0e17\u0e18\u0e28\u0e31\u0e01\u0e23\u0e32\u0e0a" },
133             { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, Locale.US,     "0" },
134             { ThaiBuddhistEra.BE,           TextStyle.SHORT, Locale.US,     "BE" },
135             { ThaiBuddhistEra.BEFORE_BE,    TextStyle.SHORT, THAI,          "0" },
136             { ThaiBuddhistEra.BE,           TextStyle.SHORT, THAI,  "\u0e1e.\u0e28." },
137             { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, Locale.US,    "0" },
138             { ThaiBuddhistEra.BE,           TextStyle.NARROW, Locale.US,    "BE" },
139             { ThaiBuddhistEra.BEFORE_BE,    TextStyle.NARROW, THAI,         "0" },
140             { ThaiBuddhistEra.BE,           TextStyle.NARROW, THAI,         "\u0e1e.\u0e28." },
141 
142             // MinguoEra
143             // Android-changed: Android uses CLDR data.
144             // { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.US,      "Before R.O.C." },
145             // { MinguoEra.ROC,        TextStyle.FULL,     Locale.US,      "Minguo" },
146             // { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.TAIWAN,  "\u6c11\u570b\u524d" },
147             // { MinguoEra.ROC,        TextStyle.FULL,     Locale.TAIWAN,  "\u6c11\u570b" },
148             // { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.US,      "Before R.O.C." },
149             // { MinguoEra.ROC,        TextStyle.SHORT,    Locale.US,      "Minguo" },
150             // { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.TAIWAN,  "\u6c11\u570b\u524d" },
151             // { MinguoEra.ROC,        TextStyle.SHORT,    Locale.TAIWAN,  "\u6c11\u570b" },
152             // { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.US,      "Before R.O.C." },
153             // { MinguoEra.ROC,        TextStyle.NARROW,   Locale.US,      "Minguo" },
154             // { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.TAIWAN,  "\u6c11\u570b\u524d" },
155             // { MinguoEra.ROC,        TextStyle.NARROW,   Locale.TAIWAN,  "\u6c11\u570b" },
156             { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.US,      "B.R.O.C." },
157             { MinguoEra.ROC,        TextStyle.FULL,     Locale.US,      "Minguo" },
158             { MinguoEra.BEFORE_ROC, TextStyle.FULL,     Locale.TAIWAN,  "\u6c11\u570b\u524d" },
159             { MinguoEra.ROC,        TextStyle.FULL,     Locale.TAIWAN,  "\u6c11\u570b" },
160             { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.US,      "B.R.O.C." },
161             { MinguoEra.ROC,        TextStyle.SHORT,    Locale.US,      "Minguo" },
162             { MinguoEra.BEFORE_ROC, TextStyle.SHORT,    Locale.TAIWAN,  "\u6c11\u570b\u524d" },
163             { MinguoEra.ROC,        TextStyle.SHORT,    Locale.TAIWAN,  "\u6c11\u570b" },
164             { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.US,      "B.R.O.C." },
165             { MinguoEra.ROC,        TextStyle.NARROW,   Locale.US,      "Minguo" },
166             { MinguoEra.BEFORE_ROC, TextStyle.NARROW,   Locale.TAIWAN,  "\u6c11\u570b\u524d" },
167             { MinguoEra.ROC,        TextStyle.NARROW,   Locale.TAIWAN,  "\u6c11\u570b" },
168 
169             // HijrahEra
170             { HijrahEra.AH, TextStyle.FULL,     Locale.US,  "AH" },
171             { HijrahEra.AH, TextStyle.FULL,     EGYPT,      "\u0647\u0640" },
172             { HijrahEra.AH, TextStyle.SHORT,    Locale.US,  "AH" },
173             { HijrahEra.AH, TextStyle.SHORT,    EGYPT,      "\u0647\u0640" },
174             { HijrahEra.AH, TextStyle.NARROW,   Locale.US,  "AH" },
175             { HijrahEra.AH, TextStyle.NARROW,   EGYPT,      "\u0647\u0640" },
176         };
177     }
178 
179     @DataProvider
allLocales()180     Object[][] allLocales() {
181         return Arrays.stream(Locale.getAvailableLocales())
182             .map(Stream::of)
183             .map(Stream::toArray)
184             .toArray(Object[][]::new);
185     }
186 
187     @DataProvider
allEras()188     Object[][] allEras() {
189         return Stream.of(IsoEra.values(),
190                         JapaneseEra.values(),
191                         HijrahEra.values(),
192                         ThaiBuddhistEra.values(),
193                         MinguoEra.values())
194             .flatMap(v -> Arrays.stream(v))
195             .map(Stream::of)
196             .map(Stream::toArray)
197             .toArray(Object[][]::new);
198     }
199 
200     // Android-changed: The ICU data is different before ICU version 70. http://b/229960530
201     @NonMts(reason = NonMtsReasons.ICU_VERSION_DEPENDENCY,
202             disabledUntilSdk = VersionCodes.TIRAMISU)
203     @Test(dataProvider="eraDisplayName")
test_eraDisplayName(Era era, TextStyle style, Locale locale, String expected)204     public void test_eraDisplayName(Era era, TextStyle style, Locale locale, String expected) {
205         assertEquals(era.getDisplayName(style, locale), expected);
206     }
207 
208     @Test(dataProvider="allLocales")
test_reiwaNames(Locale locale)209     public void test_reiwaNames(Locale locale) throws DateTimeParseException {
210         DateTimeFormatter f = JAPANESE_FORMATTER.withLocale(locale);
211         assertEquals(LocalDate.parse(REIWA_1ST.format(f), f), REIWA_1ST);
212     }
213 
214     // Make sure era display names aren't empty
215     // @bug 8240626
216     @Test(dataProvider="allEras")
test_noEmptyEraNames(Era era)217     public void test_noEmptyEraNames(Era era) {
218         Arrays.stream(Locale.getAvailableLocales())
219             .forEach(l -> {
220                 Arrays.stream(TextStyle.values())
221                     .forEach(s -> {
222                         assertFalse(era.getDisplayName(s, l).isEmpty(),
223                             "getDisplayName() returns empty display name for era: " + era
224                             + ", style: " + s + ", locale: " + l);
225                     });
226             });
227     }
228 }
229