ICU-6602 Construct a generic location string with a substring of its tzid for an unknown time zone except ones starting with Etc/. Updated test case to check such time zones also round trip with pattern VVVV.
X-SVN-Rev: 25240
This commit is contained in:
parent
83280b219a
commit
1b5ba9ed42
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2007-2008, International Business Machines Corporation and *
|
||||
* Copyright (C) 2007-2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -630,9 +630,7 @@ ZoneStringFormat::ZoneStringFormat(const Locale &locale, UErrorCode &status)
|
||||
UnicodeString city;
|
||||
UnicodeString countryCode;
|
||||
ZoneMeta::getCanonicalCountry(utzid, countryCode);
|
||||
if (countryCode.isEmpty()) {
|
||||
zstrarray[ZSIDX_LOCATION] = NULL;
|
||||
} else {
|
||||
if (!countryCode.isEmpty()) {
|
||||
const UChar* tmpCity = getZoneStringFromBundle(zoneItem, gExemplarCityTag);
|
||||
if (tmpCity != NULL) {
|
||||
city.setTo(TRUE, tmpCity, -1);
|
||||
@ -672,6 +670,42 @@ ZoneStringFormat::ZoneStringFormat(const Locale &locale, UErrorCode &status)
|
||||
location.append((UChar)0).truncate(locLen);
|
||||
|
||||
zstrarray[ZSIDX_LOCATION] = location.getTerminatedBuffer();
|
||||
} else {
|
||||
if (uprv_strlen(tzid) > 4 && uprv_strncmp(tzid, "Etc/", 4) == 0) {
|
||||
// "Etc/xxx" is not associated with a specific location, so localized
|
||||
// GMT format is always used as generic location format.
|
||||
zstrarray[ZSIDX_LOCATION] = NULL;
|
||||
} else {
|
||||
// When a new time zone ID, which is actually associated with a specific
|
||||
// location, is added in tzdata, but the current CLDR data does not have
|
||||
// the information yet, ICU creates a generic location string based on
|
||||
// the ID. This implementation supports canonical time zone round trip
|
||||
// with format pattern "VVVV". See #6602 for the details.
|
||||
UnicodeString loc(utzid);
|
||||
int32_t slashIdx = loc.lastIndexOf((UChar)0x2f);
|
||||
if (slashIdx == -1) {
|
||||
// A time zone ID without slash in the tz database is not
|
||||
// associated with a specific location. For instances,
|
||||
// MET, CET, EET and WET fall into this category.
|
||||
// In this case, we still use GMT format as fallback.
|
||||
zstrarray[ZSIDX_LOCATION] = NULL;
|
||||
} else {
|
||||
FieldPosition fpos;
|
||||
Formattable params[] = {
|
||||
Formattable(loc)
|
||||
};
|
||||
regionFmt->format(params, 1, location, fpos, status);
|
||||
if (U_FAILURE(status)) {
|
||||
goto error_cleanup;
|
||||
}
|
||||
// Workaround for reducing UMR warning in Purify.
|
||||
// Append NULL before calling getTerminatedBuffer()
|
||||
int32_t locLen = location.length();
|
||||
location.append((UChar)0).truncate(locLen);
|
||||
|
||||
zstrarray[ZSIDX_LOCATION] = location.getTerminatedBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UBool commonlyUsed = isCommonlyUsed(zoneItem);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2007-2008, International Business Machines Corporation and *
|
||||
* Copyright (C) 2007-2009, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -113,9 +113,6 @@ TimeZoneFormatTest::TestTimeZoneRoundTrip(void) {
|
||||
for (int32_t locidx = 0; locidx < nLocales; locidx++) {
|
||||
for (int32_t patidx = 0; patidx < NUM_PATTERNS; patidx++) {
|
||||
|
||||
//DEBUG static const char* PATTERNS[] = {"z", "zzzz", "Z", "ZZZZ", "v", "vvvv", "V", "VVVV"};
|
||||
//if (patidx != 1) continue;
|
||||
|
||||
SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)PATTERNS[patidx], LOCALES[locidx], status);
|
||||
if (U_FAILURE(status)) {
|
||||
errln((UnicodeString)"new SimpleDateFormat failed for pattern " +
|
||||
@ -170,6 +167,39 @@ TimeZoneFormatTest::TestTimeZoneRoundTrip(void) {
|
||||
status = U_ZERO_ERROR;
|
||||
}
|
||||
|
||||
if (uprv_strcmp(PATTERNS[patidx], "VVVV") == 0) {
|
||||
// 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.
|
||||
UnicodeString canonical;
|
||||
TimeZone::getCanonicalID(*tzid, canonical, status);
|
||||
if (U_FAILURE(status)) {
|
||||
// Uknown ID - we should not get here
|
||||
errln((UnicodeString)"Unknown ID " + *tzid);
|
||||
status = U_ZERO_ERROR;
|
||||
} else if (outtzid != canonical) {
|
||||
// Canonical ID did not match - check the rules
|
||||
if (!((BasicTimeZone*)&outtz)->hasEquivalentTransitions((BasicTimeZone&)*tz, low, high, TRUE, status)) {
|
||||
if (canonical.indexOf((UChar)0x27 /*'/'*/) == -1) {
|
||||
// Exceptional cases, such as CET, EET, MET and WET
|
||||
logln("Canonical round trip failed (as expected); tz=" + *tzid
|
||||
+ ", locale=" + LOCALES[locidx].getName() + ", pattern=" + PATTERNS[patidx]
|
||||
+ ", time=" + DATES[datidx] + ", str=" + tzstr
|
||||
+ ", outtz=" + outtzid);
|
||||
} else {
|
||||
errln("Canonical round trip failed; tz=" + *tzid
|
||||
+ ", locale=" + LOCALES[locidx].getName() + ", pattern=" + PATTERNS[patidx]
|
||||
+ ", time=" + DATES[datidx] + ", str=" + tzstr
|
||||
+ ", outtz=" + outtzid);
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
errln("hasEquivalentTransitions failed");
|
||||
status = U_ZERO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Check if localized GMT format or RFC format is used.
|
||||
int32_t numDigits = 0;
|
||||
for (int n = 0; n < tzstr.length(); n++) {
|
||||
@ -187,9 +217,7 @@ TimeZoneFormatTest::TestTimeZoneRoundTrip(void) {
|
||||
+ ", time=" + DATES[datidx] + ", str=" + tzstr
|
||||
+ ", inOffset=" + inOffset + ", outOffset=" + outOffset);
|
||||
}
|
||||
} else if (uprv_strcmp(PATTERNS[patidx], "z") == 0 || uprv_strcmp(PATTERNS[patidx], "zzzz") == 0
|
||||
|| uprv_strcmp(PATTERNS[patidx], "v") == 0 || uprv_strcmp(PATTERNS[patidx], "vvvv") == 0
|
||||
|| uprv_strcmp(PATTERNS[patidx], "V") == 0) {
|
||||
} else {
|
||||
// Specific or generic: raw offset must be preserved.
|
||||
if (inRaw != outRaw) {
|
||||
errln((UnicodeString)"Raw offset round trip failed; tz=" + *tzid
|
||||
@ -197,26 +225,6 @@ TimeZoneFormatTest::TestTimeZoneRoundTrip(void) {
|
||||
+ ", time=" + DATES[datidx] + ", str=" + tzstr
|
||||
+ ", inRawOffset=" + inRaw + ", outRawOffset=" + outRaw);
|
||||
}
|
||||
} else { // "VVVV"
|
||||
// Location: time zone rule must be preserved.
|
||||
UnicodeString canonical;
|
||||
TimeZone::getCanonicalID(*tzid, canonical, status);
|
||||
if (U_FAILURE(status)) {
|
||||
// Uknown ID - we should not get here
|
||||
errln((UnicodeString)"Unknown ID " + *tzid);
|
||||
status = U_ZERO_ERROR;
|
||||
} else if (outtzid != canonical) {
|
||||
// Canonical ID did not match - check the rules
|
||||
if (!((BasicTimeZone*)&outtz)->hasEquivalentTransitions((BasicTimeZone&)*tz, low, high, TRUE, status)) {
|
||||
errln("Canonical round trip failed; tz=" + *tzid
|
||||
+ ", locale=" + LOCALES[locidx].getName() + ", pattern=" + PATTERNS[patidx]
|
||||
+ ", time=" + DATES[datidx] + ", str=" + tzstr
|
||||
+ ", outtz=" + outtzid);
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
errln("hasEquivalentTransitions failed");
|
||||
status = U_ZERO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete outcal;
|
||||
|
Loading…
Reference in New Issue
Block a user