ICU-10934 The tz database abbreviaion support in ICU4J
X-SVN-Rev: 36081
This commit is contained in:
parent
ae3f6f13a4
commit
a53477ee99
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -263,6 +263,7 @@ icu4j/main/classes/core/.settings/edu.umd.cs.findbugs.core.prefs -text
|
||||
icu4j/main/classes/core/.settings/org.eclipse.core.resources.prefs -text
|
||||
icu4j/main/classes/core/.settings/org.eclipse.jdt.core.prefs -text
|
||||
icu4j/main/classes/core/manifest.stub -text
|
||||
icu4j/main/classes/core/src/com/ibm/icu/impl/TZDBTimeZoneNames.java -text
|
||||
icu4j/main/classes/currdata/.externalToolBuilders/copy-data-currdata.launch -text
|
||||
icu4j/main/classes/currdata/.settings/org.eclipse.core.resources.prefs -text
|
||||
icu4j/main/classes/currdata/.settings/org.eclipse.jdt.core.prefs -text
|
||||
|
@ -0,0 +1,396 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.ibm.icu.impl.TextTrieMap.ResultHandler;
|
||||
import com.ibm.icu.text.TimeZoneNames;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
import com.ibm.icu.util.UResourceBundle;
|
||||
|
||||
/**
|
||||
* Yet another TimeZoneNames implementation based on the tz database.
|
||||
* This implementation contains only tz abbreviations (short standard
|
||||
* and daylight names) for each metazone.
|
||||
*
|
||||
* The data file $ICU4C_ROOT/source/data/zone/tzdbNames.txt contains
|
||||
* the metazone - abbreviations mapping data (manually edited).
|
||||
*
|
||||
* Note: The abbreviations in the tz database are not necessarily
|
||||
* unique. For example, parsing abbreviation "IST" is ambiguous
|
||||
* (can be parsed as India Standard Time or Israel Standard Time).
|
||||
* The data file (tzdbNames.txt) contains regional mapping, and
|
||||
* the locale in the constructor is used as a hint for resolving
|
||||
* these ambiguous names.
|
||||
*/
|
||||
public class TZDBTimeZoneNames extends TimeZoneNames {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final ConcurrentHashMap<String, TZDBNames> TZDB_NAMES_MAP =
|
||||
new ConcurrentHashMap<String, TZDBNames>();
|
||||
|
||||
private static volatile TextTrieMap<TZDBNameInfo> TZDB_NAMES_TRIE = null;
|
||||
|
||||
private static final ICUResourceBundle ZONESTRINGS;
|
||||
static {
|
||||
UResourceBundle bundle = ICUResourceBundle
|
||||
.getBundleInstance(ICUResourceBundle.ICU_ZONE_BASE_NAME, "tzdbNames");
|
||||
ZONESTRINGS = (ICUResourceBundle)bundle.get("zoneStrings");
|
||||
}
|
||||
|
||||
private ULocale _locale;
|
||||
private transient volatile String _region;
|
||||
|
||||
public TZDBTimeZoneNames(ULocale loc) {
|
||||
_locale = loc;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.icu.text.TimeZoneNames#getAvailableMetaZoneIDs()
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getAvailableMetaZoneIDs() {
|
||||
return TimeZoneNamesImpl._getAvailableMetaZoneIDs();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.icu.text.TimeZoneNames#getAvailableMetaZoneIDs(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getAvailableMetaZoneIDs(String tzID) {
|
||||
return TimeZoneNamesImpl._getAvailableMetaZoneIDs(tzID);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.icu.text.TimeZoneNames#getMetaZoneID(java.lang.String, long)
|
||||
*/
|
||||
@Override
|
||||
public String getMetaZoneID(String tzID, long date) {
|
||||
return TimeZoneNamesImpl._getMetaZoneID(tzID, date);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.icu.text.TimeZoneNames#getReferenceZoneID(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String getReferenceZoneID(String mzID, String region) {
|
||||
return TimeZoneNamesImpl._getReferenceZoneID(mzID, region);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.icu.text.TimeZoneNames#getMetaZoneDisplayName(java.lang.String,
|
||||
* com.ibm.icu.text.TimeZoneNames.NameType)
|
||||
*/
|
||||
@Override
|
||||
public String getMetaZoneDisplayName(String mzID, NameType type) {
|
||||
if (mzID == null || mzID.length() == 0 ||
|
||||
(type != NameType.SHORT_STANDARD && type != NameType.SHORT_DAYLIGHT)) {
|
||||
return null;
|
||||
}
|
||||
return getMetaZoneNames(mzID).getName(type);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.icu.text.TimeZoneNames#getTimeZoneDisplayName(java.lang.String,
|
||||
* com.ibm.icu.text.TimeZoneNames.NameType)
|
||||
*/
|
||||
@Override
|
||||
public String getTimeZoneDisplayName(String tzID, NameType type) {
|
||||
// No abbreviations associated a zone directly for now.
|
||||
return null;
|
||||
}
|
||||
|
||||
// /* (non-Javadoc)
|
||||
// * @see com.ibm.icu.text.TimeZoneNames#getExemplarLocationName(java.lang.String)
|
||||
// */
|
||||
// public String getExemplarLocationName(String tzID) {
|
||||
// return super.getExemplarLocationName(tzID);
|
||||
// }
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.icu.text.TimeZoneNames#find(java.lang.CharSequence, int, java.util.EnumSet)
|
||||
*/
|
||||
@Override
|
||||
public Collection<MatchInfo> find(CharSequence text, int start, EnumSet<NameType> nameTypes) {
|
||||
if (text == null || text.length() == 0 || start < 0 || start >= text.length()) {
|
||||
throw new IllegalArgumentException("bad input text or range");
|
||||
}
|
||||
|
||||
prepareFind();
|
||||
TZDBNameSearchHandler handler = new TZDBNameSearchHandler(nameTypes, getTargetRegion());
|
||||
TZDB_NAMES_TRIE.find(text, start, handler);
|
||||
return handler.getMatches();
|
||||
}
|
||||
|
||||
private static class TZDBNames {
|
||||
public static final TZDBNames EMPTY_TZDBNAMES = new TZDBNames(null, null);
|
||||
|
||||
private String[] _names;
|
||||
private String[] _parseRegions;
|
||||
private static final String[] KEYS = {"ss", "sd"};
|
||||
|
||||
private TZDBNames(String[] names, String[] parseRegions) {
|
||||
_names = names;
|
||||
_parseRegions = parseRegions;
|
||||
}
|
||||
|
||||
static TZDBNames getInstance(ICUResourceBundle zoneStrings, String key) {
|
||||
if (zoneStrings == null || key == null || key.length() == 0) {
|
||||
return EMPTY_TZDBNAMES;
|
||||
}
|
||||
|
||||
ICUResourceBundle table = null;
|
||||
try {
|
||||
table = (ICUResourceBundle)zoneStrings.get(key);
|
||||
} catch (MissingResourceException e) {
|
||||
return EMPTY_TZDBNAMES;
|
||||
}
|
||||
|
||||
boolean isEmpty = true;
|
||||
String[] names = new String[KEYS.length];
|
||||
for (int i = 0; i < names.length; i++) {
|
||||
try {
|
||||
names[i] = table.getString(KEYS[i]);
|
||||
isEmpty = false;
|
||||
} catch (MissingResourceException e) {
|
||||
names[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (isEmpty) {
|
||||
return EMPTY_TZDBNAMES;
|
||||
}
|
||||
|
||||
String[] parseRegions = null;
|
||||
try {
|
||||
ICUResourceBundle regionsRes = (ICUResourceBundle)table.get("parseRegions");
|
||||
if (regionsRes.getType() == UResourceBundle.STRING) {
|
||||
parseRegions = new String[1];
|
||||
parseRegions[0] = regionsRes.getString();
|
||||
} else if (regionsRes.getType() == UResourceBundle.ARRAY) {
|
||||
parseRegions = regionsRes.getStringArray();
|
||||
}
|
||||
} catch (MissingResourceException e) {
|
||||
// fall through
|
||||
}
|
||||
|
||||
return new TZDBNames(names, parseRegions);
|
||||
}
|
||||
|
||||
String getName(NameType type) {
|
||||
if (_names == null) {
|
||||
return null;
|
||||
}
|
||||
String name = null;
|
||||
switch (type) {
|
||||
case SHORT_STANDARD:
|
||||
name = _names[0];
|
||||
break;
|
||||
case SHORT_DAYLIGHT:
|
||||
name = _names[1];
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
String[] getParseRegions() {
|
||||
return _parseRegions;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TZDBNameInfo {
|
||||
String mzID;
|
||||
NameType type;
|
||||
boolean ambiguousType;
|
||||
String[] parseRegions;
|
||||
}
|
||||
|
||||
private static class TZDBNameSearchHandler implements ResultHandler<TZDBNameInfo> {
|
||||
private EnumSet<NameType> _nameTypes;
|
||||
private Collection<MatchInfo> _matches;
|
||||
private String _region;
|
||||
|
||||
TZDBNameSearchHandler(EnumSet<NameType> nameTypes, String region) {
|
||||
_nameTypes = nameTypes;
|
||||
assert region != null;
|
||||
_region = region;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.ibm.icu.impl.TextTrieMap.ResultHandler#handlePrefixMatch(int,
|
||||
* java.util.Iterator)
|
||||
*/
|
||||
public boolean handlePrefixMatch(int matchLength, Iterator<TZDBNameInfo> values) {
|
||||
TZDBNameInfo match = null;
|
||||
TZDBNameInfo defaultRegionMatch = null;
|
||||
|
||||
while (values.hasNext()) {
|
||||
TZDBNameInfo ninfo = values.next();
|
||||
|
||||
if (_nameTypes != null && !_nameTypes.contains(ninfo.type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Some tz database abbreviations are ambiguous. For example,
|
||||
// CST means either Central Standard Time or China Standard Time.
|
||||
// Unlike CLDR time zone display names, this implementation
|
||||
// does not use unique names. And TimeZoneFormat does not expect
|
||||
// multiple results returned for the same time zone type.
|
||||
// For this reason, this implementation resolve one among same
|
||||
// zone type with a same name at this level.
|
||||
if (ninfo.parseRegions == null) {
|
||||
// parseRegions == null means this is the default metazone
|
||||
// mapping for the abbreviation.
|
||||
if (defaultRegionMatch == null) {
|
||||
match = defaultRegionMatch = ninfo;
|
||||
}
|
||||
} else {
|
||||
boolean matchRegion = false;
|
||||
// non-default metazone mapping for an abbreviation
|
||||
// comes with applicable regions. For example, the default
|
||||
// metazone mapping for "CST" is America_Central,
|
||||
// but if region is one of CN/MO/TW, "CST" is parsed
|
||||
// as metazone China (China Standard Time).
|
||||
for (String region : ninfo.parseRegions) {
|
||||
if (_region.equals(region)) {
|
||||
match = ninfo;
|
||||
matchRegion = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (matchRegion) {
|
||||
break;
|
||||
}
|
||||
if (match == null) {
|
||||
match = ninfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match != null) {
|
||||
NameType ntype = match.type;
|
||||
// Note: Workaround for duplicated standard/daylight names
|
||||
// The tz database contains a few zones sharing a
|
||||
// same name for both standard time and daylight saving
|
||||
// time. For example, Australia/Sydney observes DST,
|
||||
// but "EST" is used for both standard and daylight.
|
||||
// When both SHORT_STANDARD and SHORT_DAYLIGHT are included
|
||||
// in the find operation, we cannot tell which one was
|
||||
// actually matched.
|
||||
// TimeZoneFormat#parse returns a matched name type (standard
|
||||
// or daylight) and DateFormat implementation uses the info to
|
||||
// to adjust actual time. To avoid false type information,
|
||||
// this implementation replaces the name type with SHORT_GENERIC.
|
||||
if (match.ambiguousType
|
||||
&& (ntype == NameType.SHORT_STANDARD || ntype == NameType.SHORT_DAYLIGHT)
|
||||
&& _nameTypes.contains(NameType.SHORT_STANDARD)
|
||||
&& _nameTypes.contains(NameType.SHORT_DAYLIGHT)) {
|
||||
ntype = NameType.SHORT_GENERIC;
|
||||
}
|
||||
MatchInfo minfo = new MatchInfo(ntype, null, match.mzID, matchLength);
|
||||
if (_matches == null) {
|
||||
_matches = new LinkedList<MatchInfo>();
|
||||
}
|
||||
_matches.add(minfo);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the match results
|
||||
* @return the match results
|
||||
*/
|
||||
public Collection<MatchInfo> getMatches() {
|
||||
if (_matches == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return _matches;
|
||||
}
|
||||
}
|
||||
|
||||
private static TZDBNames getMetaZoneNames(String mzID) {
|
||||
TZDBNames names = TZDB_NAMES_MAP.get(mzID);
|
||||
if (names == null) {
|
||||
names = TZDBNames.getInstance(ZONESTRINGS, "meta:" + mzID);
|
||||
mzID = mzID.intern();
|
||||
TZDBNames tmpNames = TZDB_NAMES_MAP.putIfAbsent(mzID, names);
|
||||
names = (tmpNames == null) ? names : tmpNames;
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
private static void prepareFind() {
|
||||
if (TZDB_NAMES_TRIE == null) {
|
||||
synchronized(TZDBTimeZoneNames.class) {
|
||||
if (TZDB_NAMES_TRIE == null) {
|
||||
// loading all names into trie
|
||||
TZDB_NAMES_TRIE = new TextTrieMap<TZDBNameInfo>(true);
|
||||
Set<String> mzIDs = TimeZoneNamesImpl._getAvailableMetaZoneIDs();
|
||||
for (String mzID : mzIDs) {
|
||||
TZDBNames names = getMetaZoneNames(mzID);
|
||||
String std = names.getName(NameType.SHORT_STANDARD);
|
||||
String dst = names.getName(NameType.SHORT_DAYLIGHT);
|
||||
if (std == null && dst == null) {
|
||||
continue;
|
||||
}
|
||||
String[] parseRegions = names.getParseRegions();
|
||||
mzID = mzID.intern();
|
||||
|
||||
// The tz database contains a few zones sharing a
|
||||
// same name for both standard time and daylight saving
|
||||
// time. For example, Australia/Sydney observes DST,
|
||||
// but "EST" is used for both standard and daylight.
|
||||
// we need to store the information for later processing.
|
||||
boolean ambiguousType = (std != null && dst != null && std.equals(dst));
|
||||
|
||||
if (std != null) {
|
||||
TZDBNameInfo stdInf = new TZDBNameInfo();
|
||||
stdInf.mzID = mzID;
|
||||
stdInf.type = NameType.SHORT_STANDARD;
|
||||
stdInf.ambiguousType = ambiguousType;
|
||||
stdInf.parseRegions = parseRegions;
|
||||
TZDB_NAMES_TRIE.put(std, stdInf);
|
||||
}
|
||||
if (dst != null) {
|
||||
TZDBNameInfo dstInf = new TZDBNameInfo();
|
||||
dstInf.mzID = mzID;
|
||||
dstInf.type = NameType.SHORT_DAYLIGHT;
|
||||
dstInf.ambiguousType = ambiguousType;
|
||||
dstInf.parseRegions = parseRegions;
|
||||
TZDB_NAMES_TRIE.put(dst, dstInf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getTargetRegion() {
|
||||
if (_region == null) {
|
||||
String region = _locale.getCountry();
|
||||
if (region.length() == 0) {
|
||||
ULocale tmp = ULocale.addLikelySubtags(_locale);
|
||||
region = tmp.getCountry();
|
||||
if (region.length() == 0) {
|
||||
region = "001";
|
||||
}
|
||||
}
|
||||
_region = region;
|
||||
}
|
||||
return _region;
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2011-2013, International Business Machines Corporation and *
|
||||
* Copyright (C) 2011-2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -41,7 +41,7 @@ public class TimeZoneNamesImpl extends TimeZoneNames {
|
||||
private static final String ZONE_STRINGS_BUNDLE = "zoneStrings";
|
||||
private static final String MZ_PREFIX = "meta:";
|
||||
|
||||
private static Set<String> METAZONE_IDS;
|
||||
private static volatile Set<String> METAZONE_IDS;
|
||||
private static final TZ2MZsCache TZ_TO_MZS_CACHE = new TZ2MZsCache();
|
||||
private static final MZ2TZsCache MZ_TO_TZS_CACHE = new MZ2TZsCache();
|
||||
|
||||
@ -65,12 +65,20 @@ public class TimeZoneNamesImpl extends TimeZoneNames {
|
||||
* @see com.ibm.icu.text.TimeZoneNames#getAvailableMetaZoneIDs()
|
||||
*/
|
||||
@Override
|
||||
public synchronized Set<String> getAvailableMetaZoneIDs() {
|
||||
public Set<String> getAvailableMetaZoneIDs() {
|
||||
return _getAvailableMetaZoneIDs();
|
||||
}
|
||||
|
||||
static Set<String> _getAvailableMetaZoneIDs() {
|
||||
if (METAZONE_IDS == null) {
|
||||
UResourceBundle bundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "metaZones");
|
||||
UResourceBundle mapTimezones = bundle.get("mapTimezones");
|
||||
Set<String> keys = mapTimezones.keySet();
|
||||
METAZONE_IDS = Collections.unmodifiableSet(keys);
|
||||
synchronized (TimeZoneNamesImpl.class) {
|
||||
if (METAZONE_IDS == null) {
|
||||
UResourceBundle bundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "metaZones");
|
||||
UResourceBundle mapTimezones = bundle.get("mapTimezones");
|
||||
Set<String> keys = mapTimezones.keySet();
|
||||
METAZONE_IDS = Collections.unmodifiableSet(keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
return METAZONE_IDS;
|
||||
}
|
||||
@ -80,6 +88,10 @@ public class TimeZoneNamesImpl extends TimeZoneNames {
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getAvailableMetaZoneIDs(String tzID) {
|
||||
return _getAvailableMetaZoneIDs(tzID);
|
||||
}
|
||||
|
||||
static Set<String> _getAvailableMetaZoneIDs(String tzID) {
|
||||
if (tzID == null || tzID.length() == 0) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
@ -100,6 +112,10 @@ public class TimeZoneNamesImpl extends TimeZoneNames {
|
||||
*/
|
||||
@Override
|
||||
public String getMetaZoneID(String tzID, long date) {
|
||||
return _getMetaZoneID(tzID, date);
|
||||
}
|
||||
|
||||
static String _getMetaZoneID(String tzID, long date) {
|
||||
if (tzID == null || tzID.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
@ -119,6 +135,10 @@ public class TimeZoneNamesImpl extends TimeZoneNames {
|
||||
*/
|
||||
@Override
|
||||
public String getReferenceZoneID(String mzID, String region) {
|
||||
return _getReferenceZoneID(mzID, region);
|
||||
}
|
||||
|
||||
static String _getReferenceZoneID(String mzID, String region) {
|
||||
if (mzID == null || mzID.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import java.util.Set;
|
||||
|
||||
import com.ibm.icu.impl.ICUResourceBundle;
|
||||
import com.ibm.icu.impl.SoftCache;
|
||||
import com.ibm.icu.impl.TZDBTimeZoneNames;
|
||||
import com.ibm.icu.impl.TextTrieMap;
|
||||
import com.ibm.icu.impl.TimeZoneGenericNames;
|
||||
import com.ibm.icu.impl.TimeZoneGenericNames.GenericMatchInfo;
|
||||
@ -309,8 +310,17 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
* by other styles.
|
||||
* @stable ICU 49
|
||||
*/
|
||||
ALL_STYLES;
|
||||
}
|
||||
ALL_STYLES,
|
||||
/**
|
||||
* When parsing a time zone display name in {@link Style#SPECIFIC_SHORT},
|
||||
* look for the IANA tz database compatible zone abbreviations in addition
|
||||
* to the localized names coming from the {@link TimeZoneNames} currently
|
||||
* used by the {@link TimeZoneFormat}.
|
||||
* @draft ICU 54
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
TZ_DATABASE_ABBREVIATIONS;
|
||||
}
|
||||
|
||||
/*
|
||||
* fields to be serialized
|
||||
@ -322,6 +332,7 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
private String[] _gmtOffsetDigits;
|
||||
private String _gmtZeroFormat;
|
||||
private boolean _parseAllStyles;
|
||||
private boolean _parseTZDBNames;
|
||||
|
||||
/*
|
||||
* Transient fields
|
||||
@ -338,6 +349,7 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
|
||||
private transient boolean _frozen;
|
||||
|
||||
private transient volatile TimeZoneNames _tzdbNames;
|
||||
|
||||
/*
|
||||
* Static final fields
|
||||
@ -524,6 +536,23 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
return _gnames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method returning the instance of TZDBTimeZoneNames.
|
||||
* The instance if used only for parsing when {@link ParseOption#TZ_DATABASE_ABBREVIATIONS}
|
||||
* is enabled.
|
||||
* @return an instance of TZDBTimeZoneNames.
|
||||
*/
|
||||
private TimeZoneNames getTZDBTimeZoneNames() {
|
||||
if (_tzdbNames == null) {
|
||||
synchronized(this) {
|
||||
if (_tzdbNames == null) {
|
||||
_tzdbNames = new TZDBTimeZoneNames(_locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _tzdbNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time zone display name data to this instance.
|
||||
*
|
||||
@ -699,8 +728,8 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
* @stable ICU 49
|
||||
*/
|
||||
public TimeZoneFormat setDefaultParseOptions(EnumSet<ParseOption> options) {
|
||||
// Currently, only ALL_STYLES is supported
|
||||
_parseAllStyles = options.contains(ParseOption.ALL_STYLES);
|
||||
_parseTZDBNames = options.contains(ParseOption.TZ_DATABASE_ABBREVIATIONS);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -711,8 +740,12 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
* @stable ICU 49
|
||||
*/
|
||||
public EnumSet<ParseOption> getDefaultParseOptions() {
|
||||
if (_parseAllStyles) {
|
||||
if (_parseAllStyles && _parseTZDBNames) {
|
||||
return EnumSet.of(ParseOption.ALL_STYLES, ParseOption.TZ_DATABASE_ABBREVIATIONS);
|
||||
} else if (_parseAllStyles) {
|
||||
return EnumSet.of(ParseOption.ALL_STYLES);
|
||||
} else if (_parseTZDBNames) {
|
||||
return EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS);
|
||||
}
|
||||
return EnumSet.noneOf(ParseOption.class);
|
||||
}
|
||||
@ -1078,6 +1111,10 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
evaluated |= (Style.LOCALIZED_GMT.flag | Style.LOCALIZED_GMT_SHORT.flag);
|
||||
}
|
||||
|
||||
boolean parseTZDBAbbrev = (options == null) ?
|
||||
getDefaultParseOptions().contains(ParseOption.TZ_DATABASE_ABBREVIATIONS)
|
||||
: options.contains(ParseOption.TZ_DATABASE_ABBREVIATIONS);
|
||||
|
||||
// Try the specified style
|
||||
switch (style) {
|
||||
case LOCALIZED_GMT:
|
||||
@ -1173,6 +1210,28 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
return TimeZone.getTimeZone(getTimeZoneID(specificMatch.tzID(), specificMatch.mzID()));
|
||||
}
|
||||
}
|
||||
|
||||
if (parseTZDBAbbrev && style == Style.SPECIFIC_SHORT) {
|
||||
assert nameTypes.contains(NameType.SHORT_STANDARD);
|
||||
assert nameTypes.contains(NameType.SHORT_DAYLIGHT);
|
||||
|
||||
Collection<MatchInfo> tzdbNameMatches =
|
||||
getTZDBTimeZoneNames().find(text, startIdx, nameTypes);
|
||||
if (tzdbNameMatches != null) {
|
||||
MatchInfo tzdbNameMatch = null;
|
||||
for (MatchInfo match : tzdbNameMatches) {
|
||||
if (startIdx + match.matchLength() > parsedPos) {
|
||||
tzdbNameMatch = match;
|
||||
parsedPos = startIdx + match.matchLength();
|
||||
}
|
||||
}
|
||||
if (tzdbNameMatch != null) {
|
||||
timeType.value = getTimeType(tzdbNameMatch.nameType());
|
||||
pos.setIndex(parsedPos);
|
||||
return TimeZone.getTimeZone(getTimeZoneID(tzdbNameMatch.tzID(), tzdbNameMatch.mzID()));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GENERIC_LONG:
|
||||
@ -1367,7 +1426,27 @@ public class TimeZoneFormat extends UFormat implements Freezable<TimeZoneFormat>
|
||||
parsedTimeType = getTimeType(specificMatch.nameType());
|
||||
parsedOffset = UNKNOWN_OFFSET;
|
||||
}
|
||||
|
||||
}
|
||||
if (parseTZDBAbbrev && parsedPos < maxPos && (evaluated & Style.SPECIFIC_SHORT.flag) == 0) {
|
||||
Collection<MatchInfo> tzdbNameMatches =
|
||||
getTZDBTimeZoneNames().find(text, startIdx, ALL_SIMPLE_NAME_TYPES);
|
||||
MatchInfo tzdbNameMatch = null;
|
||||
int matchPos = -1;
|
||||
if (tzdbNameMatches != null) {
|
||||
for (MatchInfo match : tzdbNameMatches) {
|
||||
if (startIdx + match.matchLength() > matchPos) {
|
||||
tzdbNameMatch = match;
|
||||
matchPos = startIdx + match.matchLength();
|
||||
}
|
||||
}
|
||||
if (parsedPos < matchPos) {
|
||||
parsedPos = matchPos;
|
||||
parsedID = getTimeZoneID(tzdbNameMatch.tzID(), tzdbNameMatch.mzID());
|
||||
parsedTimeType = getTimeType(tzdbNameMatch.nameType());
|
||||
parsedOffset = UNKNOWN_OFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// Try generic names
|
||||
if (parsedPos < maxPos) {
|
||||
|
@ -15,6 +15,7 @@ import java.util.Set;
|
||||
|
||||
import com.ibm.icu.impl.ICUConfig;
|
||||
import com.ibm.icu.impl.SoftCache;
|
||||
import com.ibm.icu.impl.TZDBTimeZoneNames;
|
||||
import com.ibm.icu.impl.TimeZoneNamesImpl;
|
||||
import com.ibm.icu.util.TimeZone;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
@ -160,11 +161,11 @@ public abstract class TimeZoneNames implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of <code>TimeZoneDisplayNames</code> for the specified locale.
|
||||
* Returns an instance of <code>TimeZoneNames</code> for the specified locale.
|
||||
*
|
||||
* @param locale
|
||||
* The locale.
|
||||
* @return An instance of <code>TimeZoneDisplayNames</code>
|
||||
* @return An instance of <code>TimeZoneNames</code>
|
||||
* @stable ICU 49
|
||||
*/
|
||||
public static TimeZoneNames getInstance(ULocale locale) {
|
||||
@ -173,7 +174,7 @@ public abstract class TimeZoneNames implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of <code>TimeZoneDisplayNames</code> for the specified JDK locale.
|
||||
* Returns an instance of <code>TimeZoneNames</code> for the specified JDK locale.
|
||||
*
|
||||
* @param locale
|
||||
* The JDK locale.
|
||||
@ -185,6 +186,22 @@ public abstract class TimeZoneNames implements Serializable {
|
||||
return getInstance(ULocale.forLocale(locale));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of <code>TimeZoneNames</code> containing only short specific
|
||||
* zone names ({@link NameType#SHORT_STANDARD} and {@link NameType#SHORT_DAYLIGHT}),
|
||||
* compatible with the IANA tz database's zone abbreviations (not localized).
|
||||
* <br>
|
||||
* Note: The input locale is used for resolving ambiguous names (e.g. "IST" is parsed
|
||||
* as Israel Standard Time for Israel, while it is parsed as India Standard Time for
|
||||
* all other regions). The zone names returned by this instance are not localized.
|
||||
*
|
||||
* @draft ICU 54
|
||||
* @provisional This API might change or be removed in a future release.
|
||||
*/
|
||||
public static TimeZoneNames getTZDBInstance(ULocale locale) {
|
||||
return new TZDBTimeZoneNames(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an immutable set of all available meta zone IDs.
|
||||
* @return An immutable set of all available meta zone IDs.
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:df42e127c7c6127bce3a0a44577d33d8457fc073f5fa131f6916c039b374932c
|
||||
size 10503267
|
||||
oid sha256:3d46efbf5fced8f73fd8e352902259aa0ba4c89fdf9fcbee24862044a09c56b8
|
||||
size 10505785
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:33523d17a26aa17b47fafbd6242592cd070436cd988b32d67230612a31432ca8
|
||||
oid sha256:d3137adf135a24c2bb8f5fcbbbdea86e07a79f3eb8f4dab3734e88afa7a2dc7a
|
||||
size 91046
|
||||
|
@ -25,6 +25,7 @@ import com.ibm.icu.text.TimeZoneFormat;
|
||||
import com.ibm.icu.text.TimeZoneFormat.ParseOption;
|
||||
import com.ibm.icu.text.TimeZoneFormat.Style;
|
||||
import com.ibm.icu.text.TimeZoneFormat.TimeType;
|
||||
import com.ibm.icu.text.TimeZoneNames;
|
||||
import com.ibm.icu.util.BasicTimeZone;
|
||||
import com.ibm.icu.util.Calendar;
|
||||
import com.ibm.icu.util.Output;
|
||||
@ -498,25 +499,91 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
|
||||
public void TestParse() {
|
||||
final Object[][] DATA = {
|
||||
// text inpos locale style parseAll? expected outpos time type
|
||||
{"Z", 0, "en_US", Style.ISO_EXTENDED_FULL, false, "Etc/GMT", 1, TimeType.UNKNOWN},
|
||||
{"Z", 0, "en_US", Style.SPECIFIC_LONG, false, "Etc/GMT", 1, TimeType.UNKNOWN},
|
||||
{"Zambia time", 0, "en_US", Style.ISO_EXTENDED_FULL, true, "Etc/GMT", 1, TimeType.UNKNOWN},
|
||||
{"Zambia time", 0, "en_US", Style.GENERIC_LOCATION, false, "Africa/Lusaka", 11, TimeType.UNKNOWN},
|
||||
{"Zambia time", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, true, "Africa/Lusaka", 11, TimeType.UNKNOWN},
|
||||
{"+00:00", 0, "en_US", Style.ISO_EXTENDED_FULL, false, "Etc/GMT", 6, TimeType.UNKNOWN},
|
||||
{"-01:30:45", 0, "en_US", Style.ISO_EXTENDED_FULL, false, "GMT-01:30:45", 9, TimeType.UNKNOWN},
|
||||
{"-7", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, false, "GMT-07:00", 2, TimeType.UNKNOWN},
|
||||
{"-2222", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, false, "GMT-22:22", 5, TimeType.UNKNOWN},
|
||||
{"-3333", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, false, "GMT-03:33", 4, TimeType.UNKNOWN},
|
||||
{"XXX+01:30YYY", 3, "en_US", Style.LOCALIZED_GMT, false, "GMT+01:30", 9, TimeType.UNKNOWN},
|
||||
{"GMT0", 0, "en_US", Style.SPECIFIC_SHORT, false, "Etc/GMT", 3, TimeType.UNKNOWN},
|
||||
{"EST", 0, "en_US", Style.SPECIFIC_SHORT, false, "America/New_York", 3, TimeType.STANDARD},
|
||||
{"ESTx", 0, "en_US", Style.SPECIFIC_SHORT, false, "America/New_York", 3, TimeType.STANDARD},
|
||||
{"EDTx", 0, "en_US", Style.SPECIFIC_SHORT, false, "America/New_York", 3, TimeType.DAYLIGHT},
|
||||
{"EST", 0, "en_US", Style.SPECIFIC_LONG, false, null, 0, TimeType.UNKNOWN},
|
||||
{"EST", 0, "en_US", Style.SPECIFIC_LONG, true, "America/New_York", 3, TimeType.STANDARD},
|
||||
{"EST", 0, "en_CA", Style.SPECIFIC_SHORT, false, "America/Toronto", 3, TimeType.STANDARD},
|
||||
// text inpos locale style
|
||||
// parseOptions expected outpos time type
|
||||
{"Z", 0, "en_US", Style.ISO_EXTENDED_FULL,
|
||||
null, "Etc/GMT", 1, TimeType.UNKNOWN},
|
||||
|
||||
{"Z", 0, "en_US", Style.SPECIFIC_LONG,
|
||||
null, "Etc/GMT", 1, TimeType.UNKNOWN},
|
||||
|
||||
{"Zambia time", 0, "en_US", Style.ISO_EXTENDED_FULL,
|
||||
EnumSet.of(ParseOption.ALL_STYLES), "Etc/GMT", 1, TimeType.UNKNOWN},
|
||||
|
||||
{"Zambia time", 0, "en_US", Style.GENERIC_LOCATION,
|
||||
null, "Africa/Lusaka", 11, TimeType.UNKNOWN},
|
||||
|
||||
{"Zambia time", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL,
|
||||
EnumSet.of(ParseOption.ALL_STYLES), "Africa/Lusaka", 11, TimeType.UNKNOWN},
|
||||
|
||||
{"+00:00", 0, "en_US", Style.ISO_EXTENDED_FULL,
|
||||
null, "Etc/GMT", 6, TimeType.UNKNOWN},
|
||||
|
||||
{"-01:30:45", 0, "en_US", Style.ISO_EXTENDED_FULL,
|
||||
null, "GMT-01:30:45", 9, TimeType.UNKNOWN},
|
||||
|
||||
{"-7", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL,
|
||||
null, "GMT-07:00", 2, TimeType.UNKNOWN},
|
||||
|
||||
{"-2222", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL,
|
||||
null, "GMT-22:22", 5, TimeType.UNKNOWN},
|
||||
|
||||
{"-3333", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL,
|
||||
null, "GMT-03:33", 4, TimeType.UNKNOWN},
|
||||
|
||||
{"XXX+01:30YYY", 3, "en_US", Style.LOCALIZED_GMT,
|
||||
null, "GMT+01:30", 9, TimeType.UNKNOWN},
|
||||
|
||||
{"GMT0", 0, "en_US", Style.SPECIFIC_SHORT,
|
||||
null, "Etc/GMT", 3, TimeType.UNKNOWN},
|
||||
|
||||
{"EST", 0, "en_US", Style.SPECIFIC_SHORT,
|
||||
null, "America/New_York", 3, TimeType.STANDARD},
|
||||
|
||||
{"ESTx", 0, "en_US", Style.SPECIFIC_SHORT,
|
||||
null, "America/New_York", 3, TimeType.STANDARD},
|
||||
|
||||
{"EDTx", 0, "en_US", Style.SPECIFIC_SHORT,
|
||||
null, "America/New_York", 3, TimeType.DAYLIGHT},
|
||||
|
||||
{"EST", 0, "en_US", Style.SPECIFIC_LONG,
|
||||
null, null, 0, TimeType.UNKNOWN},
|
||||
|
||||
{"EST", 0, "en_US", Style.SPECIFIC_LONG,
|
||||
EnumSet.of(ParseOption.ALL_STYLES), "America/New_York", 3, TimeType.STANDARD},
|
||||
|
||||
{"EST", 0, "en_CA", Style.SPECIFIC_SHORT,
|
||||
null, "America/Toronto", 3, TimeType.STANDARD},
|
||||
|
||||
{"CST", 0, "en_US", Style.SPECIFIC_SHORT,
|
||||
null, "America/Chicago", 3, TimeType.STANDARD},
|
||||
|
||||
{"CST", 0, "en_GB", Style.SPECIFIC_SHORT,
|
||||
null, null, 0, TimeType.UNKNOWN},
|
||||
|
||||
{"CST", 0, "en_GB", Style.SPECIFIC_SHORT,
|
||||
EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "America/Chicago", 3, TimeType.STANDARD},
|
||||
|
||||
{"--CST--", 2, "en_GB", Style.SPECIFIC_SHORT,
|
||||
EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "America/Chicago", 5, TimeType.STANDARD},
|
||||
|
||||
{"CST", 0, "zh_CN", Style.SPECIFIC_SHORT,
|
||||
EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Shanghai", 3, TimeType.STANDARD},
|
||||
|
||||
{"EST", 0, "en_AU", Style.SPECIFIC_SHORT,
|
||||
EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Australia/Sydney", 3, TimeType.UNKNOWN},
|
||||
|
||||
{"AST", 0, "ar_SA", Style.SPECIFIC_SHORT,
|
||||
EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Riyadh", 3, TimeType.STANDARD},
|
||||
|
||||
{"AQTST", 0, "en", Style.SPECIFIC_LONG,
|
||||
null, null, 0, TimeType.UNKNOWN},
|
||||
|
||||
{"AQTST", 0, "en", Style.SPECIFIC_LONG,
|
||||
EnumSet.of(ParseOption.ALL_STYLES), null, 0, TimeType.UNKNOWN},
|
||||
|
||||
{"AQTST", 0, "en", Style.SPECIFIC_LONG,
|
||||
EnumSet.of(ParseOption.ALL_STYLES, ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Aqtobe", 5, TimeType.DAYLIGHT},
|
||||
};
|
||||
|
||||
for (Object[] test : DATA) {
|
||||
@ -524,7 +591,7 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
int inPos = (Integer)test[1];
|
||||
ULocale loc = new ULocale((String)test[2]);
|
||||
Style style = (Style)test[3];
|
||||
EnumSet<ParseOption> options = (Boolean)test[4] ? EnumSet.of(ParseOption.ALL_STYLES) : null;
|
||||
EnumSet<ParseOption> options = (EnumSet<ParseOption>)test[4];
|
||||
String expID = (String)test[5];
|
||||
int expPos = (Integer)test[6];
|
||||
TimeType expType = (TimeType)test[7];
|
||||
@ -798,4 +865,85 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void TestFormatTZDBNames() {
|
||||
final Date dateJan = new Date(1358208000000L); // 2013-01-15T00:00:00Z
|
||||
final Date dateJul = new Date(1373846400000L); // 2013-07-15T00:00:00Z
|
||||
|
||||
final Object[][] TESTDATA = {
|
||||
{
|
||||
"en",
|
||||
"America/Chicago",
|
||||
dateJan,
|
||||
Style.SPECIFIC_SHORT,
|
||||
"CST",
|
||||
TimeType.STANDARD
|
||||
},
|
||||
{
|
||||
"en",
|
||||
"Asia/Shanghai",
|
||||
dateJan,
|
||||
Style.SPECIFIC_SHORT,
|
||||
"CST",
|
||||
TimeType.STANDARD
|
||||
},
|
||||
{
|
||||
"zh_Hans",
|
||||
"Asia/Shanghai",
|
||||
dateJan,
|
||||
Style.SPECIFIC_SHORT,
|
||||
"CST",
|
||||
TimeType.STANDARD
|
||||
},
|
||||
{
|
||||
"en",
|
||||
"America/Los_Angeles",
|
||||
dateJul,
|
||||
Style.SPECIFIC_LONG,
|
||||
"GMT-07:00", // No long display names
|
||||
TimeType.DAYLIGHT
|
||||
},
|
||||
{
|
||||
"ja",
|
||||
"America/Los_Angeles",
|
||||
dateJul,
|
||||
Style.SPECIFIC_SHORT,
|
||||
"PDT",
|
||||
TimeType.DAYLIGHT
|
||||
},
|
||||
{
|
||||
"en",
|
||||
"Australia/Sydney",
|
||||
dateJan,
|
||||
Style.SPECIFIC_SHORT,
|
||||
"EST",
|
||||
TimeType.DAYLIGHT
|
||||
},
|
||||
{
|
||||
"en",
|
||||
"Australia/Sydney",
|
||||
dateJul,
|
||||
Style.SPECIFIC_SHORT,
|
||||
"EST",
|
||||
TimeType.STANDARD
|
||||
},
|
||||
};
|
||||
|
||||
for (Object[] testCase : TESTDATA) {
|
||||
ULocale loc = new ULocale((String)testCase[0]);
|
||||
TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(loc).cloneAsThawed();
|
||||
TimeZoneNames tzdbNames = TimeZoneNames.getTZDBInstance(loc);
|
||||
tzfmt.setTimeZoneNames(tzdbNames);
|
||||
|
||||
TimeZone tz = TimeZone.getTimeZone((String)testCase[1]);
|
||||
Output<TimeType> timeType = new Output<TimeType>();
|
||||
String out = tzfmt.format((Style)testCase[3], tz, ((Date)testCase[2]).getTime(), timeType);
|
||||
|
||||
if (!out.equals((String)testCase[4]) || timeType.value != testCase[5]) {
|
||||
errln("Format result for [locale=" + testCase[0] + ",tzid=" + testCase[1] + ",date=" + testCase[2]
|
||||
+ ",style=" + testCase[3] + "]: expected [output=" + testCase[4] + ",type=" + testCase[5]
|
||||
+ "]; actual [output=" + out + ",type=" + timeType.value + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (c) 2004-2013, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*
|
||||
@ -13,6 +13,7 @@ import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.ibm.icu.impl.DateNumberFormat;
|
||||
import com.ibm.icu.impl.TZDBTimeZoneNames;
|
||||
import com.ibm.icu.impl.TimeZoneGenericNames;
|
||||
import com.ibm.icu.impl.TimeZoneGenericNames.GenericNameType;
|
||||
import com.ibm.icu.impl.Utility;
|
||||
@ -38,6 +39,7 @@ import com.ibm.icu.text.TimeUnitFormat;
|
||||
import com.ibm.icu.text.TimeZoneFormat;
|
||||
import com.ibm.icu.text.TimeZoneFormat.Style;
|
||||
import com.ibm.icu.text.TimeZoneNames;
|
||||
import com.ibm.icu.text.TimeZoneNames.NameType;
|
||||
import com.ibm.icu.util.Calendar;
|
||||
import com.ibm.icu.util.DateInterval;
|
||||
import com.ibm.icu.util.GregorianCalendar;
|
||||
@ -2297,6 +2299,50 @@ public class FormatTests
|
||||
}
|
||||
}
|
||||
|
||||
public static class TZDBTimeZoneNamesHandler implements SerializableTest.Handler {
|
||||
public Object[] getTestObjects() {
|
||||
return new Object[] {
|
||||
TimeZoneNames.getTZDBInstance(ULocale.ENGLISH),
|
||||
TimeZoneNames.getTZDBInstance(ULocale.JAPAN)
|
||||
};
|
||||
}
|
||||
public boolean hasSameBehavior(Object a, Object b) {
|
||||
TZDBTimeZoneNames tzdbna = (TZDBTimeZoneNames)a;
|
||||
TZDBTimeZoneNames tzdbnb = (TZDBTimeZoneNames)b;
|
||||
|
||||
final String[] TZIDS = {
|
||||
"America/Los_Angeles",
|
||||
"America/Argentina/Buenos_Aires",
|
||||
"Asia/Shanghai",
|
||||
"Etc/GMT"
|
||||
};
|
||||
|
||||
final long[] DATES = {
|
||||
1277942400000L, // 2010-07-01 00:00:00 GMT
|
||||
1293840000000L, // 2011-01-01 00:00:00 GMT
|
||||
};
|
||||
|
||||
final NameType[] nTypes = {
|
||||
NameType.SHORT_STANDARD,
|
||||
NameType.SHORT_DAYLIGHT
|
||||
};
|
||||
|
||||
for (String tzid : TZIDS) {
|
||||
for (NameType nt : nTypes) {
|
||||
for (long date : DATES) {
|
||||
String nameA = tzdbna.getDisplayName(tzid, nt, date);
|
||||
String nameB = tzdbnb.getDisplayName(tzid, nt, date);
|
||||
if (!Utility.objectEquals(nameA, nameB)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TimeZoneFormatHandler implements SerializableTest.Handler {
|
||||
static final String CUSTOM_GMT_PATTERN = "Offset {0} from UTC";
|
||||
|
||||
|
@ -736,6 +736,7 @@ public class SerializableTest extends TestFmwk.TestGroup
|
||||
map.put("com.ibm.icu.impl.TimeZoneNamesImpl", new FormatTests.TimeZoneNamesHandler());
|
||||
map.put("com.ibm.icu.text.TimeZoneFormat", new FormatTests.TimeZoneFormatHandler());
|
||||
map.put("com.ibm.icu.impl.TimeZoneGenericNames", new FormatTests.TimeZoneGenericNamesHandler());
|
||||
map.put("com.ibm.icu.impl.TZDBTimeZoneNames", new FormatTests.TZDBTimeZoneNamesHandler());
|
||||
|
||||
map.put("com.ibm.icu.util.Calendar", new CalendarTests.CalendarHandler());
|
||||
map.put("com.ibm.icu.util.BuddhistCalendar", new CalendarTests.BuddhistCalendarHandler());
|
||||
|
Loading…
Reference in New Issue
Block a user