< prev index next >

src/java.base/share/classes/sun/util/cldr/CLDRTimeZoneNameProviderImpl.java

Print this page
rev 57986 : 8234347: "Turkey" meta time zone does not generate composed localized names
8236548: Localized time zone name inconsistency between English and other locales
Reviewed-by:

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, 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.  Oracle designates this

@@ -32,11 +32,10 @@
 import java.util.Locale;
 import java.util.Objects;
 import java.util.ResourceBundle;
 import java.util.Set;
 import java.util.TimeZone;
-import java.util.stream.Collectors;
 import sun.util.calendar.ZoneInfoFile;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.locale.provider.LocaleResources;
 import sun.util.locale.provider.TimeZoneNameProviderImpl;
 import sun.util.locale.provider.TimeZoneNameUtility;

@@ -71,12 +70,10 @@
         super(type, langtags);
     }
 
     @Override
     protected String[] getDisplayNameArray(String id, Locale locale) {
-        // Use English for the ROOT locale
-        locale = locale.equals(Locale.ROOT) ? Locale.ENGLISH : locale;
         String[] namesSuper = super.getDisplayNameArray(id, locale);
 
         if (namesSuper == null) {
             // try canonical id instead
             namesSuper = super.getDisplayNameArray(

@@ -92,16 +89,16 @@
             for(int i = INDEX_STD_LONG; i < namesSuper.length; i++) { // index 0 is the 'id' itself
                 switch (namesSuper[i]) {
                 case "":
                     // Fill in empty elements
                     deriveFallbackName(namesSuper, i, locale,
-                                       !exists(namesSuper, INDEX_DST_LONG));
+                                       !TimeZone.getTimeZone(id).useDaylightTime());
                     break;
                 case NO_INHERITANCE_MARKER:
                     // CLDR's "no inheritance marker"
                     namesSuper[i] = toGMTFormat(id, i == INDEX_DST_LONG || i == INDEX_DST_SHORT,
-                                                i % 2 != 0, locale);
+                                                locale);
                     break;
                 default:
                     break;
                 }
             }

@@ -119,28 +116,23 @@
         return null;
     }
 
     @Override
     protected String[][] getZoneStrings(Locale locale) {
-        // Use English for the ROOT locale
-        locale = locale.equals(Locale.ROOT) ? Locale.ENGLISH : locale;
         String[][] ret = super.getZoneStrings(locale);
 
         // Fill in for the empty names.
-        // English names are prefilled for performance.
-        if (!locale.equals(Locale.ENGLISH) &&
-            !locale.equals(Locale.US)) {
             for (int zoneIndex = 0; zoneIndex < ret.length; zoneIndex++) {
                 deriveFallbackNames(ret[zoneIndex], locale);
             }
-        }
         return ret;
     }
 
     // Derive fallback time zone name according to LDML's logic
     private void deriveFallbackNames(String[] names, Locale locale) {
-        boolean noDST = !exists(names, INDEX_DST_LONG);
+        boolean noDST = !TimeZone.getTimeZone(names[0]).useDaylightTime();
+
         for (int i = INDEX_STD_LONG; i <= INDEX_GEN_SHORT; i++) {
             deriveFallbackName(names, i, locale, noDST);
         }
     }
 

@@ -150,15 +142,29 @@
         if (exists(names, index)) {
             if (names[index].equals(NO_INHERITANCE_MARKER)) {
                 // CLDR's "no inheritance marker"
                 names[index] = toGMTFormat(id,
                                     index == INDEX_DST_LONG || index == INDEX_DST_SHORT,
-                                    index % 2 != 0, locale);
+                                    locale);
             }
             return;
         }
 
+        // Check parent locale first
+        if (!exists(names, index)) {
+            CLDRLocaleProviderAdapter clpa = (CLDRLocaleProviderAdapter)LocaleProviderAdapter.forType(Type.CLDR);
+            var cands = clpa.getCandidateLocales("", locale);
+            if (cands.size() > 1) {
+                var parentLoc = cands.get(1); // immediate parent locale
+                String[] parentNames = super.getDisplayNameArray(id, parentLoc);
+                if (parentNames != null && !parentNames[index].isEmpty()) {
+                    names[index] = parentNames[index];
+                    return;
+                }
+            }
+        }
+
         // Check if COMPAT can substitute the name
         if (LocaleProviderAdapter.getAdapterPreference().contains(Type.JRE)) {
             String[] compatNames = (String[])LocaleProviderAdapter.forJRE()
                 .getLocaleResources(mapChineseLocale(locale))
                 .getTimeZoneNames(id);

@@ -171,25 +177,23 @@
                 }
                 return;
             }
         }
 
-        // Type Fallback
-        if (noDST && typeFallback(names, index)) {
+        // Region Fallback
+        if (regionFormatFallback(names, index, locale)) {
             return;
         }
 
-        // Region Fallback
-        if (regionFormatFallback(names, index, locale)) {
+        // Type Fallback
+        if (noDST && typeFallback(names, index)) {
             return;
         }
 
         // last resort
-        if (!id.toUpperCase(Locale.ROOT).startsWith("UT")) {
             names[index] = toGMTFormat(id,
                                        index == INDEX_DST_LONG || index == INDEX_DST_SHORT,
-                                       index % 2 != 0,
                                        locale);
             // aliases of "GMT" timezone.
             if ((exists(names, INDEX_STD_LONG)) && (id.startsWith("Etc/")
                     || id.startsWith("GMT") || id.startsWith("Greenwich"))) {
                 switch (id) {

@@ -204,27 +208,26 @@
                     names[INDEX_DST_LONG] = names[INDEX_GEN_LONG] = names[INDEX_STD_LONG];
                     break;
                 }
             }
         }
-    }
 
     private boolean exists(String[] names, int index) {
         return Objects.nonNull(names)
                 && Objects.nonNull(names[index])
                 && !names[index].isEmpty();
     }
 
     private boolean typeFallback(String[] names, int index) {
         // check generic
         int genIndex = INDEX_GEN_SHORT - index % 2;
-        if (!exists(names, index) && exists(names, genIndex)) {
+        if (!exists(names, index) && exists(names, genIndex) && !names[genIndex].startsWith("GMT")) {
             names[index] = names[genIndex];
         } else {
             // check standard
             int stdIndex = INDEX_STD_SHORT - index % 2;
-            if (!exists(names, index) && exists(names, stdIndex)) {
+            if (!exists(names, index) && exists(names, stdIndex) && !names[stdIndex].startsWith("GMT")) {
                 names[index] = names[stdIndex];
             }
         }
 
         return exists(names, index);

@@ -233,10 +236,11 @@
     private boolean regionFormatFallback(String[] names, int index, Locale l) {
         String id = names[INDEX_TZID];
         LocaleResources lr = LocaleProviderAdapter.forType(Type.CLDR).getLocaleResources(l);
         ResourceBundle fd = lr.getJavaTimeFormatData();
 
+        id = TimeZoneNameUtility.canonicalTZID(id).orElse(id);
         String rgn = (String) lr.getTimeZoneNames("timezone.excity." + id);
         if (rgn == null && !id.startsWith("Etc") && !id.startsWith("SystemV")) {
             int slash = id.lastIndexOf('/');
             if (slash > 0) {
                 rgn = id.substring(slash + 1).replaceAll("_", " ");

@@ -262,11 +266,11 @@
         }
 
         return exists(names, index);
     }
 
-    private String toGMTFormat(String id, boolean daylight, boolean isShort, Locale l) {
+    private String toGMTFormat(String id, boolean daylight, Locale l) {
         TimeZone tz = ZoneInfoFile.getZoneInfo(id);
         int offset = (tz.getRawOffset() + (daylight ? tz.getDSTSavings() : 0)) / 60000;
         LocaleResources lr = LocaleProviderAdapter.forType(Type.CLDR).getLocaleResources(l);
         ResourceBundle fd = lr.getJavaTimeFormatData();
 

@@ -281,11 +285,11 @@
             } else {
                 hourFormat = hourFormat.substring(hourFormat.indexOf(";") + 1);
                 offset = -offset;
             }
             hourFormat = hourFormat
-                .replaceFirst("H+", (isShort ? "\\%1\\$d" : "\\%1\\$02d"))
+                .replaceFirst("H+", "\\%1\\$02d")
                 .replaceFirst("m+", "\\%2\\$02d");
             return MessageFormat.format(gmtFormat,
                     String.format(l, hourFormat, offset / 60, offset % 60));
         }
     }
< prev index next >