OLD | NEW |
(Empty) | |
| 1 diff --git a/source/i18n/timezone.cpp b/source/i18n/timezone.cpp |
| 2 index 6ed008d..6b3f8d2 100644 |
| 3 --- a/source/i18n/timezone.cpp |
| 4 +++ b/source/i18n/timezone.cpp |
| 5 @@ -1,6 +1,6 @@ |
| 6 /* |
| 7 ******************************************************************************* |
| 8 -* Copyright (C) 1997-2014, International Business Machines Corporation and |
| 9 +* Copyright (C) 1997-2015, International Business Machines Corporation and |
| 10 * others. All Rights Reserved. |
| 11 ******************************************************************************* |
| 12 * |
| 13 @@ -440,21 +440,9 @@ TimeZone::createTimeZone(const UnicodeString& ID) |
| 14 |
| 15 // ------------------------------------- |
| 16 |
| 17 -/** |
| 18 - * Initialize DEFAULT_ZONE from the system default time zone. |
| 19 - * Upon return, DEFAULT_ZONE will not be NULL, unless operator new() |
| 20 - * returns NULL. |
| 21 - */ |
| 22 -static void U_CALLCONV initDefault() |
| 23 +TimeZone* U_EXPORT2 |
| 24 +TimeZone::detectHostTimeZone() |
| 25 { |
| 26 - ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); |
| 27 - |
| 28 - // If setDefault() has already been called we can skip getting the |
| 29 - // default zone information from the system. |
| 30 - if (DEFAULT_ZONE != NULL) { |
| 31 - return; |
| 32 - } |
| 33 - |
| 34 // We access system timezone data through TPlatformUtilities, |
| 35 // including tzset(), timezone, and tzname[]. |
| 36 int32_t rawOffset = 0; |
| 37 @@ -463,16 +451,6 @@ static void U_CALLCONV initDefault() |
| 38 // First, try to create a system timezone, based |
| 39 // on the string ID in tzname[0]. |
| 40 |
| 41 - // NOTE: this code is safely single threaded, being only |
| 42 - // run via umtx_initOnce(). |
| 43 - // |
| 44 - // Some of the locale/timezone OS functions may not be thread safe, |
| 45 - // |
| 46 - // The operating system might actually use ICU to implement timezones. |
| 47 - // So we may have ICU calling ICU here, like on AIX. |
| 48 - // There shouldn't be a problem with this; initOnce does not hold a mutex |
| 49 - // while the init function is being run. |
| 50 - |
| 51 uprv_tzset(); // Initialize tz... system data |
| 52 |
| 53 // Get the timezone ID from the host. This function should do |
| 54 @@ -484,13 +462,13 @@ static void U_CALLCONV initDefault() |
| 55 // Invert sign because UNIX semantics are backwards |
| 56 rawOffset = uprv_timezone() * -U_MILLIS_PER_SECOND; |
| 57 |
| 58 - TimeZone* default_zone = NULL; |
| 59 + TimeZone* hostZone = NULL; |
| 60 |
| 61 /* Make sure that the string is NULL terminated to prevent BoundsChecker/Pu
rify warnings. */ |
| 62 UnicodeString hostStrID(hostID, -1, US_INV); |
| 63 hostStrID.append((UChar)0); |
| 64 hostStrID.truncate(hostStrID.length()-1); |
| 65 - default_zone = createSystemTimeZone(hostStrID); |
| 66 + hostZone = createSystemTimeZone(hostStrID); |
| 67 |
| 68 #if U_PLATFORM_USES_ONLY_WIN32_API |
| 69 // hostID points to a heap-allocated location on Windows. |
| 70 @@ -498,30 +476,69 @@ static void U_CALLCONV initDefault() |
| 71 #endif |
| 72 |
| 73 int32_t hostIDLen = hostStrID.length(); |
| 74 - if (default_zone != NULL && rawOffset != default_zone->getRawOffset() |
| 75 + if (hostZone != NULL && rawOffset != hostZone->getRawOffset() |
| 76 && (3 <= hostIDLen && hostIDLen <= 4)) |
| 77 { |
| 78 // Uh oh. This probably wasn't a good id. |
| 79 // It was probably an ambiguous abbreviation |
| 80 - delete default_zone; |
| 81 - default_zone = NULL; |
| 82 + delete hostZone; |
| 83 + hostZone = NULL; |
| 84 } |
| 85 |
| 86 // Construct a fixed standard zone with the host's ID |
| 87 // and raw offset. |
| 88 - if (default_zone == NULL) { |
| 89 - default_zone = new SimpleTimeZone(rawOffset, hostStrID); |
| 90 + if (hostZone == NULL) { |
| 91 + hostZone = new SimpleTimeZone(rawOffset, hostStrID); |
| 92 } |
| 93 |
| 94 // If we _still_ don't have a time zone, use GMT. |
| 95 - if (default_zone == NULL) { |
| 96 + // |
| 97 + // Note: This is extremely unlikely situation. If |
| 98 + // new SimpleTimeZone(...) above fails, the following |
| 99 + // code may also fail. |
| 100 + if (hostZone == NULL) { |
| 101 const TimeZone* temptz = TimeZone::getGMT(); |
| 102 // If we can't use GMT, get out. |
| 103 if (temptz == NULL) { |
| 104 - return; |
| 105 + return NULL; |
| 106 } |
| 107 - default_zone = temptz->clone(); |
| 108 + hostZone = temptz->clone(); |
| 109 + } |
| 110 + |
| 111 + return hostZone; |
| 112 +} |
| 113 + |
| 114 +// ------------------------------------- |
| 115 + |
| 116 +/** |
| 117 + * Initialize DEFAULT_ZONE from the system default time zone. |
| 118 + * Upon return, DEFAULT_ZONE will not be NULL, unless operator new() |
| 119 + * returns NULL. |
| 120 + */ |
| 121 +static void U_CALLCONV initDefault() |
| 122 +{ |
| 123 + ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); |
| 124 + |
| 125 + // If setDefault() has already been called we can skip getting the |
| 126 + // default zone information from the system. |
| 127 + if (DEFAULT_ZONE != NULL) { |
| 128 + return; |
| 129 } |
| 130 + |
| 131 + // NOTE: this code is safely single threaded, being only |
| 132 + // run via umtx_initOnce(). |
| 133 + // |
| 134 + // Some of the locale/timezone OS functions may not be thread safe, |
| 135 + // |
| 136 + // The operating system might actually use ICU to implement timezones. |
| 137 + // So we may have ICU calling ICU here, like on AIX. |
| 138 + // There shouldn't be a problem with this; initOnce does not hold a mutex |
| 139 + // while the init function is being run. |
| 140 + |
| 141 + // The code detecting the host time zone was separated from this |
| 142 + // and implemented as TimeZone::detectHostTimeZone() |
| 143 + |
| 144 + TimeZone *default_zone = TimeZone::detectHostTimeZone(); |
| 145 |
| 146 // The only way for DEFAULT_ZONE to be non-null at this point is if the use
r |
| 147 // made a thread-unsafe call to setDefault() or adoptDefault() in another |
| 148 diff --git a/source/i18n/unicode/timezone.h b/source/i18n/unicode/timezone.h |
| 149 index fa4f5bf..c3356c9 100644 |
| 150 --- a/source/i18n/unicode/timezone.h |
| 151 +++ b/source/i18n/unicode/timezone.h |
| 152 @@ -1,5 +1,5 @@ |
| 153 /************************************************************************* |
| 154 -* Copyright (c) 1997-2014, International Business Machines Corporation |
| 155 +* Copyright (c) 1997-2015, International Business Machines Corporation |
| 156 * and others. All Rights Reserved. |
| 157 ************************************************************************** |
| 158 * |
| 159 @@ -273,6 +273,23 @@ public: |
| 160 static const UnicodeString U_EXPORT2 getEquivalentID(const UnicodeString& i
d, |
| 161 int32_t index); |
| 162 |
| 163 +#ifndef U_HIDE_DRAFT_API |
| 164 + /** |
| 165 + * Creates an instance of TimeZone detected from the current host |
| 166 + * system configuration. Note that ICU4C does not change the default |
| 167 + * time zone unless TimeZone::adoptDefault(TimeZone*) or |
| 168 + * TimeZone::setDefault(const TimeZone&) is explicitly called by a |
| 169 + * user. This method does not update the current ICU's default, |
| 170 + * and may return a different TimeZone from the one returned by |
| 171 + * TimeZone::createDefault(). |
| 172 + * |
| 173 + * @return A new instance of TimeZone detected from the current host syste
m |
| 174 + * configuration. |
| 175 + * @draft ICU 55 |
| 176 + */ |
| 177 + static TimeZone* U_EXPORT2 detectHostTimeZone(); |
| 178 +#endif |
| 179 + |
| 180 /** |
| 181 * Creates a new copy of the default TimeZone for this host. Unless the def
ault time |
| 182 * zone has already been set using adoptDefault() or setDefault(), the defa
ult is |
| 183 diff --git a/source/test/intltest/tztest.cpp b/source/test/intltest/tztest.cpp |
| 184 index 4111e51..76304e9 100644 |
| 185 --- a/source/test/intltest/tztest.cpp |
| 186 +++ b/source/test/intltest/tztest.cpp |
| 187 @@ -135,6 +135,13 @@ TimeZoneTest::TestGenericAPI() |
| 188 infoln("WARNING: t_timezone may be incorrect. It is not a multiple of 1
5min.", tzoffset); |
| 189 } |
| 190 |
| 191 + TimeZone* hostZone = TimeZone::detectHostTimeZone(); |
| 192 + /* Host time zone's offset should match the offset returned by uprv_timezon
e() */ |
| 193 + if (hostZone->getRawOffset() != tzoffset * (-1000)) { |
| 194 + errln("FAIL: detectHostTimeZone()'s raw offset != host timezone's offse
t"); |
| 195 + } |
| 196 + delete hostZone; |
| 197 + |
| 198 UErrorCode status = U_ZERO_ERROR; |
| 199 const char* tzver = TimeZone::getTZDataVersion(status); |
| 200 if (U_FAILURE(status)) { |
OLD | NEW |