< 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 >