8076287: Performance degradation observed with TimeZone Benchmark
Reviewed-by: okutsu
This commit is contained in:
parent
41b53b0d3c
commit
5b2c289414
@ -47,6 +47,7 @@ import java.util.Calendar;
|
|||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -250,17 +251,17 @@ public class LocaleResources {
|
|||||||
return (String) localeName;
|
return (String) localeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] getTimeZoneNames(String key, int size) {
|
String[] getTimeZoneNames(String key) {
|
||||||
String[] names = null;
|
String[] names = null;
|
||||||
String cacheKey = TIME_ZONE_NAMES + size + '.' + key;
|
String cacheKey = TIME_ZONE_NAMES + '.' + key;
|
||||||
|
|
||||||
removeEmptyReferences();
|
removeEmptyReferences();
|
||||||
ResourceReference data = cache.get(cacheKey);
|
ResourceReference data = cache.get(cacheKey);
|
||||||
|
|
||||||
if (data == null || ((names = (String[]) data.get()) == null)) {
|
if (Objects.isNull(data) || Objects.isNull((names = (String[]) data.get()))) {
|
||||||
TimeZoneNamesBundle tznb = localeData.getTimeZoneNames(locale);
|
TimeZoneNamesBundle tznb = localeData.getTimeZoneNames(locale);
|
||||||
if (tznb.containsKey(key)) {
|
if (tznb.containsKey(key)) {
|
||||||
names = tznb.getStringArray(key, size);
|
names = tznb.getStringArray(key);
|
||||||
cache.put(cacheKey,
|
cache.put(cacheKey,
|
||||||
new ResourceReference(cacheKey, (Object) names, referenceQueue));
|
new ResourceReference(cacheKey, (Object) names, referenceQueue));
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package sun.util.locale.provider;
|
package sun.util.locale.provider;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.spi.TimeZoneNameProvider;
|
import java.util.spi.TimeZoneNameProvider;
|
||||||
@ -95,8 +96,9 @@ public class TimeZoneNameProviderImpl extends TimeZoneNameProvider {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getDisplayName(String id, boolean daylight, int style, Locale locale) {
|
public String getDisplayName(String id, boolean daylight, int style, Locale locale) {
|
||||||
String[] names = getDisplayNameArray(id, 5, locale);
|
String[] names = getDisplayNameArray(id, locale);
|
||||||
if (names != null) {
|
if (Objects.nonNull(names)) {
|
||||||
|
assert names.length >= 7;
|
||||||
int index = daylight ? 3 : 1;
|
int index = daylight ? 3 : 1;
|
||||||
if (style == TimeZone.SHORT) {
|
if (style == TimeZone.SHORT) {
|
||||||
index++;
|
index++;
|
||||||
@ -108,18 +110,18 @@ public class TimeZoneNameProviderImpl extends TimeZoneNameProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getGenericDisplayName(String id, int style, Locale locale) {
|
public String getGenericDisplayName(String id, int style, Locale locale) {
|
||||||
String[] names = getDisplayNameArray(id, 7, locale);
|
String[] names = getDisplayNameArray(id, locale);
|
||||||
if (names != null && names.length >= 7) {
|
if (Objects.nonNull(names)) {
|
||||||
|
assert names.length >= 7;
|
||||||
return names[(style == TimeZone.LONG) ? 5 : 6];
|
return names[(style == TimeZone.LONG) ? 5 : 6];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] getDisplayNameArray(String id, int n, Locale locale) {
|
private String[] getDisplayNameArray(String id, Locale locale) {
|
||||||
if (id == null || locale == null) {
|
Objects.requireNonNull(id);
|
||||||
throw new NullPointerException();
|
Objects.requireNonNull(locale);
|
||||||
}
|
return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getTimeZoneNames(id);
|
||||||
return LocaleProviderAdapter.forType(type).getLocaleResources(locale).getTimeZoneNames(id, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,6 +30,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.spi.TimeZoneNameProvider;
|
import java.util.spi.TimeZoneNameProvider;
|
||||||
@ -100,9 +101,9 @@ public final class TimeZoneNameUtility {
|
|||||||
* Retrieve display names for a time zone ID.
|
* Retrieve display names for a time zone ID.
|
||||||
*/
|
*/
|
||||||
public static String[] retrieveDisplayNames(String id, Locale locale) {
|
public static String[] retrieveDisplayNames(String id, Locale locale) {
|
||||||
if (id == null || locale == null) {
|
Objects.requireNonNull(id);
|
||||||
throw new NullPointerException();
|
Objects.requireNonNull(locale);
|
||||||
}
|
|
||||||
return retrieveDisplayNamesImpl(id, locale);
|
return retrieveDisplayNamesImpl(id, locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,9 +116,12 @@ public final class TimeZoneNameUtility {
|
|||||||
* @return the requested generic time zone display name, or null if not found.
|
* @return the requested generic time zone display name, or null if not found.
|
||||||
*/
|
*/
|
||||||
public static String retrieveGenericDisplayName(String id, int style, Locale locale) {
|
public static String retrieveGenericDisplayName(String id, int style, Locale locale) {
|
||||||
LocaleServiceProviderPool pool =
|
String[] names = retrieveDisplayNamesImpl(id, locale);
|
||||||
LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
|
if (Objects.nonNull(names)) {
|
||||||
return pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale, "generic", style, id);
|
return names[6 - style];
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -130,140 +134,53 @@ public final class TimeZoneNameUtility {
|
|||||||
* @return the requested time zone name, or null if not found.
|
* @return the requested time zone name, or null if not found.
|
||||||
*/
|
*/
|
||||||
public static String retrieveDisplayName(String id, boolean daylight, int style, Locale locale) {
|
public static String retrieveDisplayName(String id, boolean daylight, int style, Locale locale) {
|
||||||
LocaleServiceProviderPool pool =
|
String[] names = retrieveDisplayNamesImpl(id, locale);
|
||||||
LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
|
if (Objects.nonNull(names)) {
|
||||||
return pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale, daylight ? "dst" : "std", style, id);
|
return names[(daylight ? 4 : 2) - style];
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] retrieveDisplayNamesImpl(String id, Locale locale) {
|
private static String[] retrieveDisplayNamesImpl(String id, Locale locale) {
|
||||||
LocaleServiceProviderPool pool =
|
LocaleServiceProviderPool pool =
|
||||||
LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
|
LocaleServiceProviderPool.getPool(TimeZoneNameProvider.class);
|
||||||
|
String[] names;
|
||||||
|
Map<Locale, String[]> perLocale = null;
|
||||||
|
|
||||||
SoftReference<Map<Locale, String[]>> ref = cachedDisplayNames.get(id);
|
SoftReference<Map<Locale, String[]>> ref = cachedDisplayNames.get(id);
|
||||||
if (ref != null) {
|
if (Objects.nonNull(ref)) {
|
||||||
Map<Locale, String[]> perLocale = ref.get();
|
perLocale = ref.get();
|
||||||
if (perLocale != null) {
|
if (Objects.nonNull(perLocale)) {
|
||||||
String[] names = perLocale.get(locale);
|
names = perLocale.get(locale);
|
||||||
if (names != null) {
|
if (Objects.nonNull(names)) {
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id);
|
|
||||||
if (names != null) {
|
|
||||||
perLocale.put(locale, names);
|
|
||||||
}
|
|
||||||
return names;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] names = pool.getLocalizedObject(TimeZoneNameArrayGetter.INSTANCE, locale, id);
|
// build names array
|
||||||
if (names != null) {
|
names = new String[7];
|
||||||
Map<Locale, String[]> perLocale = new ConcurrentHashMap<>();
|
names[0] = id;
|
||||||
perLocale.put(locale, names);
|
for (int i = 1; i <= 6; i ++) {
|
||||||
ref = new SoftReference<>(perLocale);
|
names[i] = pool.getLocalizedObject(TimeZoneNameGetter.INSTANCE, locale,
|
||||||
cachedDisplayNames.put(id, ref);
|
i<5 ? (i<3 ? "std" : "dst") : "generic", i%2, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Objects.isNull(perLocale)) {
|
||||||
|
perLocale = new ConcurrentHashMap<>();
|
||||||
|
}
|
||||||
|
perLocale.put(locale, names);
|
||||||
|
ref = new SoftReference<>(perLocale);
|
||||||
|
cachedDisplayNames.put(id, ref);
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains a localized time zone strings from a TimeZoneNameProvider
|
* Obtains a localized time zone strings from a TimeZoneNameProvider
|
||||||
* implementation.
|
* implementation.
|
||||||
*/
|
*/
|
||||||
private static class TimeZoneNameArrayGetter
|
|
||||||
implements LocaleServiceProviderPool.LocalizedObjectGetter<TimeZoneNameProvider,
|
|
||||||
String[]>{
|
|
||||||
private static final TimeZoneNameArrayGetter INSTANCE =
|
|
||||||
new TimeZoneNameArrayGetter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getObject(TimeZoneNameProvider timeZoneNameProvider,
|
|
||||||
Locale locale,
|
|
||||||
String requestID,
|
|
||||||
Object... params) {
|
|
||||||
assert params.length == 0;
|
|
||||||
|
|
||||||
// First, try to get names with the request ID
|
|
||||||
String[] names = buildZoneStrings(timeZoneNameProvider, locale, requestID);
|
|
||||||
|
|
||||||
if (names == null) {
|
|
||||||
Map<String, String> aliases = ZoneInfo.getAliasTable();
|
|
||||||
|
|
||||||
if (aliases != null) {
|
|
||||||
// Check whether this id is an alias, if so,
|
|
||||||
// look for the standard id.
|
|
||||||
String canonicalID = aliases.get(requestID);
|
|
||||||
if (canonicalID != null) {
|
|
||||||
names = buildZoneStrings(timeZoneNameProvider, locale, canonicalID);
|
|
||||||
}
|
|
||||||
if (names == null) {
|
|
||||||
// There may be a case that a standard id has become an
|
|
||||||
// alias. so, check the aliases backward.
|
|
||||||
names = examineAliases(timeZoneNameProvider, locale,
|
|
||||||
canonicalID == null ? requestID : canonicalID, aliases);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (names != null) {
|
|
||||||
names[0] = requestID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String[] examineAliases(TimeZoneNameProvider tznp, Locale locale,
|
|
||||||
String id,
|
|
||||||
Map<String, String> aliases) {
|
|
||||||
if (aliases.containsValue(id)) {
|
|
||||||
for (Map.Entry<String, String> entry : aliases.entrySet()) {
|
|
||||||
if (entry.getValue().equals(id)) {
|
|
||||||
String alias = entry.getKey();
|
|
||||||
String[] names = buildZoneStrings(tznp, locale, alias);
|
|
||||||
if (names != null) {
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
names = examineAliases(tznp, locale, alias, aliases);
|
|
||||||
if (names != null) {
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String[] buildZoneStrings(TimeZoneNameProvider tznp,
|
|
||||||
Locale locale, String id) {
|
|
||||||
String[] names = new String[5];
|
|
||||||
|
|
||||||
for (int i = 1; i <= 4; i ++) {
|
|
||||||
names[i] = tznp.getDisplayName(id, i>=3, i%2, locale);
|
|
||||||
|
|
||||||
if (names[i] == null) {
|
|
||||||
switch (i) {
|
|
||||||
case 1:
|
|
||||||
// this id seems not localized by this provider
|
|
||||||
return null;
|
|
||||||
case 2:
|
|
||||||
case 4:
|
|
||||||
// If the display name for SHORT is not supplied,
|
|
||||||
// copy the LONG name.
|
|
||||||
names[i] = names[i-1];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
// If the display name for DST is not supplied,
|
|
||||||
// copy the "standard" name.
|
|
||||||
names[3] = names[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TimeZoneNameGetter
|
private static class TimeZoneNameGetter
|
||||||
implements LocaleServiceProviderPool.LocalizedObjectGetter<TimeZoneNameProvider,
|
implements LocaleServiceProviderPool.LocalizedObjectGetter<TimeZoneNameProvider,
|
||||||
String> {
|
String> {
|
||||||
@ -299,18 +216,16 @@ public final class TimeZoneNameUtility {
|
|||||||
private static String examineAliases(TimeZoneNameProvider tznp, Locale locale,
|
private static String examineAliases(TimeZoneNameProvider tznp, Locale locale,
|
||||||
String requestID, String tzid, int style,
|
String requestID, String tzid, int style,
|
||||||
Map<String, String> aliases) {
|
Map<String, String> aliases) {
|
||||||
if (aliases.containsValue(tzid)) {
|
for (Map.Entry<String, String> entry : aliases.entrySet()) {
|
||||||
for (Map.Entry<String, String> entry : aliases.entrySet()) {
|
if (entry.getValue().equals(tzid)) {
|
||||||
if (entry.getValue().equals(tzid)) {
|
String alias = entry.getKey();
|
||||||
String alias = entry.getKey();
|
String name = getName(tznp, locale, requestID, style, alias);
|
||||||
String name = getName(tznp, locale, requestID, style, alias);
|
if (name != null) {
|
||||||
if (name != null) {
|
return name;
|
||||||
return name;
|
}
|
||||||
}
|
name = examineAliases(tznp, locale, requestID, alias, style, aliases);
|
||||||
name = examineAliases(tznp, locale, requestID, alias, style, aliases);
|
if (name != null) {
|
||||||
if (name != null) {
|
return name;
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ import java.util.Map;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,26 +61,6 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public abstract class TimeZoneNamesBundle extends OpenListResourceBundle {
|
public abstract class TimeZoneNamesBundle extends OpenListResourceBundle {
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a String array containing time zone names. The String array has
|
|
||||||
* at most size elements.
|
|
||||||
*
|
|
||||||
* @param key the time zone ID for which names are obtained
|
|
||||||
* @param size the requested size of array for names
|
|
||||||
* @return a String array containing names
|
|
||||||
*/
|
|
||||||
public String[] getStringArray(String key, int size) {
|
|
||||||
String[] names = handleGetObject(key, size);
|
|
||||||
if ((names == null || names.length != size) && parent != null) {
|
|
||||||
names = ((TimeZoneNamesBundle)parent).getStringArray(key, size);
|
|
||||||
}
|
|
||||||
if (names == null) {
|
|
||||||
throw new MissingResourceException("no time zone names", getClass().getName(), key);
|
|
||||||
}
|
|
||||||
return names;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps time zone IDs to locale-specific names.
|
* Maps time zone IDs to locale-specific names.
|
||||||
* The value returned is an array of five strings:
|
* The value returned is an array of five strings:
|
||||||
@ -89,6 +70,8 @@ public abstract class TimeZoneNamesBundle extends OpenListResourceBundle {
|
|||||||
* <li>The short name of the time zone in standard time (localized).
|
* <li>The short name of the time zone in standard time (localized).
|
||||||
* <li>The long name of the time zone in daylight savings time (localized).
|
* <li>The long name of the time zone in daylight savings time (localized).
|
||||||
* <li>The short name of the time zone in daylight savings time (localized).
|
* <li>The short name of the time zone in daylight savings time (localized).
|
||||||
|
* <li>The long name of the time zone in generic form (localized).
|
||||||
|
* <li>The short name of the time zone in generic form (localized).
|
||||||
* </ul>
|
* </ul>
|
||||||
* The localized names come from the subclasses's
|
* The localized names come from the subclasses's
|
||||||
* <code>getContents</code> implementations, while the time zone
|
* <code>getContents</code> implementations, while the time zone
|
||||||
@ -96,16 +79,12 @@ public abstract class TimeZoneNamesBundle extends OpenListResourceBundle {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object handleGetObject(String key) {
|
public Object handleGetObject(String key) {
|
||||||
return handleGetObject(key, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String[] handleGetObject(String key, int n) {
|
|
||||||
String[] contents = (String[]) super.handleGetObject(key);
|
String[] contents = (String[]) super.handleGetObject(key);
|
||||||
if (contents == null) {
|
if (Objects.isNull(contents)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int clen = Math.min(n - 1, contents.length);
|
int clen = contents.length;
|
||||||
String[] tmpobj = new String[clen+1];
|
String[] tmpobj = new String[7];
|
||||||
tmpobj[0] = key;
|
tmpobj[0] = key;
|
||||||
System.arraycopy(contents, 0, tmpobj, 1, clen);
|
System.arraycopy(contents, 0, tmpobj, 1, clen);
|
||||||
return tmpobj;
|
return tmpobj;
|
||||||
|
@ -47,7 +47,8 @@ public final class TimeZoneNames_en_IE extends TimeZoneNamesBundle {
|
|||||||
protected final Object[][] getContents() {
|
protected final Object[][] getContents() {
|
||||||
return new Object[][] {
|
return new Object[][] {
|
||||||
{"Europe/London", new String[] {"Greenwich Mean Time", "GMT",
|
{"Europe/London", new String[] {"Greenwich Mean Time", "GMT",
|
||||||
"Irish Summer Time", "IST" /*Dublin*/}},
|
"Irish Summer Time", "IST", /*Dublin*/
|
||||||
|
"Irish Time", "IT" /*Dublin*/}},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.text.*;
|
import java.text.*;
|
||||||
|
import java.time.format.TextStyle;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import sun.util.locale.provider.*;
|
import sun.util.locale.provider.*;
|
||||||
import sun.util.resources.*;
|
import sun.util.resources.*;
|
||||||
@ -42,6 +43,7 @@ public class TimeZoneNameProviderTest extends ProviderTest {
|
|||||||
test2();
|
test2();
|
||||||
test3();
|
test3();
|
||||||
aliasTest();
|
aliasTest();
|
||||||
|
genericFallbackTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void test1() {
|
void test1() {
|
||||||
@ -169,9 +171,9 @@ public class TimeZoneNameProviderTest extends ProviderTest {
|
|||||||
for (int style : new int[] { TimeZone.LONG, TimeZone.SHORT }) {
|
for (int style : new int[] { TimeZone.LONG, TimeZone.SHORT }) {
|
||||||
String osakaStd = tz.getDisplayName(false, style, OSAKA);
|
String osakaStd = tz.getDisplayName(false, style, OSAKA);
|
||||||
if (osakaStd != null) {
|
if (osakaStd != null) {
|
||||||
// No API for getting generic time zone names
|
String generic = tz.toZoneId().getDisplayName(
|
||||||
String generic = TimeZoneNameUtility.retrieveGenericDisplayName(tzname,
|
style == TimeZone.LONG ? TextStyle.FULL : TextStyle.SHORT,
|
||||||
style, GENERIC);
|
GENERIC);
|
||||||
String expected = "Generic " + osakaStd;
|
String expected = "Generic " + osakaStd;
|
||||||
if (!expected.equals(generic)) {
|
if (!expected.equals(generic)) {
|
||||||
throw new RuntimeException("Wrong generic name: got=\"" + generic
|
throw new RuntimeException("Wrong generic name: got=\"" + generic
|
||||||
@ -230,4 +232,20 @@ public class TimeZoneNameProviderTest extends ProviderTest {
|
|||||||
throw new RuntimeException("Provider's localized name is not available for an alias ID: "+JAPAN+". result: "+japan+" expected: "+JST_IN_OSAKA);
|
throw new RuntimeException("Provider's localized name is not available for an alias ID: "+JAPAN+". result: "+japan+" expected: "+JST_IN_OSAKA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests whether generic names can be retrieved through fallback.
|
||||||
|
* The test assumes the provider impl for OSAKA locale does NOT
|
||||||
|
* provide generic names.
|
||||||
|
*/
|
||||||
|
final String PT = "PT"; // SHORT generic name for "America/Los_Angeles"
|
||||||
|
void genericFallbackTest() {
|
||||||
|
String generic =
|
||||||
|
TimeZone.getTimeZone(LATIME)
|
||||||
|
.toZoneId()
|
||||||
|
.getDisplayName(TextStyle.SHORT, OSAKA);
|
||||||
|
if (!PT.equals(generic)) {
|
||||||
|
throw new RuntimeException("Generic name fallback failed. got: "+generic);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user