changeset 15884:8aef19dd322b

8146750: java.time.Month.getDisplayName() return incorrect narrow names with JRE provider on locale de,de_DE,en_US. Reviewed-by: okutsu, rriggs, naoto, peytoia
author rgoel
date Fri, 21 Oct 2016 11:33:37 +0900
parents fc62eb6bf650
children 160db4882087
files src/java.base/share/classes/java/time/format/DateTimeTextProvider.java test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java
diffstat 2 files changed, 181 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java	Thu Oct 20 13:27:48 2016 -0700
+++ b/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java	Fri Oct 21 11:33:37 2016 +0900
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -349,25 +349,40 @@
 
         if (field == MONTH_OF_YEAR) {
             for (TextStyle textStyle : TextStyle.values()) {
-                Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
-                        "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
                 Map<Long, String> map = new HashMap<>();
-                if (displayNames != null) {
-                    for (Entry<String, Integer> entry : displayNames.entrySet()) {
-                        map.put((long) (entry.getValue() + 1), entry.getKey());
-                    }
-
-                } else {
-                    // Narrow names may have duplicated names, such as "J" for January, Jun, July.
-                    // Get names one by one in that case.
+                // Narrow names may have duplicated names, such as "J" for January, June, July.
+                // Get names one by one in that case.
+                if ((textStyle.equals(TextStyle.NARROW) ||
+                        textStyle.equals(TextStyle.NARROW_STANDALONE))) {
                     for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
                         String name;
                         name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
-                                "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+                                "gregory", Calendar.MONTH,
+                                month, textStyle.toCalendarStyle(), locale);
                         if (name == null) {
                             break;
                         }
-                        map.put((long) (month + 1), name);
+                        map.put((month + 1L), name);
+                    }
+                } else {
+                    Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+                            "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
+                    if (displayNames != null) {
+                        for (Entry<String, Integer> entry : displayNames.entrySet()) {
+                            map.put((long)(entry.getValue() + 1), entry.getKey());
+                        }
+                    } else {
+                        // Although probability is very less, but if other styles have duplicate names.
+                        // Get names one by one in that case.
+                        for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
+                            String name;
+                            name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+                                    "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+                            if (name == null) {
+                                break;
+                            }
+                            map.put((month + 1L), name);
+                        }
                     }
                 }
                 if (!map.isEmpty()) {
@@ -379,26 +394,41 @@
 
         if (field == DAY_OF_WEEK) {
             for (TextStyle textStyle : TextStyle.values()) {
-                Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
-                        "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
                 Map<Long, String> map = new HashMap<>();
-                if (displayNames != null) {
-                    for (Entry<String, Integer> entry : displayNames.entrySet()) {
-                        map.put((long)toWeekDay(entry.getValue()), entry.getKey());
-                    }
-
-                } else {
-                    // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
-                    // Get names one by one in that case.
+                // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
+                // Get names one by one in that case.
+                if ((textStyle.equals(TextStyle.NARROW) ||
+                        textStyle.equals(TextStyle.NARROW_STANDALONE))) {
                     for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
                         String name;
                         name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
-                            "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+                                "gregory", Calendar.DAY_OF_WEEK,
+                                wday, textStyle.toCalendarStyle(), locale);
                         if (name == null) {
                             break;
                         }
                         map.put((long)toWeekDay(wday), name);
                     }
+                } else {
+                    Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+                            "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
+                    if (displayNames != null) {
+                        for (Entry<String, Integer> entry : displayNames.entrySet()) {
+                            map.put((long)toWeekDay(entry.getValue()), entry.getKey());
+                        }
+                    } else {
+                        // Although probability is very less, but if other styles have duplicate names.
+                        // Get names one by one in that case.
+                        for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
+                            String name;
+                            name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+                                    "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+                            if (name == null) {
+                                break;
+                            }
+                            map.put((long)toWeekDay(wday), name);
+                        }
+                    }
                 }
                 if (!map.isEmpty()) {
                     styleMap.put(textStyle, map);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java	Fri Oct 21 11:33:37 2016 +0900
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package test.java.time.format;
+
+/*
+ * @test
+ * @bug 8146750
+ * @summary Test Narrow and NarrowStandalone month names are retrieved correctly.
+ */
+import static org.testng.Assert.assertEquals;
+
+import java.time.DayOfWeek;
+import java.time.Month;
+import java.time.format.TextStyle;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class TestNarrowMonthNamesAndDayNames {
+
+    static {
+        System.setProperty("java.locale.providers", "COMPAT");
+    }
+
+    private static final List<Month> MONTHVALUES = Arrays.asList(Month.values());
+    private static final List<DayOfWeek> DAYVALUES = Arrays.asList(DayOfWeek.values());
+    private static final List<TextStyle> TEXTSTYLELIST = Arrays.asList(TextStyle.NARROW,
+            TextStyle.NARROW_STANDALONE);
+    private static final List<Locale> LOCARR = Arrays.asList(Locale.US,
+            Locale.GERMANY,
+            Locale.FRANCE,
+            new Locale("no", "NO"));
+
+    /**
+     * Locale en_US, de_DE, fr_FR, no_NO will have same Narrow and
+     * Narrow_Standalone month Names for COMPAT Provider.
+     */
+    @DataProvider(name = "MonthNarrows")
+    public Object[][] monthNameData() {
+        return new Object[][]{{new String[]{
+            "J",
+            "F",
+            "M",
+            "A",
+            "M",
+            "J",
+            "J",
+            "A",
+            "S",
+            "O",
+            "N",
+            "D"
+        }},};
+    }
+
+    //-----------------------------------------------------------------------
+    // Check Narrow and Narrow_standalone month name values
+    //-----------------------------------------------------------------------
+    @Test(dataProvider = "MonthNarrows")
+    public void compareMonthNarrowValues(String[] monthNarrowExpected) {
+        LOCARR.forEach((loc) -> {
+            TEXTSTYLELIST.forEach((style) -> {
+                MONTHVALUES.forEach((value) -> {
+                    String result = value.getDisplayName(style, loc);
+                    int index = value.ordinal();
+                    assertEquals(result, monthNarrowExpected[index], "Test failed"
+                            + " for COMPAT Provider for locale "
+                            + loc + " for style " + style.name()
+                            + " with Month value " + value.name());
+                });
+            });
+        });
+    }
+
+    /**
+     * Locale en_US, de_DE, fr_FR, no_NO will have different Narrow and
+     * Narrow_Standalone Day Names for COMPAT Provider.
+     */
+    @DataProvider(name = "DayNarrows")
+    public Object[][] dayNameData() {
+        return new Object[][]{
+            {Locale.US, new String[]{"M", "T", "W", "T", "F", "S", "S"}},
+            {Locale.GERMANY, new String[]{"M", "D", "M", "D", "F", "S", "S"}},
+            {Locale.FRANCE, new String[]{"L", "M", "M", "J", "V", "S", "D"}},
+            {new Locale("no", "NO"), new String[]{"M", "T", "O", "T", "F", "L", "S"}},};
+    }
+
+    //-----------------------------------------------------------------------
+    // Check Narrow and Narrow_standalone Day name values
+    //-----------------------------------------------------------------------
+    @Test(dataProvider = "DayNarrows")
+    public void compareDayNarrowValues(Locale locale, String[] dayNarrowExpected) {
+        TEXTSTYLELIST.forEach((style) -> {
+            DAYVALUES.forEach((value) -> {
+                String result = value.getDisplayName(style, locale);
+                int index = value.ordinal();
+                assertEquals(result, dayNarrowExpected[index], "Test failed"
+                        + " for COMPAT Provider for locale "
+                        + locale + " for style " + style.name()
+                        + " with Day value " + value.name());
+            });
+        });
+    }
+}