]> granicus.if.org Git - icu/commitdiff
ICU-20759 Add ucal_getDefaultTimeZone C API for host OS timezone detection.
authorJeff Genovy <29107334+jefgen@users.noreply.github.com>
Fri, 14 Jun 2019 08:07:40 +0000 (01:07 -0700)
committerJeff Genovy <29107334+jefgen@users.noreply.github.com>
Thu, 15 Aug 2019 01:27:04 +0000 (18:27 -0700)
icu4c/source/i18n/ucal.cpp
icu4c/source/i18n/unicode/ucal.h
icu4c/source/test/cintltst/ccaltst.c

index e8f6d2e96f898a4033d9eb99b6d44bef2fcc590b..927b2d369791bd49778d7f6c66201f9b9c0e5b2b 100644 (file)
@@ -34,7 +34,7 @@ U_NAMESPACE_USE
 static TimeZone*
 _createTimeZone(const UChar* zoneID, int32_t len, UErrorCode* ec) {
     TimeZone* zone = NULL;
-    if (ec!=NULL && U_SUCCESS(*ec)) {
+    if (ec != NULL && U_SUCCESS(*ec)) {
         // Note that if zoneID is invalid, we get back GMT. This odd
         // behavior is by design and goes back to the JDK. The only
         // failure we will see is a memory allocation failure.
@@ -69,7 +69,7 @@ ucal_openCountryTimeZones(const char* country, UErrorCode* ec) {
 U_CAPI int32_t U_EXPORT2
 ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) {
     int32_t len = 0;
-    if (ec!=NULL && U_SUCCESS(*ec)) {
+    if (ec != NULL && U_SUCCESS(*ec)) {
         TimeZone* zone = TimeZone::createDefault();
         if (zone == NULL) {
             *ec = U_MEMORY_ALLOCATION_ERROR;
@@ -91,6 +91,23 @@ ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec) {
     }
 }
 
+U_DRAFT int32_t U_EXPORT2
+ucal_getHostTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) {
+    int32_t len = 0;
+    if (ec != NULL && U_SUCCESS(*ec)) {
+        TimeZone *zone = TimeZone::detectHostTimeZone();
+        if (zone == NULL) {
+            *ec = U_MEMORY_ALLOCATION_ERROR;
+        } else {
+            UnicodeString id;
+            zone->getID(id);
+            delete zone;
+            len = id.extract(result, resultCapacity, *ec);
+        }
+    }
+    return len;
+}
+
 U_CAPI int32_t U_EXPORT2
 ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) {
     int32_t result = 0;
index f31a25732dcfc6fa2dc52f9b7573497caf685dea..4466223bf0fc7f231658e40fc2a6bc8a981c0f3e 100644 (file)
@@ -657,6 +657,42 @@ ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec);
 U_STABLE void U_EXPORT2
 ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec);
 
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Return the current host time zone. The host time zone is detected from
+ * the current host system configuration by querying the host operating
+ * system. If the host system detection routines fail, or if they specify
+ * a TimeZone or TimeZone offset which is not recognized, then the special
+ * TimeZone "Etc/Unknown" is returned.
+ * 
+ * Note that host time zone and the ICU default time zone can be different.
+ * 
+ * The ICU default time zone does not change once initialized unless modified
+ * by calling `ucal_setDefaultTimeZone()` or with the C++ TimeZone API,
+ * `TimeZone::adoptDefault(TimeZone*)`.
+ * 
+ * If the host operating system configuration has changed since ICU has
+ * initialized then the returned value can be different than the ICU default
+ * time zone, even if the default has not changed.
+ *
+ * <p>This function is not thread safe.</p>
+ * 
+ * @param result A buffer to receive the result, or NULL
+ * @param resultCapacity The capacity of the result buffer
+ * @param ec input/output error code
+ * @return The result string length, not including the terminating
+ * null
+ * 
+ * @see #UCAL_UNKNOWN_ZONE_ID
+ * 
+ * @draft ICU 65
+ */
+U_DRAFT int32_t U_EXPORT2
+ucal_getHostTimeZone(UChar *result, int32_t resultCapacity, UErrorCode *ec);
+
+#endif // U_HIDE_DRAFT_API
+
 /**
  * Return the amount of time in milliseconds that the clock is
  * advanced during daylight savings time for the given time zone, or
index 2ce054690d8a122c940cbaefb5452bb54169028f..eaff8f3cd2332c04a39cc0798815565d2ec70256 100644 (file)
@@ -228,7 +228,7 @@ static void TestCalendar()
         log_err("FAIL: ucal_getDSTSavings(PST) => %d, expect %d\n", i, 1*60*60*1000);
     }
 
-    /*Test ucal_set/getDefaultTimeZone*/
+    /*Test ucal_set/getDefaultTimeZone and ucal_getHostTimeZone */
     status = U_ZERO_ERROR;
     i = ucal_getDefaultTimeZone(zone1, UPRV_LENGTHOF(zone1), &status);
     if (U_FAILURE(status)) {
@@ -247,6 +247,16 @@ static void TestCalendar()
             } else {
                 if (u_strcmp(zone2, EUROPE_PARIS) != 0) {
                     log_data_err("FAIL: ucal_getDefaultTimeZone() did not return Europe/Paris (Are you missing data?)\n");
+                } else {
+                    // Redetect the host timezone, it should be the same as zone1 even though ICU's default timezone has been changed.
+                    i = ucal_getHostTimeZone(zone2, UPRV_LENGTHOF(zone2), &status);
+                    if (U_FAILURE(status)) {
+                        log_err("FAIL: ucal_getHostTimeZone() => %s\n", u_errorName(status));
+                    } else {
+                        if (u_strcmp(zone1, zone2) != 0) {
+                            log_err("FAIL: ucal_getHostTimeZone() should give the same host timezone even if the default changed.\n");
+                        }
+                    }
                 }
             }
         }