mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-09 15:27:38 +00:00
ICU-6321 TimeZone::getDisplayName(), move bug fixes from Java to C++
X-SVN-Rev: 24126
This commit is contained in:
parent
2fa2db21f7
commit
4635ea3a9c
3 changed files with 140 additions and 18 deletions
|
@ -1175,7 +1175,7 @@ TimeZone::getDisplayName(UBool daylight, EDisplayType style, const Locale& local
|
|||
char buf[128];
|
||||
fID.extract(0, sizeof(buf)-1, buf, sizeof(buf), "");
|
||||
#endif
|
||||
SimpleDateFormat format(style == LONG ? ZZZZ_STR : Z_STR,locale,status);
|
||||
SimpleDateFormat format(style == LONG ? ZZZZ_STR : Z_STR, locale, status);
|
||||
U_DEBUG_TZ_MSG(("getDisplayName(%s)\n", buf));
|
||||
if(!U_SUCCESS(status))
|
||||
{
|
||||
|
@ -1187,30 +1187,69 @@ TimeZone::getDisplayName(UBool daylight, EDisplayType style, const Locale& local
|
|||
return result.remove();
|
||||
}
|
||||
|
||||
UDate d = Calendar::getNow();
|
||||
int32_t rawOffset;
|
||||
int32_t dstOffset;
|
||||
this->getOffset(d, FALSE, rawOffset, dstOffset, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return result.remove();
|
||||
}
|
||||
|
||||
if ((daylight && dstOffset != 0) || (!daylight && dstOffset == 0)) {
|
||||
// Current time and the request (daylight / not daylight) agree.
|
||||
format.setTimeZone(*this);
|
||||
return format.format(d, result);
|
||||
}
|
||||
|
||||
// Create a new SimpleTimeZone as a stand-in for this zone; the
|
||||
// stand-in will have no DST, or all DST, but the same ID and offset,
|
||||
// stand-in will have no DST, or DST during July, but the same ID and offset,
|
||||
// and hence the same display name.
|
||||
// We don't cache these because they're small and cheap to create.
|
||||
UnicodeString tempID;
|
||||
getID(tempID);
|
||||
SimpleTimeZone *tz = NULL;
|
||||
if(daylight && useDaylightTime()){
|
||||
// For the pure-DST zone, we use JANUARY and DECEMBER
|
||||
int savings = getDSTSavings();
|
||||
tz = new SimpleTimeZone(getRawOffset(), getID(tempID),
|
||||
UCAL_JANUARY, 1, 0, 0,
|
||||
UCAL_FEBRUARY, 1, 0, 0,
|
||||
savings, status);
|
||||
}else{
|
||||
tz = new SimpleTimeZone(getRawOffset(), getID(tempID));
|
||||
if(daylight && useDaylightTime()){
|
||||
// The display name for daylight saving time was requested, but currently not in DST
|
||||
// Set a fixed date (July 1) in this Gregorian year
|
||||
GregorianCalendar cal(*this, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return result.remove();
|
||||
}
|
||||
cal.set(UCAL_MONTH, UCAL_JULY);
|
||||
cal.set(UCAL_DATE, 1);
|
||||
|
||||
// Get July 1 date
|
||||
d = cal.getTime(status);
|
||||
|
||||
// Check if it is in DST
|
||||
if (cal.get(UCAL_DST_OFFSET, status) == 0) {
|
||||
// We need to create a fake time zone
|
||||
tz = new SimpleTimeZone(rawOffset, tempID,
|
||||
UCAL_JUNE, 1, 0, 0,
|
||||
UCAL_AUGUST, 1, 0, 0,
|
||||
getDSTSavings(), status);
|
||||
if (U_FAILURE(status) || tz == NULL) {
|
||||
if (U_SUCCESS(status)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
return result.remove();
|
||||
}
|
||||
format.adoptTimeZone(tz);
|
||||
}
|
||||
} else {
|
||||
// The display name for standard time was requested, but currently in DST
|
||||
tz = new SimpleTimeZone(rawOffset, tempID);
|
||||
if (U_FAILURE(status) || tz == NULL) {
|
||||
if (U_SUCCESS(status)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
return result.remove();
|
||||
}
|
||||
format.adoptTimeZone(tz);
|
||||
}
|
||||
format.applyPattern(style == LONG ? ZZZZ_STR : Z_STR);
|
||||
Calendar *myCalendar = (Calendar*)format.getCalendar();
|
||||
myCalendar->setTimeZone(*tz); // copy
|
||||
|
||||
delete tz;
|
||||
|
||||
FieldPosition pos(FieldPosition::DONT_CARE);
|
||||
return format.format(UDate(864000000L), result, pos); // Must use a valid date here.
|
||||
format.format(d, result, status);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ void TimeZoneTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
|
|||
CASE(14, TestFractionalDST);
|
||||
CASE(15, TestFebruary);
|
||||
CASE(16, TestCanonicalID);
|
||||
CASE(17, TestDisplayNamesMeta);
|
||||
default: name = ""; break;
|
||||
}
|
||||
}
|
||||
|
@ -1805,4 +1806,84 @@ void TimeZoneTest::TestCanonicalID() {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test Display Names, choosing zones and lcoales where there are multiple
|
||||
// meta-zones defined.
|
||||
//
|
||||
static struct {
|
||||
const char *zoneName;
|
||||
const char *localeName;
|
||||
UBool summerTime;
|
||||
TimeZone::EDisplayType style;
|
||||
const char *expectedDisplayName; }
|
||||
zoneDisplayTestData [] = {
|
||||
// zone id locale summer format expected display name
|
||||
{"Europe/London", "en", FALSE, TimeZone::SHORT, "GMT"},
|
||||
{"Europe/London", "en", FALSE, TimeZone::LONG, "Greenwich Mean Time"},
|
||||
{"Europe/London", "en", TRUE, TimeZone::SHORT, "GMT+01:00" /*"BST"*/},
|
||||
{"Europe/London", "en", TRUE, TimeZone::LONG, "British Summer Time"},
|
||||
|
||||
{"America/Anchorage", "en", FALSE, TimeZone::SHORT, "AKST"},
|
||||
{"America/Anchorage", "en", FALSE, TimeZone::LONG, "Alaska Standard Time"},
|
||||
{"America/Anchorage", "en", TRUE, TimeZone::SHORT, "AKDT"},
|
||||
{"America/Anchorage", "en", TRUE, TimeZone::LONG, "Alaska Daylight Time"},
|
||||
|
||||
// Southern Hemisphere, all data from meta:Australia_Western
|
||||
{"Australia/Perth", "en", FALSE, TimeZone::SHORT, "GMT+08:00"/*"AWST"*/},
|
||||
{"Australia/Perth", "en", FALSE, TimeZone::LONG, "Australian Western Standard Time"},
|
||||
{"Australia/Perth", "en", TRUE, TimeZone::SHORT, "GMT+09:00"/*"AWDT"*/},
|
||||
{"Australia/Perth", "en", TRUE, TimeZone::LONG, "Australian Western Daylight Time"},
|
||||
|
||||
{"America/Sao_Paulo", "en", FALSE, TimeZone::SHORT, "GMT-03:00"/*"BRT"*/},
|
||||
{"America/Sao_Paulo", "en", FALSE, TimeZone::LONG, "Brasilia Time"},
|
||||
{"America/Sao_Paulo", "en", TRUE, TimeZone::SHORT, "GMT-02:00"/*"BRST"*/},
|
||||
{"America/Sao_Paulo", "en", TRUE, TimeZone::LONG, "Brasilia Summer Time"},
|
||||
|
||||
// No Summer Time, but had it before 1983.
|
||||
{"Pacific/Honolulu", "en", FALSE, TimeZone::SHORT, "HST"},
|
||||
{"Pacific/Honolulu", "en", FALSE, TimeZone::LONG, "Hawaii-Aleutian Standard Time"},
|
||||
{"Pacific/Honolulu", "en", TRUE, TimeZone::SHORT, "HST"},
|
||||
{"Pacific/Honolulu", "en", TRUE, TimeZone::LONG, "Hawaii-Aleutian Standard Time"},
|
||||
|
||||
// Northern, has Summer, not commonly used.
|
||||
{"Europe/Helsinki", "en", FALSE, TimeZone::SHORT, "GMT+02:00"/*"EET"*/},
|
||||
{"Europe/Helsinki", "en", FALSE, TimeZone::LONG, "Eastern European Time"},
|
||||
{"Europe/Helsinki", "en", TRUE, TimeZone::SHORT, "GMT+03:00"/*"EEST"*/},
|
||||
{"Europe/Helsinki", "en", true, TimeZone::LONG, "Eastern European Summer Time"},
|
||||
{NULL, NULL, FALSE, TimeZone::SHORT, NULL} // NULL values terminate list
|
||||
};
|
||||
|
||||
void TimeZoneTest::TestDisplayNamesMeta() {
|
||||
UBool sawAnError = FALSE;
|
||||
for (int testNum = 0; zoneDisplayTestData[testNum].zoneName != NULL; testNum++) {
|
||||
Locale locale = Locale::createFromName(zoneDisplayTestData[testNum].localeName);
|
||||
TimeZone *zone = TimeZone::createTimeZone(zoneDisplayTestData[testNum].zoneName);
|
||||
UnicodeString displayName;
|
||||
zone->getDisplayName(zoneDisplayTestData[testNum].summerTime,
|
||||
zoneDisplayTestData[testNum].style,
|
||||
locale,
|
||||
displayName);
|
||||
if (displayName != zoneDisplayTestData[testNum].expectedDisplayName) {
|
||||
sawAnError = TRUE;
|
||||
char name[100];
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
displayName.extract(name, 100, NULL, status);
|
||||
errln("Incorrect time zone display name. zone = \"%s\",\n"
|
||||
" locale = \"%s\", style = %s, Summertime = %d\n"
|
||||
" Expected \"%s\", "
|
||||
" Got \"%s\"\n", zoneDisplayTestData[testNum].zoneName,
|
||||
zoneDisplayTestData[testNum].localeName,
|
||||
zoneDisplayTestData[testNum].style==TimeZone::SHORT ?
|
||||
"SHORT" : "LONG",
|
||||
zoneDisplayTestData[testNum].summerTime,
|
||||
zoneDisplayTestData[testNum].expectedDisplayName,
|
||||
name);
|
||||
}
|
||||
delete zone;
|
||||
}
|
||||
if (sawAnError) {
|
||||
errln("Note: Errors could be the result of changes to zoneStrings locale data");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
void TestFebruary(void);
|
||||
|
||||
void TestCanonicalID(void);
|
||||
|
||||
virtual void TestDisplayNamesMeta();
|
||||
|
||||
static const UDate INTERVAL;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue