changeset 8819:f00d42bd3b80

8202088: Japanese new era implementation 8207152: Placeholder for Japanese new era should be two characters 8206120: Add test cases for lenient Japanese era parsing Reviewed-by: coffeys, naoto Contributed-by: deepak.kejriwal@oracle.com
author andrew
date Sat, 13 Apr 2019 01:57:11 +0100
parents 6aa67dab21c9
children dba891c9a1b3
files src/share/classes/java/util/JapaneseImperialCalendar.java src/share/classes/sun/text/resources/FormatData.java src/share/classes/sun/text/resources/FormatData_ja.java src/share/classes/sun/util/calendar/Era.java src/share/lib/calendars.properties test/java/text/Format/DateFormat/WeekDateTest.java test/java/util/Calendar/JapaneseEraNameTest.java test/java/util/Calendar/JapaneseLenientEraTest.java
diffstat 8 files changed, 174 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/util/JapaneseImperialCalendar.java	Thu Mar 14 13:34:04 2019 -0300
+++ b/src/share/classes/java/util/JapaneseImperialCalendar.java	Sat Apr 13 01:57:11 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -50,6 +50,7 @@
  *     2       Taisho      1912-07-30 midnight local time
  *     3       Showa       1926-12-25 midnight local time
  *     4       Heisei      1989-01-08 midnight local time
+ *     5       NewEra      2019-05-01 midnight local time
  * ------------------------------------------------------
  * </tt></pre>
  *
@@ -101,6 +102,11 @@
      */
     public static final int HEISEI = 4;
 
+    /**
+     * The ERA constant designating the NewEra era.
+     */
+    private static final int NEWERA = 5;
+
     private static final int EPOCH_OFFSET   = 719163; // Fixed date of January 1, 1970 (Gregorian)
     private static final int EPOCH_YEAR     = 1970;
 
@@ -133,6 +139,9 @@
     // Fixed date of the first date of each era.
     private static final long[] sinceFixedDates;
 
+    // The current era
+    private static final int currentEra;
+
     /*
      * <pre>
      *                                 Greatest       Least
@@ -228,13 +237,18 @@
         // eras[BEFORE_MEIJI] and sinceFixedDate[BEFORE_MEIJI] are the
         // same as Gregorian.
         int index = BEFORE_MEIJI;
+        int current = index;
         sinceFixedDates[index] = gcal.getFixedDate(BEFORE_MEIJI_ERA.getSinceDate());
         eras[index++] = BEFORE_MEIJI_ERA;
         for (Era e : es) {
+            if(e.getSince(TimeZone.NO_TIMEZONE) < System.currentTimeMillis()) {
+                current = index;
+            }
             CalendarDate d = e.getSinceDate();
             sinceFixedDates[index] = gcal.getFixedDate(d);
             eras[index++] = e;
         }
+        currentEra = current;
 
         LEAST_MAX_VALUES[ERA] = MAX_VALUES[ERA] = eras.length - 1;
 
@@ -1744,12 +1758,12 @@
                     }
                 } else if (transitionYear) {
                     if (jdate.getYear() == 1) {
-                        // As of Heisei (since Meiji) there's no case
+                        // As of NewEra (since Meiji) there's no case
                         // that there are multiple transitions in a
                         // year.  Historically there was such
                         // case. There might be such case again in the
                         // future.
-                        if (era > HEISEI) {
+                        if (era > NEWERA) {
                             CalendarDate pd = eras[era - 1].getSinceDate();
                             if (normalizedYear == pd.getYear()) {
                                 d.setMonth(pd.getMonth()).setDayOfMonth(pd.getDayOfMonth());
@@ -1884,7 +1898,7 @@
             year = isSet(YEAR) ? internalGet(YEAR) : 1;
         } else {
             if (isSet(YEAR)) {
-                era = eras.length - 1;
+                era = currentEra;
                 year = internalGet(YEAR);
             } else {
                 // Equivalent to 1970 (Gregorian)
@@ -2366,7 +2380,7 @@
      * default ERA is the current era, but a zero (unset) ERA means before Meiji.
      */
     private final int internalGetEra() {
-        return isSet(ERA) ? internalGet(ERA) : eras.length - 1;
+        return isSet(ERA) ? internalGet(ERA) : currentEra;
     }
 
     /**
--- a/src/share/classes/sun/text/resources/FormatData.java	Thu Mar 14 13:34:04 2019 -0300
+++ b/src/share/classes/sun/text/resources/FormatData.java	Sat Apr 13 01:57:11 2019 +0100
@@ -138,6 +138,7 @@
                     "Taisho",
                     "Showa",
                     "Heisei",
+                    "NewEra", // NewEra
                 }
             },
             { "java.util.JapaneseImperialCalendar.short.Eras",
@@ -147,6 +148,7 @@
                     "T",
                     "S",
                     "H",
+                    "N", // NewEra
                 }
             },
             { "java.util.JapaneseImperialCalendar.FirstYear",
--- a/src/share/classes/sun/text/resources/FormatData_ja.java	Thu Mar 14 13:34:04 2019 -0300
+++ b/src/share/classes/sun/text/resources/FormatData_ja.java	Sat Apr 13 01:57:11 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -129,6 +129,7 @@
                     "\u5927\u6b63",     // Taisho
                     "\u662d\u548c",     // Showa
                     "\u5e73\u6210",     // Heisei
+                    "\u5143\u53f7",     // NewEra
                 }
             },
             { "java.util.JapaneseImperialCalendar.FirstYear",
--- a/src/share/classes/sun/util/calendar/Era.java	Thu Mar 14 13:34:04 2019 -0300
+++ b/src/share/classes/sun/util/calendar/Era.java	Sat Apr 13 01:57:11 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -49,6 +49,7 @@
  *                           Taisho           1912-07-30 midnight local time
  *                           Showa            1926-12-26 midnight local time
  *                           Heisei           1989-01-08 midnight local time
+ *                           NewEra           2019-05-01 midnight local time
  *   Julian calendar         BeforeCommonEra  -292275055-05-16T16:47:04.192Z
  *                           CommonEra        0000-12-30 midnight local time
  *   Taiwanese calendar      MinGuo           1911-01-01 midnight local time
--- a/src/share/lib/calendars.properties	Thu Mar 14 13:34:04 2019 -0300
+++ b/src/share/lib/calendars.properties	Sat Apr 13 01:57:11 2019 +0100
@@ -29,12 +29,14 @@
 #   Taisho since 1912-07-30 00:00:00 local time (Gregorian)
 #   Showa  since 1926-12-25 00:00:00 local time (Gregorian)
 #   Heisei since 1989-01-08 00:00:00 local time (Gregorian)
+#   NewEra since 2019-05-01 00:00:00 local time (Gregorian)
 calendar.japanese.type: LocalGregorianCalendar
 calendar.japanese.eras: \
 	name=Meiji,abbr=M,since=-3218832000000;  \
 	name=Taisho,abbr=T,since=-1812153600000; \
 	name=Showa,abbr=S,since=-1357603200000;  \
-	name=Heisei,abbr=H,since=600220800000
+	name=Heisei,abbr=H,since=600220800000;   \
+	name=NewEra,abbr=N,since=1556668800000
 
 #
 # Taiwanese calendar
--- a/test/java/text/Format/DateFormat/WeekDateTest.java	Thu Mar 14 13:34:04 2019 -0300
+++ b/test/java/text/Format/DateFormat/WeekDateTest.java	Sat Apr 13 01:57:11 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, 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
@@ -137,20 +137,28 @@
         Calendar jcal = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
                                              new Locale("ja", "JP", "JP"));
 
+        String format = "2-W01-2"; // 2019-12-31 == N1-12-31
+        int expectedYear = 2019;
+        // Check the current era, Heisei or NewEra
+        if (System.currentTimeMillis() < 1556668800000L) {
+            format = "21-W01-3"; // 2008-12-31 == H20-12-31
+            expectedYear = 2008;
+        }
         jcal.setFirstDayOfWeek(MONDAY);
         jcal.setMinimalDaysInFirstWeek(4);
         SimpleDateFormat sdf = new SimpleDateFormat("Y-'W'ww-u");
         sdf.setCalendar(jcal);
-        Date d = sdf.parse("21-W01-3"); // 2008-12-31 == H20-12-31
+        Date d = sdf.parse(format);
         GregorianCalendar gcal = newCalendar();
         gcal.setTime(d);
-        if (gcal.get(YEAR) != 2008
+        if (gcal.get(YEAR) != expectedYear
             || gcal.get(MONTH) != DECEMBER
             || gcal.get(DAY_OF_MONTH) != 31) {
-            String s = String.format("noWeekDateSupport: got %04d-%02d-%02d, expected 2008-12-31%n",
+            String s = String.format("noWeekDateSupport: got %04d-%02d-%02d, expected %4d-12-31%n",
                                      gcal.get(YEAR),
                                      gcal.get(MONTH)+1,
-                                     gcal.get(DAY_OF_MONTH));
+                                     gcal.get(DAY_OF_MONTH),
+                                     expectedYear);
             throw new RuntimeException(s);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Calendar/JapaneseEraNameTest.java	Sat Apr 13 01:57:11 2019 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2019, 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
+ * @summary Test the localized Japanese new era name (May 1st. 2019-)
+ *      is retrieved no matter CLDR provider contains the name or not.
+ * @run testng/othervm 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;
+
+    static {
+        c = Calendar.getInstance(new Locale("ja","JP","JP"));
+        c.set(ERA, 5);
+        c.set(YEAR, 1);
+        c.set(MONTH, MAY);
+        c.set(DAY_OF_MONTH, 1);
+    }
+
+    @DataProvider(name="names")
+    Object[][] names() {
+        return new Object[][] {
+            // type,    locale,  name
+            { LONG,     JAPAN,   "\u5143\u53f7" }, // NewEra
+            { LONG,     US,      "NewEra" },
+            { SHORT,    JAPAN,   "N" },
+            { SHORT,    US,      "N" },
+        };
+    }
+
+    @Test(dataProvider="names")
+    public void testJapaneseNewEraName(int type, Locale locale, String expected) {
+        assertEquals(c.getDisplayName(ERA, type, locale), expected);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/Calendar/JapaneseLenientEraTest.java	Sat Apr 13 01:57:11 2019 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019, 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 8206120
+ * @summary Test whether lenient era is accepted in JapaneseImperialCalendar
+ * @run testng/othervm JapaneseLenientEraTest
+ */
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+
+@Test
+public class JapaneseLenientEraTest {
+
+    @DataProvider(name="lenientEra")
+    Object[][] names() {
+        return new Object[][] {
+            // lenient era/year, strict era/year
+            { "Meiji 123", "Heisei 2" },
+            { "Showa 65", "Heisei 2" },
+            { "Heisei 32", "NewEra 2" }, // NewEra
+        };
+    }
+
+    @Test(dataProvider="lenientEra")
+    public void testLenientEra(String lenient, String strict) throws Exception {
+        Locale loc = new Locale.Builder().setUnicodeLocaleKeyword("ca","japanese").build();
+        Calendar c = Calendar.getInstance(loc);
+        DateFormat df = new SimpleDateFormat("GGGG y-M-d", Locale.ROOT);
+        df.setCalendar(c);
+        Date lenDate = df.parse(lenient + "-01-01");
+        df.setLenient(false);
+        Date strDate = df.parse(strict + "-01-01");
+        assertEquals(lenDate, strDate);
+    }
+}