ICU-6216 Fixed a VTIMEZONE parsing problem in ICU4C.

X-SVN-Rev: 23780
This commit is contained in:
Yoshito Umaoka 2008-04-10 03:41:22 +00:00
parent 10b591004d
commit a55d75d400
4 changed files with 300 additions and 5 deletions

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and *
* Copyright (C) 2007-2008, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -629,7 +629,7 @@ public:
* @param numStartTimes The number of elements in the parameter "startTimes"
* @param timeRuleType The time type of the start times, which is one of
* <code>DataTimeRule::WALL_TIME</code>, <code>STANDARD_TIME</code>
* and <code>UNIVERSAL_TIME</code>.
* and <code>UTC_TIME</code>.
* @draft ICU 3.8
*/
TimeArrayTimeZoneRule(const UnicodeString& name, int32_t rawOffset, int32_t dstSavings,
@ -684,7 +684,7 @@ public:
/**
* Gets the time type of the start times used by this rule. The return value
* is either <code>DateTimeRule::WALL_TIME</code> or <code>STANDARD_TIME</code>
* or <code>UNIVERSAL_TIME</code>.
* or <code>UTC_TIME</code>.
*
* @return The time type used of the start times used by this rule.
* @draft ICU 3.8

View File

@ -1328,6 +1328,9 @@ VTimeZone::parse(UErrorCode& status) {
UVector *dates = NULL; // list of RDATE or RRULE strings
UVector *rules = NULL; // list of TimeZoneRule instances
int32_t finalRuleIdx = -1;
int32_t finalRuleCount = 0;
rules = new UVector(status);
if (U_FAILURE(status)) {
goto cleanupParse;
@ -1545,6 +1548,91 @@ VTimeZone::parse(UErrorCode& status) {
status = U_MEMORY_ALLOCATION_ERROR;
goto cleanupParse;
}
initialRule = NULL; // already adopted by RBTZ, no need to delete
for (n = 0; n < rules->size(); n++) {
TimeZoneRule *r = (TimeZoneRule*)rules->elementAt(n);
if (r->getDynamicClassID() == AnnualTimeZoneRule::getStaticClassID()) {
if (((AnnualTimeZoneRule*)r)->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
finalRuleCount++;
finalRuleIdx = n;
}
}
}
if (finalRuleCount > 2) {
// Too many final rules
status = U_ILLEGAL_ARGUMENT_ERROR;
goto cleanupParse;
}
if (finalRuleCount == 1) {
if (rules->size() == 1) {
// Only one final rule, only governs the initial rule,
// which is already initialized, thus, we do not need to
// add this transition rule
rules->removeAllElements();
} else {
// Normalize the final rule
AnnualTimeZoneRule *finalRule = (AnnualTimeZoneRule*)rules->elementAt(finalRuleIdx);
int32_t tmpRaw = finalRule->getRawOffset();
int32_t tmpDST = finalRule->getDSTSavings();
// Find the last non-final rule
UDate finalStart, start;
finalRule->getFirstStart(initialRawOffset, initialDSTSavings, finalStart);
start = finalStart;
for (n = 0; n < rules->size(); n++) {
if (finalRuleIdx == n) {
continue;
}
TimeZoneRule *r = (TimeZoneRule*)rules->elementAt(n);
UDate lastStart;
r->getFinalStart(tmpRaw, tmpDST, lastStart);
if (lastStart > start) {
finalRule->getNextStart(lastStart,
r->getRawOffset(),
r->getDSTSavings(),
FALSE,
start);
}
}
TimeZoneRule *newRule;
UnicodeString tznam;
if (start == finalStart) {
// Transform this into a single transition
newRule = new TimeArrayTimeZoneRule(
finalRule->getName(tznam),
finalRule->getRawOffset(),
finalRule->getDSTSavings(),
&finalStart,
1,
DateTimeRule::UTC_TIME);
} else {
// Update the end year
int32_t y, m, d, dow, doy, mid;
Grego::timeToFields(start, y, m, d, dow, doy, mid);
newRule = new AnnualTimeZoneRule(
finalRule->getName(tznam),
finalRule->getRawOffset(),
finalRule->getDSTSavings(),
*(finalRule->getRule()),
finalRule->getStartYear(),
y);
}
if (newRule == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
goto cleanupParse;
}
rules->removeElementAt(finalRuleIdx);
rules->addElement(newRule, status);
if (U_FAILURE(status)) {
delete newRule;
goto cleanupParse;
}
}
}
while (!rules->isEmpty()) {
TimeZoneRule *tzr = (TimeZoneRule*)rules->orphanElementAt(0);
rbtz->addTransitionRule(tzr, status);

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and *
* Copyright (C) 2007-2008, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -125,6 +125,7 @@ void TimeZoneRuleTest::runIndexedTest( int32_t index, UBool exec, const char* &n
CASE(11, TestSimpleTimeZoneCoverage);
CASE(12, TestVTimeZoneCoverage);
CASE(13, TestVTimeZoneParse);
CASE(14, TestT6216);
default: name = ""; break;
}
}
@ -1862,6 +1863,211 @@ TimeZoneRuleTest::TestVTimeZoneParse(void) {
delete foo;
}
void
TimeZoneRuleTest::TestT6216(void) {
// Test case in #6216
static const UChar tokyoTZ[] = {
/* "BEGIN:VCALENDAR\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
/* "VERSION:2.0\r\n" */
0x56,0x45,0x52,0x53,0x49,0x4f,0x4e,0x3a,0x32,0x2e,0x30,0x0d,0x0a,
/* "PRODID:-//PYVOBJECT//NONSGML Version 1//EN\r\n" */
0x50,0x52,0x4f,0x44,0x49,0x44,0x3a,0x2d,0x2f,0x2f,0x50,0x59,0x56,0x4f,0x42,0x4a,0x45,0x43,0x54,0x2f,0x2f,0x4e,0x4f,0x4e,0x53,0x47,0x4d,0x4c,0x20,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x2f,0x2f,0x45,0x4e,0x0d,0x0a,
/* "BEGIN:VTIMEZONE\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
/* "TZID:Asia/Tokyo\r\n" */
0x54,0x5a,0x49,0x44,0x3a,0x41,0x73,0x69,0x61,0x2f,0x54,0x6f,0x6b,0x79,0x6f,0x0d,0x0a,
/* "BEGIN:STANDARD\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
/* "DTSTART:20000101T000000\r\n" */
0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x32,0x30,0x30,0x30,0x30,0x31,0x30,0x31,0x54,0x30,0x30,0x30,0x30,0x30,0x30,0x0d,0x0a,
/* "RRULE:FREQ=YEARLY;BYMONTH=1\r\n" */
0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x31,0x0d,0x0a,
/* "TZNAME:Asia/Tokyo\r\n" */
0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x41,0x73,0x69,0x61,0x2f,0x54,0x6f,0x6b,0x79,0x6f,0x0d,0x0a,
/* "TZOFFSETFROM:+0900\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2b,0x30,0x39,0x30,0x30,0x0d,0x0a,
/* "TZOFFSETTO:+0900\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2b,0x30,0x39,0x30,0x30,0x0d,0x0a,
/* "END:STANDARD\r\n" */
0x45,0x4e,0x44,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
/* "END:VTIMEZONE\r\n" */
0x45,0x4e,0x44,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
/* "END:VCALENDAR" */
0x45,0x4e,0x44,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
0
};
// Single final rule, overlapping with another
static const UChar finalOverlap[] = {
/* "BEGIN:VCALENDAR\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
/* "BEGIN:VTIMEZONE\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
/* "TZID:FinalOverlap\r\n" */
0x54,0x5a,0x49,0x44,0x3a,0x46,0x69,0x6e,0x61,0x6c,0x4f,0x76,0x65,0x72,0x6c,0x61,0x70,0x0d,0x0a,
/* "BEGIN:STANDARD\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
/* "TZOFFSETFROM:-0200\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
/* "TZOFFSETTO:-0300\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
/* "TZNAME:STD\r\n" */
0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x53,0x54,0x44,0x0d,0x0a,
/* "DTSTART:20001029T020000\r\n" */
0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x32,0x30,0x30,0x30,0x31,0x30,0x32,0x39,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
/* "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10\r\n" */
0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x2d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x31,0x30,0x0d,0x0a,
/* "END:STANDARD\r\n" */
0x45,0x4e,0x44,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
/* "BEGIN:DAYLIGHT\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x44,0x41,0x59,0x4c,0x49,0x47,0x48,0x54,0x0d,0x0a,
/* "TZOFFSETFROM:-0300\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
/* "TZOFFSETTO:-0200\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
/* "TZNAME:DST\r\n" */
0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x44,0x53,0x54,0x0d,0x0a,
/* "DTSTART:19990404T020000\r\n" */
0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x31,0x39,0x39,0x39,0x30,0x34,0x30,0x34,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
/* "RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20050403T040000Z\r\n" */
0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x34,0x3b,0x55,0x4e,0x54,0x49,0x4c,0x3d,0x32,0x30,0x30,0x35,0x30,0x34,0x30,0x33,0x54,0x30,0x34,0x30,0x30,0x30,0x30,0x5a,0x0d,0x0a,
/* "END:DAYLIGHT\r\n" */
0x45,0x4e,0x44,0x3a,0x44,0x41,0x59,0x4c,0x49,0x47,0x48,0x54,0x0d,0x0a,
/* "END:VTIMEZONE\r\n" */
0x45,0x4e,0x44,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
/* "END:VCALENDAR" */
0x45,0x4e,0x44,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
0
};
// Single final rule, no overlapping with another
static const UChar finalNonOverlap[] = {
/* "BEGIN:VCALENDAR\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
/* "BEGIN:VTIMEZONE\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
/* "TZID:FinalNonOverlap\r\n" */
0x54,0x5a,0x49,0x44,0x3a,0x46,0x69,0x6e,0x61,0x6c,0x4e,0x6f,0x6e,0x4f,0x76,0x65,0x72,0x6c,0x61,0x70,0x0d,0x0a,
/* "BEGIN:STANDARD\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
/* "TZOFFSETFROM:-0200\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
/* "TZOFFSETTO:-0300\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
/* "TZNAME:STD\r\n" */
0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x53,0x54,0x44,0x0d,0x0a,
/* "DTSTART:20001029T020000\r\n" */
0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x32,0x30,0x30,0x30,0x31,0x30,0x32,0x39,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
/* "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10;UNTIL=20041031T040000Z\r\n" */
0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x2d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x31,0x30,0x3b,0x55,0x4e,0x54,0x49,0x4c,0x3d,0x32,0x30,0x30,0x34,0x31,0x30,0x33,0x31,0x54,0x30,0x34,0x30,0x30,0x30,0x30,0x5a,0x0d,0x0a,
/* "END:STANDARD\r\n" */
0x45,0x4e,0x44,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
/* "BEGIN:DAYLIGHT\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x44,0x41,0x59,0x4c,0x49,0x47,0x48,0x54,0x0d,0x0a,
/* "TZOFFSETFROM:-0300\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
/* "TZOFFSETTO:-0200\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
/* "TZNAME:DST\r\n" */
0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x44,0x53,0x54,0x0d,0x0a,
/* "DTSTART:19990404T020000\r\n" */
0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x31,0x39,0x39,0x39,0x30,0x34,0x30,0x34,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
/* "RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=20050403T040000Z\r\n" */
0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x34,0x3b,0x55,0x4e,0x54,0x49,0x4c,0x3d,0x32,0x30,0x30,0x35,0x30,0x34,0x30,0x33,0x54,0x30,0x34,0x30,0x30,0x30,0x30,0x5a,0x0d,0x0a,
/* "END:DAYLIGHT\r\n" */
0x45,0x4e,0x44,0x3a,0x44,0x41,0x59,0x4c,0x49,0x47,0x48,0x54,0x0d,0x0a,
/* "BEGIN:STANDARD\r\n" */
0x42,0x45,0x47,0x49,0x4e,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
/* "TZOFFSETFROM:-0200\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x46,0x52,0x4f,0x4d,0x3a,0x2d,0x30,0x32,0x30,0x30,0x0d,0x0a,
/* "TZOFFSETTO:-0300\r\n" */
0x54,0x5a,0x4f,0x46,0x46,0x53,0x45,0x54,0x54,0x4f,0x3a,0x2d,0x30,0x33,0x30,0x30,0x0d,0x0a,
/* "TZNAME:STDFINAL\r\n" */
0x54,0x5a,0x4e,0x41,0x4d,0x45,0x3a,0x53,0x54,0x44,0x46,0x49,0x4e,0x41,0x4c,0x0d,0x0a,
/* "DTSTART:20071028T020000\r\n" */
0x44,0x54,0x53,0x54,0x41,0x52,0x54,0x3a,0x32,0x30,0x30,0x37,0x31,0x30,0x32,0x38,0x54,0x30,0x32,0x30,0x30,0x30,0x30,0x0d,0x0a,
/* "RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10\r\n" */
0x52,0x52,0x55,0x4c,0x45,0x3a,0x46,0x52,0x45,0x51,0x3d,0x59,0x45,0x41,0x52,0x4c,0x59,0x3b,0x42,0x59,0x44,0x41,0x59,0x3d,0x2d,0x31,0x53,0x55,0x3b,0x42,0x59,0x4d,0x4f,0x4e,0x54,0x48,0x3d,0x31,0x30,0x0d,0x0a,
/* "END:STANDARD\r\n" */
0x45,0x4e,0x44,0x3a,0x53,0x54,0x41,0x4e,0x44,0x41,0x52,0x44,0x0d,0x0a,
/* "END:VTIMEZONE\r\n" */
0x45,0x4e,0x44,0x3a,0x56,0x54,0x49,0x4d,0x45,0x5a,0x4f,0x4e,0x45,0x0d,0x0a,
/* "END:VCALENDAR" */
0x45,0x4e,0x44,0x3a,0x56,0x43,0x41,0x4c,0x45,0x4e,0x44,0x41,0x52,0x0d,0x0a,
0
};
static const int32_t TestDates[][3] = {
{1995, UCAL_JANUARY, 1},
{1995, UCAL_JULY, 1},
{2000, UCAL_JANUARY, 1},
{2000, UCAL_JULY, 1},
{2005, UCAL_JANUARY, 1},
{2005, UCAL_JULY, 1},
{2010, UCAL_JANUARY, 1},
{2010, UCAL_JULY, 1},
{0, 0, 0}
};
static const UnicodeString TestZones[] = {
UnicodeString(tokyoTZ),
UnicodeString(finalOverlap),
UnicodeString(finalNonOverlap),
UnicodeString()
};
int32_t Expected[][8] = {
// JAN90 JUL90 JAN00 JUL00 JAN05 JUL05 JAN10 JUL10
{ 32400000, 32400000, 32400000, 32400000, 32400000, 32400000, 32400000, 32400000},
{-10800000, -10800000, -7200000, -7200000, -10800000, -7200000, -10800000, -10800000},
{-10800000, -10800000, -7200000, -7200000, -10800000, -7200000, -10800000, -10800000}
};
int32_t i, j;
// Get test times
UDate times[sizeof(TestDates) / (3 * sizeof(int32_t))];
int32_t numTimes;
UErrorCode status = U_ZERO_ERROR;
TimeZone *utc = TimeZone::createTimeZone("Etc/GMT");
GregorianCalendar cal(utc, status);
if (U_FAILURE(status)) {
errln("FAIL: Failed to creat a GregorianCalendar");
return;
}
for (i = 0; TestDates[i][2] != 0; i++) {
cal.clear();
cal.set(TestDates[i][0], TestDates[i][1], TestDates[i][2]);
times[i] = cal.getTime(status);
if (U_FAILURE(status)) {
errln("FAIL: getTime failed");
return;
}
}
numTimes = i;
// Test offset
for (i = 0; !TestZones[i].isEmpty(); i++) {
VTimeZone *vtz = VTimeZone::createVTimeZone(TestZones[i], status);
if (U_FAILURE(status)) {
errln("FAIL: failed to create VTimeZone");
continue;
}
for (j = 0; j < numTimes; j++) {
int32_t raw, dst;
status = U_ZERO_ERROR;
vtz->getOffset(times[j], FALSE, raw, dst, status);
if (U_FAILURE(status)) {
errln((UnicodeString)"FAIL: getOffset failed for time zone " + i + " at " + times[j]);
}
int32_t offset = raw + dst;
if (offset != Expected[i][j]) {
errln((UnicodeString)"FAIL: Invalid offset at time(" + times[j] + "):" + offset + " Expected:" + Expected[i][j]);
}
}
}
}
//----------- private test helpers -------------------------------------------------
UDate

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and *
* Copyright (C) 2007-2008, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -34,6 +34,7 @@ public:
void TestSimpleTimeZoneCoverage(void);
void TestVTimeZoneCoverage(void);
void TestVTimeZoneParse(void);
void TestT6216(void);
private:
void verifyTransitions(BasicTimeZone& icutz, UDate start, UDate end);