]> granicus.if.org Git - icu/commitdiff
ICU-8779 add getUnknown()
authorMarkus Scherer <markus.icu@gmail.com>
Wed, 28 Sep 2011 00:00:31 +0000 (00:00 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Wed, 28 Sep 2011 00:00:31 +0000 (00:00 +0000)
X-SVN-Rev: 30729

icu4c/source/i18n/timezone.cpp
icu4c/source/i18n/unicode/timezone.h
icu4c/source/test/intltest/tztest.cpp
icu4c/source/test/intltest/tztest.h

index 01a86ebf1bda305db7ca9e31712d75ca31b4abd0..c39c71c4099debc0ff611a009846109d8abe2ba0 100644 (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;
 }
index a37014d17be540d2f0fdb2214746a48d9e96104b..12263130d1f689fa00967d3c0c62f52b2150e327 100644 (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);
index d88cfb6ae5843accf005d725e3ce40ee66a669bb..94ca0431e014527b42aca71ccc3cd43cd87642d4 100644 (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 */
index e42ce1fb9f53b95caa82e05939806dd2e15bd71b..f9041f1d16ef79ce43a499a9a800d6865711ff62 100644 (file)
@@ -95,6 +95,7 @@ public:
     virtual void TestDisplayNamesMeta();
 
     void TestGetRegion(void);
+    void TestGetUnknown();
 
     static const UDate INTERVAL;