}
}
if (tztype != TZTYPE_UNK) {
copy = (Calendar)cal.clone();
TimeZone tz = copy.getTimeZone();
BasicTimeZone btz = null;
if (tz instanceof BasicTimeZone) {
btz = (BasicTimeZone)tz;
}
// Get local millis
copy.set(Calendar.ZONE_OFFSET, 0);
copy.set(Calendar.DST_OFFSET, 0);
long localMillis = copy.getTimeInMillis();
// Make sure parsed time zone type (Standard or Daylight)
// matches the rule used by the parsed time zone.
int[] offsets = new int[2];
if (btz != null) {
if (tztype == TZTYPE_STD) {
btz.getOffsetFromLocal(localMillis,
BasicTimeZone.LOCAL_STD, BasicTimeZone.LOCAL_STD, offsets);
} else {
btz.getOffsetFromLocal(localMillis,
BasicTimeZone.LOCAL_DST, BasicTimeZone.LOCAL_DST, offsets);
}
} else {
// No good way to resolve ambiguous time at transition,
// but following code work in most case.
tz.getOffset(localMillis, true, offsets);
if (tztype == TZTYPE_STD && offsets[1] != 0
|| tztype == TZTYPE_DST && offsets[1] == 0) {
// Roll back one day and try it again.
// Note: This code assumes 1. timezone transition only happens
// once within 24 hours at max
// 2. the difference of local offsets at the transition is
// less than 24 hours.
tz.getOffset(localMillis - (24*60*60*1000), true, offsets);
}
}
// Now, compare the results with parsed type, either standard or
// daylight saving time
int resolvedSavings = offsets[1];
if (tztype == TZTYPE_STD) {
if (offsets[1] != 0) {
// Override DST_OFFSET = 0 in the result calendar
resolvedSavings = 0;
}
} else { // tztype == TZTYPE_DST
if (offsets[1] == 0) {
if (btz != null) {
long time = localMillis + offsets[0];
// We use the nearest daylight saving time rule.
TimeZoneTransition beforeTrs, afterTrs;
long beforeT = time, afterT = time;
int beforeSav = 0, afterSav = 0;
// Search for DST rule before or on the time
while (true) {
beforeTrs = btz.getPreviousTransition(beforeT, true);
if (beforeTrs == null) {
break;
}
beforeT = beforeTrs.getTime() - 1;
beforeSav = beforeTrs.getFrom().getDSTSavings();
if (beforeSav != 0) {
break;
}
}
// Search for DST rule after the time
while (true) {
afterTrs = btz.getNextTransition(afterT, false);
if (afterTrs == null) {
break;
}
afterT = afterTrs.getTime();
afterSav = afterTrs.getTo().getDSTSavings();
if (afterSav != 0) {
break;
}
}
if (beforeTrs != null && afterTrs != null) {
if (time - beforeT > afterT - time) {
resolvedSavings = afterSav;
} else {
resolvedSavings = beforeSav;
}
} else if (beforeTrs != null && beforeSav != 0) {
resolvedSavings = beforeSav;
} else if (afterTrs != null && afterSav != 0) {
resolvedSavings = afterSav;
} else {
resolvedSavings = btz.getDSTSavings();
}
} else {
resolvedSavings = tz.getDSTSavings();
}
if (resolvedSavings == 0) {