ICU-8779 add getUnknown()

X-SVN-Rev: 30729
This commit is contained in:
Markus Scherer 2011-09-28 00:00:31 +00:00
parent 077d3a16e0
commit 3458799ca4
4 changed files with 90 additions and 34 deletions

View file

@ -119,7 +119,8 @@ static const int32_t UNKNOWN_ZONE_ID_LENGTH = 11;
static UMTX LOCK;
static UMTX TZSET_LOCK;
static icu::TimeZone* DEFAULT_ZONE = NULL;
static icu::TimeZone* _GMT = NULL; // cf. TimeZone::GMT
static icu::TimeZone* _GMT = NULL;
static icu::TimeZone* _UNKNOWN_ZONE = NULL;
static char TZDATA_VERSION[16];
static UBool TZDataVersionInitialized = FALSE;
@ -141,6 +142,9 @@ static UBool U_CALLCONV timeZone_cleanup(void)
delete _GMT;
_GMT = NULL;
delete _UNKNOWN_ZONE;
_UNKNOWN_ZONE = NULL;
uprv_memset(TZDATA_VERSION, 0, sizeof(TZDATA_VERSION));
TZDataVersionInitialized = FALSE;
@ -297,25 +301,48 @@ static UResourceBundle* openOlsonResource(const UnicodeString& id,
// -------------------------------------
const TimeZone* U_EXPORT2
TimeZone::getGMT(void)
{
namespace {
void
ensureStaticTimeZones() {
UBool needsInit;
UMTX_CHECK(&LOCK, (_GMT == NULL), needsInit); /* This is here to prevent race conditions. */
// Initialize _GMT independently of other static data; it should
// be valid even if we can't load the time zone UDataMemory.
if (needsInit) {
SimpleTimeZone *tmpUnknown =
new SimpleTimeZone(0, UnicodeString(TRUE, UNKNOWN_ZONE_ID, UNKNOWN_ZONE_ID_LENGTH));
SimpleTimeZone *tmpGMT = new SimpleTimeZone(0, UnicodeString(TRUE, GMT_ID, GMT_ID_LENGTH));
umtx_lock(&LOCK);
if (_UNKNOWN_ZONE == 0) {
_UNKNOWN_ZONE = tmpUnknown;
tmpUnknown = NULL;
}
if (_GMT == 0) {
_GMT = tmpGMT;
tmpGMT = NULL;
}
umtx_unlock(&LOCK);
ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
delete tmpUnknown;
delete tmpGMT;
}
}
} // anonymous namespace
const TimeZone& U_EXPORT2
TimeZone::getUnknown()
{
ensureStaticTimeZones();
return *_UNKNOWN_ZONE;
}
const TimeZone* U_EXPORT2
TimeZone::getGMT(void)
{
ensureStaticTimeZones();
return _GMT;
}
@ -389,7 +416,7 @@ TimeZone::createTimeZone(const UnicodeString& ID)
}
if (result == 0) {
U_DEBUG_TZ_MSG(("failed to load time zone with id - falling to Etc/Unknown(GMT)"));
result = new SimpleTimeZone(0, UnicodeString(TRUE, UNKNOWN_ZONE_ID, UNKNOWN_ZONE_ID_LENGTH));
result = getUnknown().clone();
}
return result;
}

View file

@ -128,14 +128,29 @@ public:
virtual ~TimeZone();
/**
* The GMT time zone has a raw offset of zero and does not use daylight
* Returns the "unknown" time zone.
* It behaves like the GMT/UTC time zone but has the
* <code>UCAL_UNKNOWN_ZONE_ID</code> = "Etc/Unknown".
* createTimeZone() returns a mutable clone of this time zone if the input ID is not recognized.
*
* @return the "unknown" time zone.
* @see UCAL_UNKNOWN_ZONE_ID
* @see createTimeZone
* @see getGMT
* @draft ICU 49
*/
static const TimeZone& U_EXPORT2 getUnknown();
/**
* The GMT (=UTC) time zone has a raw offset of zero and does not use daylight
* savings time. This is a commonly used time zone.
*
* <p>Note: For backward compatibility reason, the ID used by the time
* zone returned by this method is "GMT", although the ICU's canonical
* ID for the GMT time zone is "Etc/GMT".
*
* @return the GMT time zone.
* @return the GMT/UTC time zone.
* @see getUnknown
* @stable ICU 2.0
*/
static const TimeZone* U_EXPORT2 getGMT(void);
@ -144,10 +159,11 @@ public:
* Creates a <code>TimeZone</code> for the given ID.
* @param ID the ID for a <code>TimeZone</code>, such as "America/Los_Angeles",
* or a custom ID such as "GMT-8:00".
* @return the specified <code>TimeZone</code>, or the GMT zone with ID
* <code>UCAL_UNKNOWN_ZONE_ID</code> ("Etc/Unknown") if the given ID cannot be understood.
* Return result guaranteed to be non-null. If you require that the specific zone asked
* for be returned, check the ID of the return result.
* @return the specified <code>TimeZone</code>, or a mutable clone of getUnknown()
* if the given ID cannot be understood.
* The return result is guaranteed to be non-NULL.
* If you require that the specific zone asked for be returned,
* compare the result with getUnknown() or check the ID of the return result.
* @stable ICU 2.0
*/
static TimeZone* U_EXPORT2 createTimeZone(const UnicodeString& ID);

View file

@ -41,30 +41,32 @@ const char * TimeZoneTest::REFERENCE_DATA_VERSION = "2009d";
void TimeZoneTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
if (exec) logln("TestSuite TestTimeZone");
switch (index) {
CASE(0, TestPRTOffset);
CASE(1, TestVariousAPI518);
CASE(2, TestGetAvailableIDs913);
CASE(3, TestGenericAPI);
CASE(4, TestRuleAPI);
CASE(5, TestShortZoneIDs);
CASE(6, TestCustomParse);
CASE(7, TestDisplayName);
CASE(8, TestDSTSavings);
CASE(9, TestAlternateRules);
CASE(10,TestCountries);
CASE(11,TestHistorical);
CASE(12,TestEquivalentIDs);
CASE(13, TestAliasedNames);
CASE(14, TestFractionalDST);
CASE(15, TestFebruary);
CASE(16, TestCanonicalID);
CASE(17, TestDisplayNamesMeta);
CASE(18, TestGetRegion);
CASE(19, TestGetAvailableIDsNew);
default: name = ""; break;
if (exec) {
logln("TestSuite TestTimeZone");
}
TESTCASE_AUTO_BEGIN;
TESTCASE_AUTO(TestPRTOffset);
TESTCASE_AUTO(TestVariousAPI518);
TESTCASE_AUTO(TestGetAvailableIDs913);
TESTCASE_AUTO(TestGenericAPI);
TESTCASE_AUTO(TestRuleAPI);
TESTCASE_AUTO(TestShortZoneIDs);
TESTCASE_AUTO(TestCustomParse);
TESTCASE_AUTO(TestDisplayName);
TESTCASE_AUTO(TestDSTSavings);
TESTCASE_AUTO(TestAlternateRules);
TESTCASE_AUTO(TestCountries);
TESTCASE_AUTO(TestHistorical);
TESTCASE_AUTO(TestEquivalentIDs);
TESTCASE_AUTO(TestAliasedNames);
TESTCASE_AUTO(TestFractionalDST);
TESTCASE_AUTO(TestFebruary);
TESTCASE_AUTO(TestCanonicalID);
TESTCASE_AUTO(TestDisplayNamesMeta);
TESTCASE_AUTO(TestGetRegion);
TESTCASE_AUTO(TestGetAvailableIDsNew);
TESTCASE_AUTO(TestGetUnknown);
TESTCASE_AUTO_END;
}
const int32_t TimeZoneTest::millisPerHour = 3600000;
@ -2307,4 +2309,14 @@ void TimeZoneTest::TestGetRegion()
}
}
}
void TimeZoneTest::TestGetUnknown() {
const TimeZone &unknown = TimeZone::getUnknown();
UnicodeString expectedID = UNICODE_STRING_SIMPLE("Etc/Unknown");
UnicodeString id;
assertEquals("getUnknown() wrong ID", expectedID, unknown.getID(id));
assertTrue("getUnknown() wrong offset", 0 == unknown.getRawOffset());
assertFalse("getUnknown() uses DST", unknown.useDaylightTime());
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -95,6 +95,7 @@ public:
virtual void TestDisplayNamesMeta();
void TestGetRegion(void);
void TestGetUnknown();
static const UDate INTERVAL;