/*
* Test case for checking if a TimeZone is properly set in the result calendar
* and if the result TimeZone has the expected behavior.
*/
public void TestTimeZoneRoundTrip() {
TimeZone unknownZone = new SimpleTimeZone(-31415, "Etc/Unknown");
int badDstOffset = -1234;
int badZoneOffset = -2345;
int[][] testDateData = {
{2007, 1, 15},
{2007, 6, 15},
{1990, 1, 15},
{1990, 6, 15},
{1960, 1, 15},
{1960, 6, 15},
};
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.clear();
// Set up rule equivalency test range
long low, high;
cal.set(1900, 0, 1);
low = cal.getTimeInMillis();
cal.set(2040, 0, 1);
high = cal.getTimeInMillis();
// Set up test dates
Date[] DATES = new Date[testDateData.length];
cal.clear();
for (int i = 0; i < DATES.length; i++) {
cal.set(testDateData[i][0], testDateData[i][1], testDateData[i][2]);
DATES[i] = cal.getTime();
}
// Set up test locales
ULocale[] LOCALES = null;
if (getInclusion() > 5) {
LOCALES = ULocale.getAvailableLocales();
} else {
LOCALES = new ULocale[] {new ULocale("en"), new ULocale("en_CA"), new ULocale("fr"), new ULocale("zh_Hant")};
}
String[] tzids = TimeZone.getAvailableIDs();
int[] inOffsets = new int[2];
int[] outOffsets = new int[2];
// Run the roundtrip test
for (int locidx = 0; locidx < LOCALES.length; locidx++) {
for (int patidx = 0; patidx < PATTERNS.length; patidx++) {
SimpleDateFormat sdf = new SimpleDateFormat(PATTERNS[patidx], LOCALES[locidx]);
for (int tzidx = 0; tzidx < tzids.length; tzidx++) {
TimeZone tz = TimeZone.getTimeZone(tzids[tzidx]);
for (int datidx = 0; datidx < DATES.length; datidx++) {
// Format
sdf.setTimeZone(tz);
String tzstr = sdf.format(DATES[datidx]);
// Before parse, set unknown zone to SimpleDateFormat instance
// just for making sure that it does not depends on the time zone
// originally set.
sdf.setTimeZone(unknownZone);
// Parse
ParsePosition pos = new ParsePosition(0);
Calendar outcal = Calendar.getInstance(unknownZone);
outcal.set(Calendar.DST_OFFSET, badDstOffset);
outcal.set(Calendar.ZONE_OFFSET, badZoneOffset);
sdf.parse(tzstr, outcal, pos);
// Check the result
TimeZone outtz = outcal.getTimeZone();
tz.getOffset(DATES[datidx].getTime(), false, inOffsets);
outtz.getOffset(DATES[datidx].getTime(), false, outOffsets);
if (PATTERNS[patidx].equals("VVVV")) {
// Location: time zone rule must be preserved except
// zones not actually associated with a specific location.
// Time zones in this category do not have "/" in its ID.
String canonicalID = TimeZone.getCanonicalID(tzids[tzidx]);
if (canonicalID != null && !outtz.getID().equals(canonicalID)) {
// Canonical ID did not match - check the rules
boolean bFailure = false;
if ((tz instanceof BasicTimeZone) && (outtz instanceof BasicTimeZone)) {
bFailure = !(canonicalID.indexOf('/') == -1)
&& !((BasicTimeZone)outtz).hasEquivalentTransitions(tz, low, high);
}
if (bFailure) {
errln("Canonical round trip failed; tz=" + tzids[tzidx]
+ ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx]
+ ", time=" + DATES[datidx].getTime() + ", str=" + tzstr
+ ", outtz=" + outtz.getID());
} else {
logln("Canonical round trip failed (as expected); tz=" + tzids[tzidx]
+ ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx]
+ ", time=" + DATES[datidx].getTime() + ", str=" + tzstr
+ ", outtz=" + outtz.getID());
}
}
} else {
// Check if localized GMT format or RFC format is used.
int numDigits = 0;