ICU-5990 metazoneInfo.res support. Fixed a bug for detecting daylight saving time amount. Updated icudata.jar to include metazoneInfo.res.
X-SVN-Rev: 22968
This commit is contained in:
parent
12aea479ca
commit
8cd61ae501
@ -208,6 +208,7 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
};
|
||||
}
|
||||
|
||||
long testCounts = 0;
|
||||
long[] testTimes = new long[4];
|
||||
boolean[] expectedRoundTrip = new boolean[4];
|
||||
int testLen = 0;
|
||||
@ -219,7 +220,6 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(pattern, LOCALES[locidx]);
|
||||
|
||||
String[] ids = TimeZone.getAvailableIDs();
|
||||
timer = System.currentTimeMillis();
|
||||
for (int zidx = 0; zidx < ids.length; zidx++) {
|
||||
if(!ids[zidx].equals(ZoneMeta.getCanonicalID(ids[zidx]))) {
|
||||
// Skip aliases
|
||||
@ -262,6 +262,8 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
}
|
||||
}
|
||||
for (int testidx = 0; testidx < testLen; testidx++) {
|
||||
testCounts++;
|
||||
timer = System.currentTimeMillis();
|
||||
String text = sdf.format(new Date(testTimes[testidx]));
|
||||
try {
|
||||
Date parsedDate = sdf.parse(text);
|
||||
@ -285,6 +287,7 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
} catch (ParseException pe) {
|
||||
errln("FAIL: " + pe.getMessage());
|
||||
}
|
||||
times[patidx] += System.currentTimeMillis() - timer;
|
||||
}
|
||||
tzt = tz.getNextTransition(t, false);
|
||||
if (tzt == null) {
|
||||
@ -300,7 +303,6 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
}
|
||||
}
|
||||
}
|
||||
times[patidx] += System.currentTimeMillis() - timer;
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,5 +313,6 @@ public class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
total += times[i];
|
||||
}
|
||||
logln("Total: " + total + "ms");
|
||||
logln("Iteration: " + testCounts);
|
||||
}
|
||||
}
|
@ -747,66 +747,20 @@ public final class ZoneMeta {
|
||||
}
|
||||
|
||||
static Map getOlsonToMetaMap() {
|
||||
HashMap olsonToMeta = null;
|
||||
Map olsonToMeta = null;
|
||||
synchronized(ZoneMeta.class) {
|
||||
if (OLSON_TO_META_REF != null) {
|
||||
olsonToMeta = (HashMap)OLSON_TO_META_REF.get();
|
||||
}
|
||||
if (olsonToMeta == null) {
|
||||
// Create olson id to metazone mapping table
|
||||
olsonToMeta = new HashMap();
|
||||
UResourceBundle zoneStringsBundle = null;
|
||||
try {
|
||||
UResourceBundle bundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "root");
|
||||
zoneStringsBundle = bundle.get("zoneStrings");
|
||||
} catch (MissingResourceException mre) {
|
||||
// do nothing
|
||||
olsonToMeta = createOlsonToMetaMap();
|
||||
if (olsonToMeta == null) {
|
||||
// We may not need this code for ICU4J...
|
||||
olsonToMeta = createOlsonToMetaMapOld();
|
||||
}
|
||||
if (zoneStringsBundle != null) {
|
||||
// DateFormat to be used for parsing metazone mapping range
|
||||
SimpleDateFormat mzdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
mzdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
|
||||
String[] tzids = getAvailableIDs();
|
||||
for (int i = 0; i < tzids.length; i++) {
|
||||
// Skip aliases
|
||||
if (!tzids[i].equals(getCanonicalID(tzids[i]))) {
|
||||
continue;
|
||||
}
|
||||
String tzkey = tzids[i].replace('/', ':');
|
||||
try {
|
||||
UResourceBundle zoneBundle = zoneStringsBundle.get(tzkey);
|
||||
UResourceBundle useMZ = zoneBundle.get("um");
|
||||
LinkedList mzMappings = new LinkedList();
|
||||
for (int idx = 0; ; idx++) {
|
||||
try {
|
||||
UResourceBundle mz = useMZ.get("mz" + idx);
|
||||
String[] mzstr = mz.getStringArray();
|
||||
if (mzstr == null || mzstr.length != 3) {
|
||||
continue;
|
||||
}
|
||||
OlsonToMetaMappingEntry mzmap = new OlsonToMetaMappingEntry();
|
||||
mzmap.mzid = mzstr[0].intern();
|
||||
mzmap.from = mzdf.parse(mzstr[1]).getTime();
|
||||
mzmap.to = mzdf.parse(mzstr[2]).getTime();
|
||||
|
||||
// Add this mapping to the list
|
||||
mzMappings.add(mzmap);
|
||||
} catch (MissingResourceException nomz) {
|
||||
// we're done
|
||||
break;
|
||||
} catch (ParseException baddate) {
|
||||
// skip this
|
||||
}
|
||||
}
|
||||
if (mzMappings.size() != 0) {
|
||||
// Add to the olson-to-meta map
|
||||
olsonToMeta.put(tzids[i], mzMappings);
|
||||
}
|
||||
} catch (MissingResourceException noum) {
|
||||
// Does not use metazone, just skip this.
|
||||
}
|
||||
}
|
||||
if (olsonToMeta == null) {
|
||||
// We need to return non-null Map to avoid disaster
|
||||
olsonToMeta = new HashMap();
|
||||
}
|
||||
OLSON_TO_META_REF = new SoftReference(olsonToMeta);
|
||||
}
|
||||
@ -814,6 +768,127 @@ public final class ZoneMeta {
|
||||
return olsonToMeta;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create olson tzid to metazone mappings from metazoneInfo.res (3.8.1 or later)
|
||||
*/
|
||||
private static Map createOlsonToMetaMap() {
|
||||
// Create olson id to metazone mapping table
|
||||
HashMap olsonToMeta = null;
|
||||
UResourceBundle metazoneMappingsBundle = null;
|
||||
try {
|
||||
UResourceBundle bundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "metazoneInfo");
|
||||
metazoneMappingsBundle = bundle.get("metazoneMappings");
|
||||
} catch (MissingResourceException mre) {
|
||||
// do nothing
|
||||
}
|
||||
if (metazoneMappingsBundle != null) {
|
||||
String[] tzids = getAvailableIDs();
|
||||
for (int i = 0; i < tzids.length; i++) {
|
||||
// Skip aliases
|
||||
if (!tzids[i].equals(getCanonicalID(tzids[i]))) {
|
||||
continue;
|
||||
}
|
||||
String tzkey = tzids[i].replace('/', ':');
|
||||
try {
|
||||
UResourceBundle zoneBundle = metazoneMappingsBundle.get(tzkey);
|
||||
LinkedList mzMappings = new LinkedList();
|
||||
for (int idx = 0; ; idx++) {
|
||||
try {
|
||||
UResourceBundle mz = zoneBundle.get("mz" + idx);
|
||||
String[] mzstr = mz.getStringArray();
|
||||
if (mzstr == null || mzstr.length != 3) {
|
||||
continue;
|
||||
}
|
||||
OlsonToMetaMappingEntry mzmap = new OlsonToMetaMappingEntry();
|
||||
mzmap.mzid = mzstr[0].intern();
|
||||
mzmap.from = parseDate(mzstr[1]);
|
||||
mzmap.to = parseDate(mzstr[2]);
|
||||
|
||||
// Add this mapping to the list
|
||||
mzMappings.add(mzmap);
|
||||
} catch (MissingResourceException nomz) {
|
||||
// we're done
|
||||
break;
|
||||
} catch (IllegalArgumentException baddate) {
|
||||
// skip this
|
||||
}
|
||||
}
|
||||
if (mzMappings.size() != 0) {
|
||||
// Add to the olson-to-meta map
|
||||
if (olsonToMeta == null) {
|
||||
olsonToMeta = new HashMap();
|
||||
}
|
||||
olsonToMeta.put(tzids[i], mzMappings);
|
||||
}
|
||||
} catch (MissingResourceException noum) {
|
||||
// Does not use metazone, just skip this.
|
||||
}
|
||||
}
|
||||
}
|
||||
return olsonToMeta;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create olson tzid to metazone mappings from root.res (3.8)
|
||||
*/
|
||||
private static Map createOlsonToMetaMapOld() {
|
||||
// Create olson id to metazone mapping table
|
||||
HashMap olsonToMeta = null;
|
||||
UResourceBundle zoneStringsBundle = null;
|
||||
try {
|
||||
UResourceBundle bundle = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, "root");
|
||||
zoneStringsBundle = bundle.get("zoneStrings");
|
||||
} catch (MissingResourceException mre) {
|
||||
// do nothing
|
||||
}
|
||||
if (zoneStringsBundle != null) {
|
||||
String[] tzids = getAvailableIDs();
|
||||
for (int i = 0; i < tzids.length; i++) {
|
||||
// Skip aliases
|
||||
if (!tzids[i].equals(getCanonicalID(tzids[i]))) {
|
||||
continue;
|
||||
}
|
||||
String tzkey = tzids[i].replace('/', ':');
|
||||
try {
|
||||
UResourceBundle zoneBundle = zoneStringsBundle.get(tzkey);
|
||||
UResourceBundle useMZ = zoneBundle.get("um");
|
||||
LinkedList mzMappings = new LinkedList();
|
||||
for (int idx = 0; ; idx++) {
|
||||
try {
|
||||
UResourceBundle mz = useMZ.get("mz" + idx);
|
||||
String[] mzstr = mz.getStringArray();
|
||||
if (mzstr == null || mzstr.length != 3) {
|
||||
continue;
|
||||
}
|
||||
OlsonToMetaMappingEntry mzmap = new OlsonToMetaMappingEntry();
|
||||
mzmap.mzid = mzstr[0].intern();
|
||||
mzmap.from = parseDate(mzstr[1]);
|
||||
mzmap.to = parseDate(mzstr[2]);
|
||||
|
||||
// Add this mapping to the list
|
||||
mzMappings.add(mzmap);
|
||||
} catch (MissingResourceException nomz) {
|
||||
// we're done
|
||||
break;
|
||||
} catch (IllegalArgumentException baddate) {
|
||||
// skip this
|
||||
}
|
||||
}
|
||||
if (mzMappings.size() != 0) {
|
||||
// Add to the olson-to-meta map
|
||||
if (olsonToMeta == null) {
|
||||
olsonToMeta = new HashMap();
|
||||
}
|
||||
olsonToMeta.put(tzids[i], mzMappings);
|
||||
}
|
||||
} catch (MissingResourceException noum) {
|
||||
// Does not use metazone, just skip this.
|
||||
}
|
||||
}
|
||||
}
|
||||
return olsonToMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a CLDR metazone ID for the given Olson tzid and time.
|
||||
*/
|
||||
@ -920,4 +995,67 @@ public final class ZoneMeta {
|
||||
// }
|
||||
// return getZoneIdByMetazone(metazoneID, region);
|
||||
// }
|
||||
|
||||
/*
|
||||
* Convert a date string used by metazone mappings to long.
|
||||
* The format used by CLDR metazone mapping is "yyyy-MM-dd HH:mm".
|
||||
* We do not want to use SimpleDateFormat to parse the metazone
|
||||
* mapping range strings in createOlsonToMeta, because it might be
|
||||
* called from SimpleDateFormat initialization code.
|
||||
*/
|
||||
static long parseDate (String text) throws IllegalArgumentException {
|
||||
int year = 0, month = 0, day = 0, hour = 0, min = 0;
|
||||
int idx;
|
||||
int n;
|
||||
|
||||
// "yyyy" (0 - 3)
|
||||
for (idx = 0; idx <= 3; idx++) {
|
||||
n = text.charAt(idx) - '0';
|
||||
if (n >= 0 && n < 10) {
|
||||
year = 10*year + n;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad year");
|
||||
}
|
||||
}
|
||||
// "MM" (5 - 6)
|
||||
for (idx = 5; idx <= 6; idx++) {
|
||||
n = text.charAt(idx) - '0';
|
||||
if (n >= 0 && n < 10) {
|
||||
month = 10*month + n;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad month");
|
||||
}
|
||||
}
|
||||
// "dd" (8 - 9)
|
||||
for (idx = 8; idx <= 9; idx++) {
|
||||
n = text.charAt(idx) - '0';
|
||||
if (n >= 0 && n < 10) {
|
||||
day = 10*day + n;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad day");
|
||||
}
|
||||
}
|
||||
// "HH" (11 - 12)
|
||||
for (idx = 11; idx <= 12; idx++) {
|
||||
n = text.charAt(idx) - '0';
|
||||
if (n >= 0 && n < 10) {
|
||||
hour = 10*hour + n;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad hour");
|
||||
}
|
||||
}
|
||||
// "mm" (14 - 15)
|
||||
for (idx = 14; idx <= 15; idx++) {
|
||||
n = text.charAt(idx) - '0';
|
||||
if (n >= 0 && n < 10) {
|
||||
min = 10*min + n;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Bad minute");
|
||||
}
|
||||
}
|
||||
|
||||
long date = Grego.fieldsToDay(year, month - 1, day) * Grego.MILLIS_PER_DAY
|
||||
+ hour * Grego.MILLIS_PER_HOUR + min * Grego.MILLIS_PER_MINUTE;
|
||||
return date;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0e01a9a1a779d74792f4ae0391b586695f6dd280d7d972fd1e9919bbe74905fe
|
||||
size 5391701
|
||||
oid sha256:d50452d34dbff6e92dbe1d2985eb62696e35bafd40914a57afd0ba2edc8c8876
|
||||
size 5409244
|
||||
|
@ -1648,7 +1648,6 @@ public class SimpleDateFormat extends DateFormat {
|
||||
}
|
||||
} else { // tztype == TZTYPE_DST
|
||||
if (offsets[1] == 0) {
|
||||
int savings = 60*60*1000; // default DST savings
|
||||
if (btz != null) {
|
||||
long time = localMillis + offsets[0];
|
||||
// We use the nearest daylight saving time rule.
|
||||
@ -1684,16 +1683,23 @@ public class SimpleDateFormat extends DateFormat {
|
||||
|
||||
if (beforeTrs != null && afterTrs != null) {
|
||||
if (time - beforeT > afterT - time) {
|
||||
savings = afterSav;
|
||||
resolvedSavings = afterSav;
|
||||
} else {
|
||||
savings = beforeSav;
|
||||
resolvedSavings = beforeSav;
|
||||
}
|
||||
} else if (beforeTrs != null) {
|
||||
savings = beforeSav;
|
||||
} else if (afterTrs != null) {
|
||||
savings = afterSav;
|
||||
} else if (beforeTrs != null && beforeSav != 0) {
|
||||
resolvedSavings = beforeSav;
|
||||
} else if (afterTrs != null && afterSav != 0) {
|
||||
resolvedSavings = afterSav;
|
||||
} else {
|
||||
resolvedSavings = btz.getDSTSavings();
|
||||
}
|
||||
resolvedSavings = savings;
|
||||
} else {
|
||||
resolvedSavings = tz.getDSTSavings();
|
||||
}
|
||||
if (resolvedSavings == 0) {
|
||||
// Final fallback
|
||||
resolvedSavings = millisPerHour;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4041,8 +4041,6 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable {
|
||||
|
||||
fields[JULIAN_DAY] = (int) days + EPOCH_JULIAN_DAY;
|
||||
|
||||
// In some cases we will have to call this method again below to
|
||||
// adjust for DST pushing us into the next Julian day.
|
||||
computeGregorianAndDOWFields(fields[JULIAN_DAY]);
|
||||
|
||||
// Call framework method to have subclass compute its fields.
|
||||
|
Loading…
Reference in New Issue
Block a user