diff --git a/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java b/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java index d8752bca142..cbef22d91c0 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java @@ -542,10 +542,10 @@ class Bundle { if (pattern != null) { // Perform date-time format pattern conversion which is // applicable to both SimpleDateFormat and j.t.f.DateTimeFormatter. - String transPattern = translateDateFormatLetters(calendarType, pattern, this::convertDateTimePatternLetter); + String transPattern = translateDateFormatLetters(calendarType, key, pattern, this::convertDateTimePatternLetter); dateTimePatterns.add(i, transPattern); // Additionally, perform SDF specific date-time format pattern conversion - sdfPatterns.add(i, translateDateFormatLetters(calendarType, transPattern, this::convertSDFLetter)); + sdfPatterns.add(i, translateDateFormatLetters(calendarType, key, transPattern, this::convertSDFLetter)); } else { dateTimePatterns.add(i, null); sdfPatterns.add(i, null); @@ -568,7 +568,7 @@ class Bundle { } } - private String translateDateFormatLetters(CalendarType calendarType, String cldrFormat, ConvertDateTimeLetters converter) { + private String translateDateFormatLetters(CalendarType calendarType, String patternKey, String cldrFormat, ConvertDateTimeLetters converter) { String pattern = cldrFormat; int length = pattern.length(); boolean inQuote = false; @@ -587,7 +587,7 @@ class Bundle { if (nextc == '\'') { i++; if (count != 0) { - converter.convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, patternKey, lastLetter, count, jrePattern); lastLetter = 0; count = 0; } @@ -597,7 +597,7 @@ class Bundle { } if (!inQuote) { if (count != 0) { - converter.convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, patternKey, lastLetter, count, jrePattern); lastLetter = 0; count = 0; } @@ -614,7 +614,7 @@ class Bundle { } if (!(c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')) { if (count != 0) { - converter.convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, patternKey, lastLetter, count, jrePattern); lastLetter = 0; count = 0; } @@ -627,7 +627,7 @@ class Bundle { count++; continue; } - converter.convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, patternKey, lastLetter, count, jrePattern); lastLetter = c; count = 1; } @@ -637,7 +637,7 @@ class Bundle { } if (count != 0) { - converter.convert(calendarType, lastLetter, count, jrePattern); + converter.convert(calendarType, patternKey, lastLetter, count, jrePattern); } if (cldrFormat.contentEquals(jrePattern)) { return cldrFormat; @@ -661,7 +661,7 @@ class Bundle { * on the support given by the SimpleDateFormat and the j.t.f.DateTimeFormatter * for date-time formatting. */ - private void convertDateTimePatternLetter(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) { + private void convertDateTimePatternLetter(CalendarType calendarType, String patternKey, char cldrLetter, int count, StringBuilder sb) { switch (cldrLetter) { case 'u': case 'U': @@ -683,7 +683,7 @@ class Bundle { * Perform a conversion of CLDR date-time format pattern letter which is * specific to the SimpleDateFormat. */ - private void convertSDFLetter(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb) { + private void convertSDFLetter(CalendarType calendarType, String patternKey, char cldrLetter, int count, StringBuilder sb) { switch (cldrLetter) { case 'G': if (calendarType != CalendarType.GREGORIAN) { @@ -722,6 +722,17 @@ class Bundle { appendN('z', count, sb); break; + case 'y': + // If the style is FULL/LONG for a Japanese Calendar, make the + // count == 4 for Gan-nen + if (calendarType == CalendarType.JAPANESE && + (patternKey.contains("full-") || + patternKey.contains("long-"))) { + count = 4; + } + appendN(cldrLetter, count, sb); + break; + case 'Z': if (count == 4 || count == 5) { sb.append("XXX"); @@ -767,6 +778,7 @@ class Bundle { .collect(Collectors.toMap( e -> calendarPrefix + e.getKey(), e -> translateDateFormatLetters(calendarType, + e.getKey(), (String)e.getValue(), this::convertDateTimePatternLetter) )) @@ -775,7 +787,7 @@ class Bundle { @FunctionalInterface private interface ConvertDateTimeLetters { - void convert(CalendarType calendarType, char cldrLetter, int count, StringBuilder sb); + void convert(CalendarType calendarType, String patternKey, char cldrLetter, int count, StringBuilder sb); } /** diff --git a/test/jdk/java/util/Calendar/JapaneseCalendarNameTest.java b/test/jdk/java/util/Calendar/JapaneseCalendarNameTest.java new file mode 100644 index 00000000000..6c8597c9404 --- /dev/null +++ b/test/jdk/java/util/Calendar/JapaneseCalendarNameTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8202088 8207152 8217609 8219890 8358819 + * @summary Test the localized Japanese calendar names, such as + * the Reiwa Era names (May 1st. 2019-), or the Gan-nen text + * @modules jdk.localedata + * @run junit JapaneseCalendarNameTest + */ + +import static java.util.Calendar.*; +import static java.util.Locale.*; + +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Calendar; +import java.util.Locale; +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class JapaneseCalendarNameTest { + private static final Calendar c = new Calendar.Builder() + .setCalendarType("japanese") + .setFields(ERA, 5, YEAR, 1, MONTH, MAY, DAY_OF_MONTH, 1) + .build(); + private static final Locale JAJPJP = Locale.of("ja", "JP", "JP"); + private static final Locale JCAL = Locale.forLanguageTag("ja-u-ca-japanese"); + + private static Stream reiwaEraNames() { + return Stream.of( + // type, locale, name + Arguments.of(LONG, JAPAN, "令和"), + Arguments.of(LONG, US, "Reiwa"), + Arguments.of(LONG, CHINA, "令和"), + Arguments.of(SHORT, JAPAN, "令和"), + Arguments.of(SHORT, US, "Reiwa"), + Arguments.of(SHORT, CHINA, "令和") + ); + } + + @ParameterizedTest + @MethodSource("reiwaEraNames") + void testReiwaEraName(int type, Locale locale, String expected) { + assertEquals(expected, c.getDisplayName(ERA, type, locale)); + } + + private static Stream gannen() { + return Stream.of( + // format, + // formatted text + Arguments.of(DateFormat.getDateInstance(DateFormat.FULL, JAJPJP), + "令和元年5月1日水曜日"), + Arguments.of(DateFormat.getDateInstance(DateFormat.FULL, JCAL), + "令和元年5月1日水曜日"), + Arguments.of(DateFormat.getDateInstance(DateFormat.LONG, JAJPJP), + "令和元年5月1日"), + Arguments.of(DateFormat.getDateInstance(DateFormat.LONG, JCAL), + "令和元年5月1日"), + Arguments.of(DateFormat.getDateInstance(DateFormat.MEDIUM, JAJPJP), + "令和1年5月1日"), + Arguments.of(DateFormat.getDateInstance(DateFormat.MEDIUM, JCAL), + "令和1年5月1日"), + Arguments.of(DateFormat.getDateInstance(DateFormat.SHORT, JAJPJP), + "令和1/5/1"), + Arguments.of(DateFormat.getDateInstance(DateFormat.SHORT, JCAL), + "令和1/5/1") + ); + } + + @ParameterizedTest + @MethodSource("gannen") + void testGannenFormat(DateFormat df, String expected) { + assertEquals(expected, df.format(c.getTime())); + } + + @ParameterizedTest + @MethodSource("gannen") + void testGannenParse(DateFormat df, String formatted) throws ParseException { + assertEquals(c.getTime(), df.parse(formatted)); + } +} diff --git a/test/jdk/java/util/Calendar/JapaneseEraNameTest.java b/test/jdk/java/util/Calendar/JapaneseEraNameTest.java deleted file mode 100644 index 11e35927adf..00000000000 --- a/test/jdk/java/util/Calendar/JapaneseEraNameTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8202088 8207152 8217609 8219890 - * @summary Test the localized Japanese new era name (May 1st. 2019-) - * is retrieved no matter CLDR provider contains the name or not. - * @modules jdk.localedata - * @run testng JapaneseEraNameTest - */ - -import static java.util.Calendar.*; -import static java.util.Locale.*; -import java.util.Calendar; -import java.util.Locale; - -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; - -@Test -public class JapaneseEraNameTest { - static final Calendar c = new Calendar.Builder() - .setCalendarType("japanese") - .setFields(ERA, 5, YEAR, 1, MONTH, MAY, DAY_OF_MONTH, 1) - .build(); - - @DataProvider(name="names") - Object[][] names() { - return new Object[][] { - // type, locale, name - { LONG, JAPAN, "\u4ee4\u548c" }, - { LONG, US, "Reiwa" }, - { LONG, CHINA, "\u4ee4\u548c" }, - { SHORT, JAPAN, "\u4ee4\u548c" }, - { SHORT, US, "Reiwa" }, - { SHORT, CHINA, "\u4ee4\u548c" }, - }; - } - - @Test(dataProvider="names") - public void testJapaneseNewEraName(int type, Locale locale, String expected) { - assertEquals(c.getDisplayName(ERA, type, locale), expected); - } -}