ICU-7606 VTimeZone, add factory to create from BasicTimeZone.

X-SVN-Rev: 28311
This commit is contained in:
Andy Heninger 2010-07-14 23:42:09 +00:00
parent a8575b74fa
commit 5bcaaa08dc
4 changed files with 97 additions and 8 deletions

View File

@ -362,9 +362,10 @@ BasicTimeZone::getTimeZoneRulesAfter(UDate start, InitialTimeZoneRule*& initial,
}
UDate updatedTime = tzt.getTime();
if (updatedTime == time) {
// Time zones that have been manually initialized with inconsistent transtion rules
// can bring us here. Bail out to prevent an infinite loop.
status = U_INVALID_STATE_ERROR;
// Can get here if rules for start & end of daylight time have exactly
// the same time.
// TODO: fix getNextTransition() to prevent it?
status = U_INVALID_STATE_ERROR;
goto error;
}
time = updatedTime;

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2007-2009, International Business Machines Corporation and *
* Copyright (C) 2007-2010, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -30,7 +30,9 @@ class UVector;
* With the <code>VTimeZone</code> instance created from the ID, you can write out the rule
* in RFC2445 VTIMEZONE format. Also, you can create a <code>VTimeZone</code> instance
* from RFC2445 VTIMEZONE data stream, which allows you to calculate time
* zone offset by the rules defined by the data.<br><br>
* zone offset by the rules defined by the data. Or, you can create a
* <code>VTimeZone</code> from any other ICU <code>BasicTimeZone</code>.
* <br><br>
* Note: The consumer of this class reading or writing VTIMEZONE data is responsible to
* decode or encode Non-ASCII text. Methods reading/writing VTIMEZONE data in this class
* do nothing with MIME encoding.
@ -87,6 +89,16 @@ public:
*/
static VTimeZone* createVTimeZoneByID(const UnicodeString& ID);
/**
* Create a <code>VTimeZone</code> instance using a basic time zone.
* @param basicTZ The basic time zone instance
* @param status Output param to filled in with a success or an error.
* @return A <code>VTimeZone</code> object initialized by the basic time zone.
* @draft ICU 4.6
*/
static VTimeZone* createVTimeZoneFromBasicTimeZone(const BasicTimeZone& basicTZ,
UErrorCode &status);
/**
* Create a <code>VTimeZone</code> instance by RFC2445 VTIMEZONE data
*

View File

@ -1064,8 +1064,39 @@ VTimeZone::createVTimeZoneByID(const UnicodeString& ID) {
UErrorCode status = U_ZERO_ERROR;
UResourceBundle *bundle = NULL;
const UChar* versionStr = NULL;
int32_t len;
bundle = ures_openDirect(NULL, "zoneinfo", &status);
int32_t len = 0;
bundle = ures_openDirect(NULL, "zoneinfo64", &status);
versionStr = ures_getStringByKey(bundle, "TZVersion", &len, &status);
if (U_SUCCESS(status)) {
vtz->icutzver.setTo(versionStr, len);
}
ures_close(bundle);
return vtz;
}
VTimeZone*
VTimeZone::createVTimeZoneFromBasicTimeZone(const BasicTimeZone& basic_time_zone, UErrorCode &status) {
if (U_FAILURE(status)) {
return NULL;
}
VTimeZone *vtz = new VTimeZone();
if (vtz == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
vtz->tz = (BasicTimeZone *)basic_time_zone.clone();
if (vtz->tz == NULL) {
status = U_MEMORY_ALLOCATION_ERROR;
delete vtz;
return NULL;
}
vtz->tz->getID(vtz->olsonzid);
// Set ICU tzdata version
UResourceBundle *bundle = NULL;
const UChar* versionStr = NULL;
int32_t len = 0;
bundle = ures_openDirect(NULL, "zoneinfo64", &status);
versionStr = ures_getStringByKey(bundle, "TZVersion", &len, &status);
if (U_SUCCESS(status)) {
vtz->icutzver.setTo(versionStr, len);
@ -2580,4 +2611,3 @@ U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof

View File

@ -1762,6 +1762,52 @@ TimeZoneRuleTest::TestVTimeZoneCoverage(void) {
errln("FAIL: VTimeZone vtz1 is equal to vtz, but got wrong result");
}
// Creation from BasicTimeZone
//
status = U_ZERO_ERROR;
VTimeZone *vtzFromBasic = NULL;
SimpleTimeZone *simpleTZ = new SimpleTimeZone(28800000, "Asia/Singapore");
simpleTZ->setStartYear(1970);
simpleTZ->setStartRule(0, // month
1, // day of week
0, // time
status);
simpleTZ->setEndRule(1, 1, 0, status);
if (U_FAILURE(status)) {
errln("File %s, line %d, failed with status = %s", __FILE__, __LINE__, u_errorName(status));
goto end_basic_tz_test;
}
vtzFromBasic = VTimeZone::createVTimeZoneFromBasicTimeZone(*simpleTZ, status);
if (U_FAILURE(status) || vtzFromBasic == NULL) {
errln("File %s, line %d, failed with status = %s", __FILE__, __LINE__, u_errorName(status));
goto end_basic_tz_test;
}
// delete the source time zone, to make sure there are no dependencies on it.
delete simpleTZ;
// Create another simple time zone w the same rules, and check that it is the
// same as the test VTimeZone created above.
{
SimpleTimeZone simpleTZ2(28800000, "Asia/Singapore");
simpleTZ2.setStartYear(1970);
simpleTZ2.setStartRule(0, // month
1, // day of week
0, // time
status);
simpleTZ2.setEndRule(1, 1, 0, status);
if (U_FAILURE(status)) {
errln("File %s, line %d, failed with status = %s", __FILE__, __LINE__, u_errorName(status));
goto end_basic_tz_test;
}
if (vtzFromBasic->hasSameRules(simpleTZ2) == FALSE) {
errln("File %s, line %d, failed hasSameRules() ", __FILE__, __LINE__);
goto end_basic_tz_test;
}
}
end_basic_tz_test:
delete vtzFromBasic;
delete otz;
delete vtz;
delete tmpvtz;