OLD | NEW |
| 1 diff --git a/source/common/putil.cpp b/source/common/putil.cpp |
| 2 index 5f09288..c87b60e 100644 |
| 3 --- a/source/common/putil.cpp |
| 4 +++ b/source/common/putil.cpp |
| 5 @@ -970,6 +970,15 @@ static char* searchForTZFile(const char* path, DefaultTZInf
o* tzInfo) { |
| 6 return result; |
| 7 } |
| 8 #endif |
| 9 + |
| 10 +U_CAPI void U_EXPORT2 |
| 11 +uprv_tzname_clear_cache() |
| 12 +{ |
| 13 +#if defined(CHECK_LOCALTIME_LINK) && !defined(DEBUG_SKIP_LOCALTIME_LINK) |
| 14 + gTimeZoneBufferPtr = NULL; |
| 15 +#endif |
| 16 +} |
| 17 + |
| 18 U_CAPI const char* U_EXPORT2 |
| 19 uprv_tzname(int n) |
| 20 { |
| 21 diff --git a/source/common/putilimp.h b/source/common/putilimp.h |
| 22 index 5de801f..55ec0ae 100644 |
| 23 --- a/source/common/putilimp.h |
| 24 +++ b/source/common/putilimp.h |
| 25 @@ -479,6 +479,12 @@ U_INTERNAL int32_t U_EXPORT2 uprv_timezone(void); |
| 26 U_INTERNAL const char* U_EXPORT2 uprv_tzname(int n); |
| 27 |
| 28 /** |
| 29 + * Reset the global tzname cache. |
| 30 + * @internal |
| 31 + */ |
| 32 +U_INTERNAL void uprv_tzname_clear_cache(); |
| 33 + |
| 34 +/** |
| 35 * Get UTC (GMT) time measured in milliseconds since 0:00 on 1/1/1970. |
| 36 * This function is affected by 'faketime' and should be the bottleneck for all
user-visible ICU time functions. |
| 37 * @return the UTC time measured in milliseconds |
1 diff --git a/source/i18n/timezone.cpp b/source/i18n/timezone.cpp | 38 diff --git a/source/i18n/timezone.cpp b/source/i18n/timezone.cpp |
2 index 6ed008d..6b3f8d2 100644 | 39 index 59c3891..00eca38 100644 |
3 --- a/source/i18n/timezone.cpp | 40 --- a/source/i18n/timezone.cpp |
4 +++ b/source/i18n/timezone.cpp | 41 +++ b/source/i18n/timezone.cpp |
5 @@ -1,6 +1,6 @@ | 42 @@ -458,6 +458,8 @@ TimeZone::detectHostTimeZone() |
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 | 43 |
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 | 44 uprv_tzset(); // Initialize tz... system data |
52 | 45 |
| 46 + uprv_tzname_clear_cache(); |
| 47 + |
53 // Get the timezone ID from the host. This function should do | 48 // Get the timezone ID from the host. This function should do |
54 @@ -484,13 +462,13 @@ static void U_CALLCONV initDefault() | 49 // any required host-specific remapping; e.g., on Windows this |
55 // Invert sign because UNIX semantics are backwards | 50 // function maps the Date and Time control panel setting to an |
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 |