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:
Yoshito Umaoka 2007-11-27 07:48:45 +00:00
parent 12aea479ca
commit 8cd61ae501
5 changed files with 213 additions and 68 deletions

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0e01a9a1a779d74792f4ae0391b586695f6dd280d7d972fd1e9919bbe74905fe
size 5391701
oid sha256:d50452d34dbff6e92dbe1d2985eb62696e35bafd40914a57afd0ba2edc8c8876
size 5409244

View File

@ -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;
}
}
}

View File

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