]> git.saurik.com Git - apple/cf.git/blob - NumberDate.subproj/CFTimeZone.c
CF-368.tar.gz
[apple/cf.git] / NumberDate.subproj / CFTimeZone.c
1 /*
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /* CFTimeZone.c
24 Copyright 1998-2002, Apple, Inc. All rights reserved.
25 Responsibility: Christopher Kane
26 */
27
28 #include <CoreFoundation/CFTimeZone.h>
29 #include <CoreFoundation/CFPropertyList.h>
30 #include "CFUtilitiesPriv.h"
31 #include "CFInternal.h"
32 #include <math.h>
33 #include <limits.h>
34 #include <sys/stat.h>
35 #if !defined(__WIN32__)
36 #include <dirent.h>
37 #else
38 #include <windows.h>
39 #include <winreg.h>
40 #include <tchar.h>
41 #include <time.h>
42 #endif
43 #include <fcntl.h>
44 #include <stdlib.h>
45 #include <string.h>
46
47 #if defined(__WIN32__)
48 #include <io.h>
49 #endif
50
51 // For Windows(TM) time zone information, see registry key:
52 // HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Time Zones
53
54 #if defined(__WIN32__)
55 #define TZZONEINFO "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"
56 #else
57 #define TZZONELINK "/etc/localtime"
58 #define TZZONEINFO "/usr/share/zoneinfo/"
59 #endif
60
61 static CFTimeZoneRef __CFTimeZoneSystem = NULL;
62 static CFTimeZoneRef __CFTimeZoneDefault = NULL;
63 static CFDictionaryRef __CFTimeZoneAbbreviationDict = NULL;
64 static CFSpinLock_t __CFTimeZoneAbbreviationLock = 0;
65 static CFMutableDictionaryRef __CFTimeZoneCompatibilityMappingDict = NULL;
66 static CFMutableDictionaryRef __CFTimeZoneCompatibilityMappingDict2 = NULL;
67 static CFSpinLock_t __CFTimeZoneCompatibilityMappingLock = 0;
68 static CFArrayRef __CFKnownTimeZoneList = NULL;
69 static CFMutableDictionaryRef __CFTimeZoneCache = NULL;
70 static CFSpinLock_t __CFTimeZoneGlobalLock = 0;
71
72 CF_INLINE void __CFTimeZoneLockGlobal(void) {
73 __CFSpinLock(&__CFTimeZoneGlobalLock);
74 }
75
76 CF_INLINE void __CFTimeZoneUnlockGlobal(void) {
77 __CFSpinUnlock(&__CFTimeZoneGlobalLock);
78 }
79
80 CF_INLINE void __CFTimeZoneLockAbbreviations(void) {
81 __CFSpinLock(&__CFTimeZoneAbbreviationLock);
82 }
83
84 CF_INLINE void __CFTimeZoneUnlockAbbreviations(void) {
85 __CFSpinUnlock(&__CFTimeZoneAbbreviationLock);
86 }
87
88 CF_INLINE void __CFTimeZoneLockCompatibilityMapping(void) {
89 __CFSpinLock(&__CFTimeZoneCompatibilityMappingLock);
90 }
91
92 CF_INLINE void __CFTimeZoneUnlockCompatibilityMapping(void) {
93 __CFSpinUnlock(&__CFTimeZoneCompatibilityMappingLock);
94 }
95
96 /* This function should be used for WIN32 instead of
97 * __CFCopyRecursiveDirectoryList function.
98 * It takes TimeZone names from the registry
99 * (Aleksey Dukhnyakov)
100 */
101 #if defined(__WIN32__)
102 static CFMutableArrayRef __CFCopyWindowsTimeZoneList() {
103 CFMutableArrayRef result = NULL;
104 HKEY hkResult;
105 TCHAR lpName[MAX_PATH+1];
106 DWORD dwIndex, retCode;
107
108 if (RegOpenKey(HKEY_LOCAL_MACHINE,_T(TZZONEINFO),&hkResult) !=
109 ERROR_SUCCESS )
110 return NULL;
111
112 result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
113
114 for (dwIndex=0; (retCode = RegEnumKey(hkResult,dwIndex,lpName,MAX_PATH)) != ERROR_NO_MORE_ITEMS ; dwIndex++) {
115
116 if (retCode != ERROR_SUCCESS) {
117 RegCloseKey(hkResult);
118 CFRelease(result);
119 return NULL;
120 }
121 else {
122 #if defined(UNICODE)
123 CFStringRef string = CFStringCreateWithBytes(kCFAllocatorDefault, lpName, _tcslen(lpName), kCFStringEncodingUnicode, false);
124 #else
125 CFStringRef string = CFStringCreateWithBytes(kCFAllocatorDefault, lpName, _tcslen(lpName), CFStringGetSystemEncoding(), false);
126 #endif
127 CFArrayAppendValue(result, string);
128 CFRelease(string);
129 }
130 }
131
132 RegCloseKey(hkResult);
133 return result;
134 }
135 #endif
136
137 #if !defined(__WIN32__)
138 static CFMutableArrayRef __CFCopyRecursiveDirectoryList(const char *topDir) {
139 CFMutableArrayRef result = NULL, temp;
140 long fd, numread, plen, basep = 0;
141 CFIndex idx, cnt, usedLen;
142 char *dirge, path[CFMaxPathSize];
143
144 // No d_namlen in dirent struct on Linux
145 #if defined(__LINUX__)
146 #define dentDNameLen strlen(dent->d_name)
147 #else
148 #define dentDNameLen dent->d_namlen
149 #endif
150 fd = open(topDir, O_RDONLY, 0);
151 if (fd < 0) {
152 return NULL;
153 }
154 dirge = malloc(8192);
155 result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
156 numread = getdirentries(fd, dirge, 8192, &basep);
157 while (0 < numread) {
158 struct dirent *dent = (struct dirent *)dirge;
159 for (; dent < (struct dirent *)(dirge + numread); dent = (struct dirent *)((char *)dent + dent->d_reclen)) {
160 if (0 == dent->d_fileno) continue;
161 if (1 == dentDNameLen && '.' == dent->d_name[0]) continue;
162 if (2 == dentDNameLen && '.' == dent->d_name[0] && '.' == dent->d_name[1]) continue;
163 if (dent->d_type == DT_UNKNOWN) {
164 struct stat statbuf;
165 strcpy(path, topDir);
166 strcat(path, "/");
167 plen = strlen(path);
168 memmove(path + plen, dent->d_name, dentDNameLen);
169 path[plen + dentDNameLen] = '\0';
170 if (0 <= stat(path, &statbuf) && (statbuf.st_mode & S_IFMT) == S_IFDIR) {
171 dent->d_type = DT_DIR;
172 }
173 }
174 if (DT_DIR == dent->d_type) {
175 strcpy(path, topDir);
176 strcat(path, "/");
177 plen = strlen(path);
178 memmove(path + plen, dent->d_name, dentDNameLen);
179 path[plen + dentDNameLen] = '\0';
180 temp = __CFCopyRecursiveDirectoryList(path);
181 for (idx = 0, cnt = CFArrayGetCount(temp); idx < cnt; idx++) {
182 CFStringRef string, item = CFArrayGetValueAtIndex(temp, idx);
183 memmove(path, dent->d_name, dentDNameLen);
184 path[dentDNameLen] = '/';
185 CFStringGetBytes(item, CFRangeMake(0, CFStringGetLength(item)), kCFStringEncodingUTF8, 0, false, path + dentDNameLen + 1, CFMaxPathLength - dentDNameLen - 2, &usedLen);
186 string = CFStringCreateWithBytes(kCFAllocatorDefault, path, dentDNameLen + 1 + usedLen, kCFStringEncodingUTF8, false);
187 CFArrayAppendValue(result, string);
188 CFRelease(string);
189 }
190 CFRelease(temp);
191 } else {
192 CFStringRef string = CFStringCreateWithBytes(kCFAllocatorDefault, dent->d_name, dentDNameLen, kCFStringEncodingUTF8, false);
193 CFArrayAppendValue(result, string);
194 CFRelease(string);
195 }
196 }
197 numread = getdirentries(fd, dirge, 8192, &basep);
198 }
199 close(fd);
200 free(dirge);
201 if (-1 == numread) {
202 CFRelease(result);
203 return NULL;
204 }
205 return result;
206 }
207 #endif
208
209 typedef struct _CFTZPeriod {
210 int32_t startSec;
211 CFStringRef abbrev;
212 uint32_t info;
213 } CFTZPeriod;
214
215 struct __CFTimeZone {
216 CFRuntimeBase _base;
217 CFStringRef _name; /* immutable */
218 CFDataRef _data; /* immutable */
219 CFTZPeriod *_periods; /* immutable */
220 int32_t _periodCnt; /* immutable */
221 };
222
223 /* startSec is the whole integer seconds from a CFAbsoluteTime, giving dates
224 * between 1933 and 2069; info outside these years is discarded on read-in */
225 /* Bits 31-18 of the info are unused */
226 /* Bit 17 of the info is used for the is-DST state */
227 /* Bit 16 of the info is used for the sign of the offset (1 == negative) */
228 /* Bits 15-0 of the info are used for abs(offset) in seconds from GMT */
229
230 CF_INLINE void __CFTZPeriodInit(CFTZPeriod *period, int32_t startTime, CFStringRef abbrev, int32_t offset, Boolean isDST) {
231 period->startSec = startTime;
232 period->abbrev = abbrev ? CFRetain(abbrev) : NULL;
233 __CFBitfieldSetValue(period->info, 15, 0, abs(offset));
234 __CFBitfieldSetValue(period->info, 16, 16, (offset < 0 ? 1 : 0));
235 __CFBitfieldSetValue(period->info, 17, 17, (isDST ? 1 : 0));
236 }
237
238 CF_INLINE int32_t __CFTZPeriodStartSeconds(const CFTZPeriod *period) {
239 return period->startSec;
240 }
241
242 CF_INLINE CFStringRef __CFTZPeriodAbbreviation(const CFTZPeriod *period) {
243 return period->abbrev;
244 }
245
246 CF_INLINE int32_t __CFTZPeriodGMTOffset(const CFTZPeriod *period) {
247 int32_t v = __CFBitfieldGetValue(period->info, 15, 0);
248 if (__CFBitfieldGetValue(period->info, 16, 16)) v = -v;
249 return v;
250 }
251
252 CF_INLINE Boolean __CFTZPeriodIsDST(const CFTZPeriod *period) {
253 return (Boolean)__CFBitfieldGetValue(period->info, 17, 17);
254 }
255
256 static CFComparisonResult __CFCompareTZPeriods(const void *val1, const void *val2, void *context) {
257 CFTZPeriod *tzp1 = (CFTZPeriod *)val1;
258 CFTZPeriod *tzp2 = (CFTZPeriod *)val2;
259 // we treat equal as less than, as the code which uses the
260 // result of the bsearch doesn't expect exact matches
261 // (they're pretty rare, so no point in over-coding for them)
262 if (__CFTZPeriodStartSeconds(tzp1) <= __CFTZPeriodStartSeconds(tzp2)) return kCFCompareLessThan;
263 return kCFCompareGreaterThan;
264 }
265
266 static CFIndex __CFBSearchTZPeriods(CFTimeZoneRef tz, CFAbsoluteTime at) {
267 CFTZPeriod elem;
268 CFIndex idx;
269 __CFTZPeriodInit(&elem, (int32_t)(float)floor(at), NULL, 0, false);
270 idx = CFBSearch(&elem, sizeof(CFTZPeriod), tz->_periods, tz->_periodCnt, __CFCompareTZPeriods, NULL);
271 if (tz->_periodCnt <= idx) {
272 idx = tz->_periodCnt;
273 } else if (0 == idx) {
274 // We want anything before the time zone records start to be not in DST;
275 // we assume that if period[0] is DST, then period[1] is not; could do a search instead.
276 idx = __CFTZPeriodIsDST(&(tz->_periods[0])) ? 2 : 1;
277 }
278 return idx - 1;
279 }
280
281 /*
282 ** Each time zone data file begins with. . .
283 */
284
285 struct tzhead {
286 char tzh_reserved[20]; /* reserved for future use */
287 char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
288 char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
289 char tzh_leapcnt[4]; /* coded number of leap seconds */
290 char tzh_timecnt[4]; /* coded number of transition times */
291 char tzh_typecnt[4]; /* coded number of local time types */
292 char tzh_charcnt[4]; /* coded number of abbr. chars */
293 };
294
295 /*
296 ** . . .followed by. . .
297 **
298 ** tzh_timecnt (char [4])s coded transition times a la time(2)
299 ** tzh_timecnt (UInt8)s types of local time starting at above
300 ** tzh_typecnt repetitions of
301 ** one (char [4]) coded GMT offset in seconds
302 ** one (UInt8) used to set tm_isdst
303 ** one (UInt8) that's an abbreviation list index
304 ** tzh_charcnt (char)s '\0'-terminated zone abbreviations
305 ** tzh_leapcnt repetitions of
306 ** one (char [4]) coded leap second transition times
307 ** one (char [4]) total correction after above
308 ** tzh_ttisstdcnt (char)s indexed by type; if 1, transition
309 ** time is standard time, if 0,
310 ** transition time is wall clock time
311 ** if absent, transition times are
312 ** assumed to be wall clock time
313 ** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition
314 ** time is GMT, if 0,
315 ** transition time is local time
316 ** if absent, transition times are
317 ** assumed to be local time
318 */
319
320 CF_INLINE int32_t __CFDetzcode(const unsigned char *bufp) {
321 int32_t result = (bufp[0] & 0x80) ? ~0L : 0L;
322 result = (result << 8) | (bufp[0] & 0xff);
323 result = (result << 8) | (bufp[1] & 0xff);
324 result = (result << 8) | (bufp[2] & 0xff);
325 result = (result << 8) | (bufp[3] & 0xff);
326 return result;
327 }
328
329 CF_INLINE void __CFEntzcode(int32_t value, unsigned char *bufp) {
330 bufp[0] = (value >> 24) & 0xff;
331 bufp[1] = (value >> 16) & 0xff;
332 bufp[2] = (value >> 8) & 0xff;
333 bufp[3] = (value >> 0) & 0xff;
334 }
335
336 static Boolean __CFParseTimeZoneData(CFAllocatorRef allocator, CFDataRef data, CFTZPeriod **tzpp, CFIndex *cntp) {
337 #if !defined(__WIN32__)
338 int32_t len, timecnt, typecnt, charcnt, idx, cnt;
339 const char *p, *timep, *typep, *ttisp, *charp;
340 CFStringRef *abbrs;
341 Boolean result = true;
342
343 p = CFDataGetBytePtr(data);
344 len = CFDataGetLength(data);
345 if (len < (int32_t)sizeof(struct tzhead)) {
346 return false;
347 }
348 p += 20 + 4 + 4 + 4; /* skip reserved, ttisgmtcnt, ttisstdcnt, leapcnt */
349 timecnt = __CFDetzcode(p);
350 p += 4;
351 typecnt = __CFDetzcode(p);
352 p += 4;
353 charcnt = __CFDetzcode(p);
354 p += 4;
355 if (typecnt <= 0 || timecnt < 0 || charcnt < 0) {
356 return false;
357 }
358 if (len - (int32_t)sizeof(struct tzhead) < (4 + 1) * timecnt + (4 + 1 + 1) * typecnt + charcnt) {
359 return false;
360 }
361 timep = p;
362 typep = timep + 4 * timecnt;
363 ttisp = typep + timecnt;
364 charp = ttisp + (4 + 1 + 1) * typecnt;
365 cnt = (0 < timecnt) ? timecnt : 1;
366 *tzpp = CFAllocatorAllocate(allocator, cnt * sizeof(CFTZPeriod), 0);
367 if (__CFOASafe) __CFSetLastAllocationEventName(*tzpp, "CFTimeZone (store)");
368 memset(*tzpp, 0, cnt * sizeof(CFTZPeriod));
369 abbrs = CFAllocatorAllocate(allocator, (charcnt + 1) * sizeof(CFStringRef), 0);
370 if (__CFOASafe) __CFSetLastAllocationEventName(abbrs, "CFTimeZone (temp)");
371 for (idx = 0; idx < charcnt + 1; idx++) {
372 abbrs[idx] = NULL;
373 }
374 for (idx = 0; idx < cnt; idx++) {
375 CFAbsoluteTime at;
376 int32_t itime, offset;
377 uint8_t type, dst, abbridx;
378
379 at = (CFAbsoluteTime)(__CFDetzcode(timep) + 0.0) - kCFAbsoluteTimeIntervalSince1970;
380 if (0 == timecnt) itime = INT_MIN;
381 else if (at < (CFAbsoluteTime)INT_MIN) itime = INT_MIN;
382 else if ((CFAbsoluteTime)INT_MAX < at) itime = INT_MAX;
383 else itime = (int32_t)at;
384 timep += 4; /* harmless if 0 == timecnt */
385 type = (0 < timecnt) ? (uint8_t)*typep++ : 0;
386 if (typecnt <= type) {
387 result = false;
388 break;
389 }
390 offset = __CFDetzcode(ttisp + 6 * type);
391 dst = (uint8_t)*(ttisp + 6 * type + 4);
392 if (0 != dst && 1 != dst) {
393 result = false;
394 break;
395 }
396 abbridx = (uint8_t)*(ttisp + 6 * type + 5);
397 if (charcnt < abbridx) {
398 result = false;
399 break;
400 }
401 if (NULL == abbrs[abbridx]) {
402 abbrs[abbridx] = CFStringCreateWithCString(allocator, &charp[abbridx], kCFStringEncodingASCII);
403 }
404 __CFTZPeriodInit(*tzpp + idx, itime, abbrs[abbridx], offset, (dst ? true : false));
405 }
406 for (idx = 0; idx < charcnt + 1; idx++) {
407 if (NULL != abbrs[idx]) {
408 CFRelease(abbrs[idx]);
409 }
410 }
411 CFAllocatorDeallocate(allocator, abbrs);
412 if (result) {
413 // dump all but the last INT_MIN and the first INT_MAX
414 for (idx = 0; idx < cnt; idx++) {
415 if (((*tzpp + idx)->startSec == INT_MIN) && (idx + 1 < cnt) && (((*tzpp + idx + 1)->startSec == INT_MIN))) {
416 if (NULL != (*tzpp + idx)->abbrev) CFRelease((*tzpp + idx)->abbrev);
417 cnt--;
418 memmove((*tzpp + idx), (*tzpp + idx + 1), sizeof(CFTZPeriod) * (cnt - idx));
419 idx--;
420 }
421 }
422 // Don't combine these loops! Watch the idx decrementing...
423 for (idx = 0; idx < cnt; idx++) {
424 if (((*tzpp + idx)->startSec == INT_MAX) && (0 < idx) && (((*tzpp + idx - 1)->startSec == INT_MAX))) {
425 if (NULL != (*tzpp + idx)->abbrev) CFRelease((*tzpp + idx)->abbrev);
426 cnt--;
427 memmove((*tzpp + idx), (*tzpp + idx + 1), sizeof(CFTZPeriod) * (cnt - idx));
428 idx--;
429 }
430 }
431 CFQSortArray(*tzpp, cnt, sizeof(CFTZPeriod), __CFCompareTZPeriods, NULL);
432 *cntp = cnt;
433 } else {
434 CFAllocatorDeallocate(allocator, *tzpp);
435 *tzpp = NULL;
436 }
437 return result;
438 #else
439 /* We use Win32 function to find TimeZone
440 * (Aleksey Dukhnyakov)
441 */
442 *tzpp = CFAllocatorAllocate(allocator, sizeof(CFTZPeriod), 0);
443 __CFTZPeriodInit(*tzpp, 0, NULL, 0, false);
444 *cntp = 1;
445 return TRUE;
446 #endif
447 }
448
449 static Boolean __CFTimeZoneEqual(CFTypeRef cf1, CFTypeRef cf2) {
450 CFTimeZoneRef tz1 = (CFTimeZoneRef)cf1;
451 CFTimeZoneRef tz2 = (CFTimeZoneRef)cf2;
452 if (!CFEqual(CFTimeZoneGetName(tz1), CFTimeZoneGetName(tz2))) return false;
453 if (!CFEqual(CFTimeZoneGetData(tz1), CFTimeZoneGetData(tz2))) return false;
454 return true;
455 }
456
457 static CFHashCode __CFTimeZoneHash(CFTypeRef cf) {
458 CFTimeZoneRef tz = (CFTimeZoneRef)cf;
459 return CFHash(CFTimeZoneGetName(tz));
460 }
461
462 static CFStringRef __CFTimeZoneCopyDescription(CFTypeRef cf) {
463 CFTimeZoneRef tz = (CFTimeZoneRef)cf;
464 CFStringRef result, abbrev;
465 CFAbsoluteTime at;
466 at = CFAbsoluteTimeGetCurrent();
467 abbrev = CFTimeZoneCopyAbbreviation(tz, at);
468 result = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<CFTimeZone %p [%p]>{name = %@; abbreviation = %@; GMT offset = %g; is DST = %s}"), cf, CFGetAllocator(tz), tz->_name, abbrev, CFTimeZoneGetSecondsFromGMT(tz, at), CFTimeZoneIsDaylightSavingTime(tz, at) ? "true" : "false");
469 CFRelease(abbrev);
470 return result;
471 }
472
473 static void __CFTimeZoneDeallocate(CFTypeRef cf) {
474 CFTimeZoneRef tz = (CFTimeZoneRef)cf;
475 CFAllocatorRef allocator = CFGetAllocator(tz);
476 CFIndex idx;
477 if (tz->_name) CFRelease(tz->_name);
478 if (tz->_data) CFRelease(tz->_data);
479 for (idx = 0; idx < tz->_periodCnt; idx++) {
480 if (NULL != tz->_periods[idx].abbrev) CFRelease(tz->_periods[idx].abbrev);
481 }
482 if (NULL != tz->_periods) CFAllocatorDeallocate(allocator, tz->_periods);
483 }
484
485 static CFTypeID __kCFTimeZoneTypeID = _kCFRuntimeNotATypeID;
486
487 static const CFRuntimeClass __CFTimeZoneClass = {
488 0,
489 "CFTimeZone",
490 NULL, // init
491 NULL, // copy
492 __CFTimeZoneDeallocate,
493 __CFTimeZoneEqual,
494 __CFTimeZoneHash,
495 NULL, //
496 __CFTimeZoneCopyDescription
497 };
498
499 __private_extern__ void __CFTimeZoneInitialize(void) {
500 __kCFTimeZoneTypeID = _CFRuntimeRegisterClass(&__CFTimeZoneClass);
501 }
502
503 CFTypeID CFTimeZoneGetTypeID(void) {
504 return __kCFTimeZoneTypeID;
505 }
506
507 static CFTimeZoneRef __CFTimeZoneCreateSystem(void) {
508 CFTimeZoneRef result = NULL;
509 #if defined(__WIN32__)
510 /* The GetTimeZoneInformation function retrieves the current
511 * time-zone parameters for Win32
512 * (Aleksey Dukhnyakov)
513 */
514 CFDataRef data;
515 TIME_ZONE_INFORMATION tz;
516 DWORD dw_result;
517 dw_result=GetTimeZoneInformation(&tz);
518
519 if ( dw_result == TIME_ZONE_ID_STANDARD ||
520 dw_result == TIME_ZONE_ID_DAYLIGHT ) {
521 CFStringRef name = CFStringCreateWithCharacters(kCFAllocatorDefault, tz.StandardName, wcslen(tz.StandardName));
522 data = CFDataCreate(kCFAllocatorDefault, (UInt8*)&tz, sizeof(tz));
523 result = CFTimeZoneCreate(kCFAllocatorSystemDefault, name, data);
524 CFRelease(name);
525 CFRelease(data);
526 if (result) return result;
527 }
528 #else
529 char *tzenv;
530 int ret;
531 char linkbuf[CFMaxPathSize];
532
533 tzenv = getenv("TZFILE");
534 if (NULL != tzenv) {
535 CFStringRef name = CFStringCreateWithBytes(kCFAllocatorDefault, tzenv, strlen(tzenv), kCFStringEncodingUTF8, false);
536 result = CFTimeZoneCreateWithName(kCFAllocatorSystemDefault, name, false);
537 CFRelease(name);
538 if (result) return result;
539 }
540 tzenv = getenv("TZ");
541 if (NULL != tzenv) {
542 CFStringRef name = CFStringCreateWithBytes(kCFAllocatorDefault, tzenv, strlen(tzenv), kCFStringEncodingUTF8, false);
543 result = CFTimeZoneCreateWithName(kCFAllocatorSystemDefault, name, true);
544 CFRelease(name);
545 if (result) return result;
546 }
547 ret = readlink(TZZONELINK, linkbuf, sizeof(linkbuf));
548 if (0 < ret) {
549 CFStringRef name;
550 linkbuf[ret] = '\0';
551 if (strncmp(linkbuf, TZZONEINFO, sizeof(TZZONEINFO) - 1) == 0) {
552 name = CFStringCreateWithBytes(kCFAllocatorDefault, linkbuf + sizeof(TZZONEINFO) - 1, strlen(linkbuf) - sizeof(TZZONEINFO) + 1, kCFStringEncodingUTF8, false);
553 } else {
554 name = CFStringCreateWithBytes(kCFAllocatorDefault, linkbuf, strlen(linkbuf), kCFStringEncodingUTF8, false);
555 }
556 result = CFTimeZoneCreateWithName(kCFAllocatorSystemDefault, name, false);
557 CFRelease(name);
558 if (result) return result;
559 }
560 #endif
561 return CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorSystemDefault, 0.0);
562 }
563
564 CFTimeZoneRef CFTimeZoneCopySystem(void) {
565 CFTimeZoneRef tz;
566 __CFTimeZoneLockGlobal();
567 if (NULL == __CFTimeZoneSystem) {
568 __CFTimeZoneUnlockGlobal();
569 tz = __CFTimeZoneCreateSystem();
570 __CFTimeZoneLockGlobal();
571 if (NULL == __CFTimeZoneSystem) {
572 __CFTimeZoneSystem = tz;
573 } else {
574 if (tz) CFRelease(tz);
575 }
576 }
577 tz = __CFTimeZoneSystem ? CFRetain(__CFTimeZoneSystem) : NULL;
578 __CFTimeZoneUnlockGlobal();
579 return tz;
580 }
581
582 void CFTimeZoneResetSystem(void) {
583 __CFTimeZoneLockGlobal();
584 if (__CFTimeZoneDefault == __CFTimeZoneSystem) {
585 if (__CFTimeZoneDefault) CFRelease(__CFTimeZoneDefault);
586 __CFTimeZoneDefault = NULL;
587 }
588 if (__CFTimeZoneSystem) CFRelease(__CFTimeZoneSystem);
589 __CFTimeZoneSystem = NULL;
590 __CFTimeZoneUnlockGlobal();
591 }
592
593 CFTimeZoneRef CFTimeZoneCopyDefault(void) {
594 CFTimeZoneRef tz;
595 __CFTimeZoneLockGlobal();
596 if (NULL == __CFTimeZoneDefault) {
597 __CFTimeZoneUnlockGlobal();
598 tz = CFTimeZoneCopySystem();
599 __CFTimeZoneLockGlobal();
600 if (NULL == __CFTimeZoneDefault) {
601 __CFTimeZoneDefault = tz;
602 } else {
603 if (tz) CFRelease(tz);
604 }
605 }
606 tz = __CFTimeZoneDefault ? CFRetain(__CFTimeZoneDefault) : NULL;
607 __CFTimeZoneUnlockGlobal();
608 return tz;
609 }
610
611 void CFTimeZoneSetDefault(CFTimeZoneRef tz) {
612 __CFGenericValidateType(tz, __kCFTimeZoneTypeID);
613 __CFTimeZoneLockGlobal();
614 if (tz != __CFTimeZoneDefault) {
615 if (tz) CFRetain(tz);
616 if (__CFTimeZoneDefault) CFRelease(__CFTimeZoneDefault);
617 __CFTimeZoneDefault = tz;
618 }
619 __CFTimeZoneUnlockGlobal();
620 }
621
622 static CFDictionaryRef __CFTimeZoneCopyCompatibilityDictionary(void);
623
624 CFArrayRef CFTimeZoneCopyKnownNames(void) {
625 CFArrayRef tzs;
626 __CFTimeZoneLockGlobal();
627 if (NULL == __CFKnownTimeZoneList) {
628 CFMutableArrayRef list;
629 /* TimeZone information locate in the registry for Win32
630 * (Aleksey Dukhnyakov)
631 */
632 #if !defined(__WIN32__)
633 list = __CFCopyRecursiveDirectoryList(TZZONEINFO);
634 #else
635 list = __CFCopyWindowsTimeZoneList();
636 #endif
637 // Remove undesirable ancient cruft
638 CFDictionaryRef dict = __CFTimeZoneCopyCompatibilityDictionary();
639 CFIndex idx;
640 for (idx = CFArrayGetCount(list); idx--; ) {
641 CFStringRef item = CFArrayGetValueAtIndex(list, idx);
642 if (CFDictionaryContainsKey(dict, item)) {
643 CFArrayRemoveValueAtIndex(list, idx);
644 }
645 }
646 __CFKnownTimeZoneList = CFArrayCreateCopy(kCFAllocatorSystemDefault, list);
647 CFRelease(list);
648 }
649 tzs = __CFKnownTimeZoneList ? CFRetain(__CFKnownTimeZoneList) : NULL;
650 __CFTimeZoneUnlockGlobal();
651 return tzs;
652 }
653
654 static const unsigned char *__CFTimeZoneAbbreviationDefaults =
655 #if defined(__WIN32__)
656 /*
657 * TimeZone abbreviations for Win32
658 * (Andrew Dzubandovsky)
659 *
660 */
661 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
662 " <!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">"
663 " <plist version=\"1.0\">"
664 " <dict>"
665 " <key>AFG</key> <string>Afghanistan Standard Time</string>"
666 " <key>ALS</key> <string>Alaskan Standard Time</string>"
667 " <key>ARA</key> <string>Arab Standard Time</string>"
668 " <key>ARB</key> <string>Arabian Standard Time</string>"
669 " <key>ARC</key> <string>Arabic Standard Time</string>"
670 " <key>ATL</key> <string>Atlantic Standard Time</string>"
671 " <key>ASC</key> <string>AUS Central Standard Time</string>"
672 " <key>ASE</key> <string>AUS Eastern Standard Time</string>"
673 " <key>AZS</key> <string>Azores Standard Time</string>"
674 " <key>CND</key> <string>Canada Central Standard Time</string>"
675 " <key>CPV</key> <string>Cape Verde Standard Time</string>"
676 " <key>CCS</key> <string>Caucasus Standard Time</string>"
677 " <key>CNAS</key> <string>Cen. Australia Standard Time</string>"
678 " <key>CAMR</key> <string>Central America Standard Time</string>"
679 " <key>CAS</key> <string>Central Asia Standard Time</string>"
680 " <key>CER</key> <string>Central Europe Standard Time</string>"
681 " <key>CEPN</key> <string>Central European Standard Time</string>"
682 " <key>CPC</key> <string>Central Pacific Standard Time</string>"
683 " <key>CSTD</key> <string>Central Standard Time</string>"
684 " <key>CHN</key> <string>China Standard Time</string>"
685 " <key>DTLN</key> <string>Dateline Standard Time</string>"
686 " <key>EAFR</key> <string>E. Africa Standard Time</string>"
687 " <key>EAS</key> <string>E. Australia Standard Time</string>"
688 " <key>ERP</key> <string>E. Europe Standard Time</string>"
689 " <key>ESTH</key> <string>E. South America Standard Time</string>"
690 " <key>ESTM</key> <string>Eastern Standard Time</string>"
691 " <key>EGP</key> <string>Egypt Standard Time</string>"
692 " <key>EKT</key> <string>Ekaterinburg Standard Time</string>"
693 " <key>FST</key> <string>Fiji Standard Time</string>"
694 " <key>FLE</key> <string>FLE Standard Time</string>"
695 " <key>GMT</key> <string>GMT Standard Time</string>"
696 " <key>GRLD</key> <string>Greenland Standard Time</string>"
697 " <key>GRW</key> <string>Greenwich Standard Time</string>"
698 " <key>GTB</key> <string>GTB Standard Time</string>"
699 " <key>HWT</key> <string>Hawaiian Standard Time</string>"
700 " <key>INT</key> <string>India Standard Time</string>"
701 " <key>IRT</key> <string>Iran Standard Time</string>"
702 " <key>ISL</key> <string>Israel Standard Time</string>"
703 " <key>KRT</key> <string>Korea Standard Time</string>"
704 " <key>MXST</key> <string>Mexico Standard Time</string>"
705 " <key>MTL</key> <string>Mid-Atlantic Standard Time</string>"
706 " <key>MNT</key> <string>Mountain Standard Time</string>"
707 " <key>MNM</key> <string>Myanmar Standard Time</string>"
708 " <key>NCNA</key> <string>N. Central Asia Standard Time</string>"
709 " <key>MPL</key> <string>Nepal Standard Time</string>"
710 " <key>NWZ</key> <string>New Zealand Standard Time</string>"
711 " <key>NWF</key> <string>Newfoundland Standard Time</string>"
712 " <key>NTAE</key> <string>North Asia East Standard Time</string>"
713 " <key>NTAS</key> <string>North Asia Standard Time</string>"
714 " <key>HSAT</key> <string>Pacific SA Standard Time</string>"
715 " <key>PST</key> <string>Pacific Standard Time</string>"
716 " <key>RMC</key> <string>Romance Standard Time</string>"
717 " <key>MSK</key> <string>Russian Standard Time</string>"
718 " <key>SSS</key> <string>SA Eastern Standard Time</string>"
719 " <key>SPS</key> <string>SA Pacific Standard Time</string>"
720 " <key>SWS</key> <string>SA Western Standard Time</string>"
721 " <key>SMS</key> <string>Samoa Standard Time</string>"
722 " <key>SAS</key> <string>SE Asia Standard Time</string>"
723 " <key>SNG</key> <string>Singapore Standard Time</string>"
724 " <key>STAF</key> <string>South Africa Standard Time</string>"
725 " <key>SRLK</key> <string>Sri Lanka Standard Time</string>"
726 " <key>TPS</key> <string>Taipei Standard Time</string>"
727 " <key>TSM</key> <string>Tasmania Standard Time</string>"
728 " <key>JPN</key> <string>Tokyo Standard Time</string>"
729 " <key>TNG</key> <string>Tonga Standard Time</string>"
730 " <key>AEST</key> <string>US Eastern Standard Time</string>"
731 " <key>AMST</key> <string>US Mountain Standard Time</string>"
732 " <key>VLD</key> <string>Vladivostok Standard Time</string>"
733 " <key>AUSW</key> <string>W. Australia Standard Time</string>"
734 " <key>AFCW</key> <string>W. Central Africa Standard Time</string>"
735 " <key>EWS</key> <string>W. Europe Standard Time</string>"
736 " <key>ASW</key> <string>West Asia Standard Time</string>"
737 " <key>PWS</key> <string>West Pacific Standard Time</string>"
738 " <key>RKS</key> <string>Yakutsk Standard Time</string>"
739 " </dict>"
740 " </plist>";
741 #else
742 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
743 " <!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">"
744 " <plist version=\"1.0\">"
745 " <dict>"
746 " <key>ADT</key> <string>America/Halifax</string>"
747 " <key>AFT</key> <string>Asia/Kabul</string>"
748 " <key>AKDT</key> <string>America/Juneau</string>"
749 " <key>AKST</key> <string>America/Juneau</string>"
750 " <key>AST</key> <string>America/Halifax</string>"
751 " <key>CDT</key> <string>America/Chicago</string>"
752 " <key>CEST</key> <string>Europe/Rome</string>"
753 " <key>CET</key> <string>Europe/Rome</string>"
754 " <key>CST</key> <string>America/Chicago</string>"
755 " <key>EDT</key> <string>America/New_York</string>"
756 " <key>EEST</key> <string>Europe/Warsaw</string>"
757 " <key>EET</key> <string>Europe/Warsaw</string>"
758 " <key>EST</key> <string>America/New_York</string>"
759 " <key>GMT</key> <string>GMT</string>"
760 " <key>HKST</key> <string>Asia/Hong_Kong</string>"
761 " <key>HST</key> <string>Pacific/Honolulu</string>"
762 " <key>JST</key> <string>Asia/Tokyo</string>"
763 " <key>MDT</key> <string>America/Denver</string>"
764 " <key>MSD</key> <string>Europe/Moscow</string>"
765 " <key>MSK</key> <string>Europe/Moscow</string>"
766 " <key>MST</key> <string>America/Denver</string>"
767 " <key>NZDT</key> <string>Pacific/Auckland</string>"
768 " <key>NZST</key> <string>Pacific/Auckland</string>"
769 " <key>PDT</key> <string>America/Los_Angeles</string>"
770 " <key>PST</key> <string>America/Los_Angeles</string>"
771 " <key>UTC</key> <string>UTC</string>"
772 " <key>WEST</key> <string>Europe/Paris</string>"
773 " <key>WET</key> <string>Europe/Paris</string>"
774 " <key>YDT</key> <string>America/Yakutat</string>"
775 " <key>YST</key> <string>America/Yakutat</string>"
776 " </dict>"
777 " </plist>";
778 #endif
779
780 CFDictionaryRef CFTimeZoneCopyAbbreviationDictionary(void) {
781 CFDictionaryRef dict;
782 __CFTimeZoneLockAbbreviations();
783 if (NULL == __CFTimeZoneAbbreviationDict) {
784 CFDataRef data = CFDataCreate(kCFAllocatorDefault, __CFTimeZoneAbbreviationDefaults, strlen(__CFTimeZoneAbbreviationDefaults));
785 __CFTimeZoneAbbreviationDict = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, data, kCFPropertyListImmutable, NULL);
786 CFRelease(data);
787 }
788 if (NULL == __CFTimeZoneAbbreviationDict) {
789 __CFTimeZoneAbbreviationDict = CFDictionaryCreate(kCFAllocatorDefault, NULL, NULL, 0, NULL, NULL);
790 }
791 dict = __CFTimeZoneAbbreviationDict ? CFRetain(__CFTimeZoneAbbreviationDict) : NULL;
792 __CFTimeZoneUnlockAbbreviations();
793 return dict;
794 }
795
796 void CFTimeZoneSetAbbreviationDictionary(CFDictionaryRef dict) {
797 __CFGenericValidateType(dict, CFDictionaryGetTypeID());
798 __CFTimeZoneLockGlobal();
799 if (dict != __CFTimeZoneAbbreviationDict) {
800 if (dict) CFRetain(dict);
801 if (__CFTimeZoneAbbreviationDict) CFRelease(__CFTimeZoneAbbreviationDict);
802 __CFTimeZoneAbbreviationDict = dict;
803 }
804 __CFTimeZoneUnlockGlobal();
805 }
806
807 CFTimeZoneRef CFTimeZoneCreate(CFAllocatorRef allocator, CFStringRef name, CFDataRef data) {
808 // assert: (NULL != name && NULL != data);
809 CFTimeZoneRef memory;
810 uint32_t size;
811 CFTZPeriod *tzp;
812 CFIndex idx, cnt;
813
814 if (allocator == NULL) allocator = __CFGetDefaultAllocator();
815 __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
816 __CFGenericValidateType(name, CFStringGetTypeID());
817 __CFGenericValidateType(data, CFDataGetTypeID());
818 __CFTimeZoneLockGlobal();
819 if (NULL != __CFTimeZoneCache && CFDictionaryGetValueIfPresent(__CFTimeZoneCache, name, (const void **)&memory)) {
820 __CFTimeZoneUnlockGlobal();
821 return (CFTimeZoneRef)CFRetain(memory);
822 }
823 if (!__CFParseTimeZoneData(allocator, data, &tzp, &cnt)) {
824 __CFTimeZoneUnlockGlobal();
825 return NULL;
826 }
827 size = sizeof(struct __CFTimeZone) - sizeof(CFRuntimeBase);
828 memory = _CFRuntimeCreateInstance(allocator, __kCFTimeZoneTypeID, size, NULL);
829 if (NULL == memory) {
830 __CFTimeZoneUnlockGlobal();
831 for (idx = 0; idx < cnt; idx++) {
832 if (NULL != tzp[idx].abbrev) CFRelease(tzp[idx].abbrev);
833 }
834 if (NULL != tzp) CFAllocatorDeallocate(allocator, tzp);
835 return NULL;
836 }
837 ((struct __CFTimeZone *)memory)->_name = CFStringCreateCopy(allocator, name);
838 ((struct __CFTimeZone *)memory)->_data = CFDataCreateCopy(allocator, data);
839 ((struct __CFTimeZone *)memory)->_periods = tzp;
840 ((struct __CFTimeZone *)memory)->_periodCnt = cnt;
841 if (NULL == __CFTimeZoneCache) {
842 CFDictionaryKeyCallBacks kcb = kCFTypeDictionaryKeyCallBacks;
843 kcb.retain = kcb.release = NULL;
844 __CFTimeZoneCache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kcb, &kCFTypeDictionaryValueCallBacks);
845 }
846 CFDictionaryAddValue(__CFTimeZoneCache, ((struct __CFTimeZone *)memory)->_name, memory);
847 __CFTimeZoneUnlockGlobal();
848 return memory;
849 }
850
851 #if !defined(__WIN32__)
852 static CFTimeZoneRef __CFTimeZoneCreateFixed(CFAllocatorRef allocator, int32_t seconds, CFStringRef name, int isDST) {
853 CFTimeZoneRef result;
854 CFDataRef data;
855 int32_t nameLen = CFStringGetLength(name);
856 #if defined(__WIN32__)
857 unsigned char *dataBytes = CFAllocatorAllocate(allocator, 52 + nameLen + 1, 0);
858 if (!dataBytes) return NULL;
859 if (__CFOASafe) __CFSetLastAllocationEventName(dataBytes, "CFTimeZone (temp)");
860 #else
861 unsigned char dataBytes[52 + nameLen + 1];
862 #endif
863 memset(dataBytes, 0, sizeof(dataBytes));
864 __CFEntzcode(1, dataBytes + 20);
865 __CFEntzcode(1, dataBytes + 24);
866 __CFEntzcode(1, dataBytes + 36);
867 __CFEntzcode(nameLen + 1, dataBytes + 40);
868 __CFEntzcode(seconds, dataBytes + 44);
869 dataBytes[48] = isDST ? 1 : 0;
870 CFStringGetCString(name, dataBytes + 50, nameLen + 1, kCFStringEncodingASCII);
871 data = CFDataCreate(allocator, dataBytes, 52 + nameLen + 1);
872 result = CFTimeZoneCreate(allocator, name, data);
873 CFRelease(data);
874 #if defined(__WIN32__)
875 CFAllocatorDeallocate(allocator, dataBytes);
876 #endif
877 return result;
878 }
879 #endif
880
881 // rounds offset to nearest minute
882 CFTimeZoneRef CFTimeZoneCreateWithTimeIntervalFromGMT(CFAllocatorRef allocator, CFTimeInterval ti) {
883 CFTimeZoneRef result;
884 CFStringRef name;
885 int32_t seconds, minute, hour;
886 if (allocator == NULL) allocator = __CFGetDefaultAllocator();
887 __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
888 if (ti < -18.0 * 3600 || 18.0 * 3600 < ti) return NULL;
889 ti = (ti < 0.0) ? ceil((ti / 60.0) - 0.5) * 60.0 : floor((ti / 60.0) + 0.5) * 60.0;
890 seconds = (int32_t)ti;
891 hour = (ti < 0) ? (-seconds / 3600) : (seconds / 3600);
892 seconds -= ((ti < 0) ? -hour : hour) * 3600;
893 minute = (ti < 0) ? (-seconds / 60) : (seconds / 60);
894 if (fabs(ti) < 1.0) {
895 name = CFRetain(CFSTR("GMT"));
896 } else {
897 name = CFStringCreateWithFormat(allocator, NULL, CFSTR("GMT%c%02d%02d"), (ti < 0.0 ? '-' : '+'), hour, minute);
898 }
899 #if !defined(__WIN32__)
900 result = __CFTimeZoneCreateFixed(allocator, (int32_t)ti, name, 0);
901 #else
902 /* CFTimeZoneRef->_data will contain TIME_ZONE_INFORMATION structure
903 * to find current timezone
904 * (Aleksey Dukhnyakov)
905 */
906 {
907 TIME_ZONE_INFORMATION tzi;
908 CFDataRef data;
909 CFIndex length = CFStringGetLength(name);
910
911 memset(&tzi,0,sizeof(tzi));
912 tzi.Bias=(long)(-ti/60);
913 CFStringGetCharacters(name, CFRangeMake(0, length < 31 ? length : 31 ), tzi.StandardName);
914 data = CFDataCreate(allocator,(UInt8*)&tzi, sizeof(tzi));
915 result = CFTimeZoneCreate(allocator, name, data);
916 CFRelease(data);
917 }
918 #endif
919 CFRelease(name);
920 return result;
921 }
922
923 CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef name, Boolean tryAbbrev) {
924 CFTimeZoneRef result = NULL;
925 CFStringRef tzName = NULL;
926 CFDataRef data = NULL;
927
928 if (allocator == NULL) allocator = __CFGetDefaultAllocator();
929 __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
930 __CFGenericValidateType(name, CFStringGetTypeID());
931 if (CFEqual(CFSTR(""), name)) {
932 // empty string is not a time zone name, just abort now,
933 // following stuff will fail anyway
934 return NULL;
935 }
936 __CFTimeZoneLockGlobal();
937 if (NULL != __CFTimeZoneCache && CFDictionaryGetValueIfPresent(__CFTimeZoneCache, name, (const void **)&result)) {
938 __CFTimeZoneUnlockGlobal();
939 return (CFTimeZoneRef)CFRetain(result);
940 }
941 __CFTimeZoneUnlockGlobal();
942 #if !defined(__WIN32__)
943 CFURLRef baseURL, tempURL;
944 void *bytes;
945 CFIndex length;
946
947 baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(TZZONEINFO), kCFURLPOSIXPathStyle, true);
948 if (tryAbbrev) {
949 CFDictionaryRef abbrevs = CFTimeZoneCopyAbbreviationDictionary();
950 tzName = CFDictionaryGetValue(abbrevs, name);
951 if (NULL != tzName) {
952 tempURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, baseURL, tzName, false);
953 if (NULL != tempURL) {
954 if (_CFReadBytesFromFile(kCFAllocatorDefault, tempURL, &bytes, &length, 0)) {
955 data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, length, kCFAllocatorDefault);
956 }
957 CFRelease(tempURL);
958 }
959 }
960 CFRelease(abbrevs);
961 }
962 if (NULL == data) {
963 CFDictionaryRef dict = __CFTimeZoneCopyCompatibilityDictionary();
964 CFStringRef mapping = CFDictionaryGetValue(dict, name);
965 if (mapping) {
966 name = mapping;
967 } else if (CFStringHasPrefix(name, CFSTR(TZZONEINFO))) {
968 CFMutableStringRef unprefixed = CFStringCreateMutableCopy(kCFAllocatorDefault, CFStringGetLength(name), name);
969 CFStringDelete(unprefixed, CFRangeMake(0, sizeof(TZZONEINFO)));
970 mapping = CFDictionaryGetValue(dict, unprefixed);
971 if (mapping) {
972 name = mapping;
973 }
974 CFRelease(unprefixed);
975 }
976 CFRelease(dict);
977 if (CFEqual(CFSTR(""), name)) {
978 return NULL;
979 }
980 }
981 if (NULL == data) {
982 tzName = name;
983 tempURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, baseURL, tzName, false);
984 if (NULL != tempURL) {
985 if (_CFReadBytesFromFile(kCFAllocatorDefault, tempURL, &bytes, &length, 0)) {
986 data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, length, kCFAllocatorDefault);
987 }
988 CFRelease(tempURL);
989 }
990 }
991 CFRelease(baseURL);
992 if (NULL == data) {
993 tzName = name;
994 tempURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, tzName, kCFURLPOSIXPathStyle, false);
995 if (NULL != tempURL) {
996 if (_CFReadBytesFromFile(kCFAllocatorDefault, tempURL, &bytes, &length, 0)) {
997 data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, length, kCFAllocatorDefault);
998 }
999 CFRelease(tempURL);
1000 }
1001 }
1002 if (NULL != data) {
1003 result = CFTimeZoneCreate(allocator, tzName, data);
1004 CFRelease(data);
1005 }
1006 #else
1007 /* Reading GMT offset and daylight flag from the registry
1008 * for TimeZone name
1009 * (Aleksey Dukhnyakov)
1010 */
1011 {
1012 CFStringRef safeName = name;
1013 struct {
1014 LONG Bias;
1015 LONG StandardBias;
1016 LONG DaylightBias;
1017 SYSTEMTIME StandardDate;
1018 SYSTEMTIME DaylightDate;
1019 } tzi;
1020 TIME_ZONE_INFORMATION tzi_system;
1021
1022 HKEY hkResult;
1023 DWORD dwType, dwSize=sizeof(tzi),
1024 dwSize_name1=sizeof(tzi_system.StandardName),
1025 dwSize_name2=sizeof(tzi_system.DaylightName);
1026
1027 if (tryAbbrev) {
1028 CFDictionaryRef abbrevs = CFTimeZoneCopyAbbreviationDictionary();
1029 tzName = CFDictionaryGetValue(abbrevs, name);
1030 if (NULL == tzName) {
1031 return NULL;
1032 }
1033 name = tzName;
1034 CFRelease(abbrevs);
1035 }
1036
1037 /* Open regestry and move down to the TimeZone information
1038 */
1039 if (RegOpenKey(HKEY_LOCAL_MACHINE,_T(TZZONEINFO),&hkResult) !=
1040 ERROR_SUCCESS ) {
1041 return NULL;
1042 }
1043 /* Move down to specific TimeZone name
1044 */
1045 #if defined(UNICODE)
1046 if (RegOpenKey(hkResult,CFStringGetCharactersPtr(name) ,&hkResult) !=
1047 ERROR_SUCCESS ) {
1048 #else
1049 if (RegOpenKey(hkResult,CFStringGetCStringPtr(name, CFStringGetSystemEncoding()),&hkResult) != ERROR_SUCCESS ) {
1050 #endif
1051 return NULL;
1052 }
1053 /* TimeZone information(offsets, daylight flag, ...) assign to tzi structure
1054 */
1055 if ( RegQueryValueEx(hkResult,_T("TZI"),NULL,&dwType,(LPBYTE)&tzi,&dwSize) != ERROR_SUCCESS &&
1056 RegQueryValueEx(hkResult,_T("Std"),NULL,&dwType,(LPBYTE)&tzi_system.StandardName,&dwSize_name1) != ERROR_SUCCESS &&
1057 RegQueryValueEx(hkResult,_T("Dlt"),NULL,&dwType,(LPBYTE)&tzi_system.DaylightName,&dwSize_name2) != ERROR_SUCCESS )
1058 {
1059 return NULL;
1060 }
1061
1062 tzi_system.Bias=tzi.Bias;
1063 tzi_system.StandardBias=tzi.StandardBias;
1064 tzi_system.DaylightBias=tzi.DaylightBias;
1065 tzi_system.StandardDate=tzi.StandardDate;
1066 tzi_system.DaylightDate=tzi.DaylightDate;
1067
1068 /* CFTimeZoneRef->_data will contain TIME_ZONE_INFORMATION structure
1069 * to find current timezone
1070 * (Aleksey Dukhnyakov)
1071 */
1072 data = CFDataCreate(allocator,(UInt8*)&tzi_system, sizeof(tzi_system));
1073
1074 RegCloseKey(hkResult);
1075 result = CFTimeZoneCreate(allocator, name, data);
1076 if (result) {
1077 if (tryAbbrev)
1078 result->_periods->abbrev = CFStringCreateCopy(allocator,safeName);
1079 else {
1080 }
1081 }
1082 CFRelease(data);
1083 }
1084 #endif
1085 return result;
1086 }
1087
1088 CFStringRef CFTimeZoneGetName(CFTimeZoneRef tz) {
1089 CF_OBJC_FUNCDISPATCH0(__kCFTimeZoneTypeID, CFStringRef, tz, "name");
1090 __CFGenericValidateType(tz, __kCFTimeZoneTypeID);
1091 return tz->_name;
1092 }
1093
1094 CFDataRef CFTimeZoneGetData(CFTimeZoneRef tz) {
1095 CF_OBJC_FUNCDISPATCH0(__kCFTimeZoneTypeID, CFDataRef, tz, "data");
1096 __CFGenericValidateType(tz, __kCFTimeZoneTypeID);
1097 return tz->_data;
1098 }
1099
1100 /* This function converts CFAbsoluteTime to (Win32) SYSTEMTIME
1101 * (Aleksey Dukhnyakov)
1102 */
1103 #if defined(__WIN32__)
1104 BOOL __CFTimeZoneGetWin32SystemTime(SYSTEMTIME * sys_time, CFAbsoluteTime time)
1105 {
1106 LONGLONG l;
1107 FILETIME * ftime=(FILETIME*)&l;
1108
1109 /* seconds between 1601 and 1970 : 11644473600,
1110 * seconds between 1970 and 2001 : 978307200,
1111 * FILETIME - number of 100-nanosecond intervals since January 1, 1601
1112 */
1113 l=(time+11644473600LL+978307200)*10000000;
1114 if (FileTimeToSystemTime(ftime,sys_time))
1115 return TRUE;
1116 else
1117 return FALSE;
1118 }
1119 #endif
1120
1121 CFTimeInterval _CFTimeZoneGetDSTOffset(CFTimeZoneRef tz, CFAbsoluteTime at) {
1122 #if !defined(__WIN32__)
1123 // #warning this does not work for non-CFTimeZoneRefs
1124 CFIndex idx;
1125 idx = __CFBSearchTZPeriods(tz, at);
1126 // idx 0 is never returned if it is in DST
1127 if (__CFTZPeriodIsDST(&(tz->_periods[idx]))) {
1128 return __CFTZPeriodGMTOffset(&(tz->_periods[idx])) - __CFTZPeriodGMTOffset(&(tz->_periods[idx - 1]));
1129 }
1130 #endif
1131 return 0.0;
1132 }
1133
1134 // returns 0.0 if there is no data for the next switch after 'at'
1135 CFAbsoluteTime _CFTimeZoneGetNextDSTSwitch(CFTimeZoneRef tz, CFAbsoluteTime at) {
1136 #if !defined(__WIN32__)
1137 // #warning this does not work for non-CFTimeZoneRefs
1138 CFIndex idx;
1139 idx = __CFBSearchTZPeriods(tz, at);
1140 if (tz->_periodCnt <= idx + 1) {
1141 return 0.0;
1142 }
1143 return (CFAbsoluteTime)__CFTZPeriodStartSeconds(&(tz->_periods[idx + 1]));
1144 #endif
1145 return 0.0;
1146 }
1147
1148 CFTimeInterval CFTimeZoneGetSecondsFromGMT(CFTimeZoneRef tz, CFAbsoluteTime at) {
1149 #if !defined(__WIN32__)
1150 CFIndex idx;
1151 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID, CFTimeInterval, tz, "_secondsFromGMTForAbsoluteTime:", at);
1152 __CFGenericValidateType(tz, __kCFTimeZoneTypeID);
1153 idx = __CFBSearchTZPeriods(tz, at);
1154 return __CFTZPeriodGMTOffset(&(tz->_periods[idx]));
1155 #else
1156 /* To calculate seconds from GMT, calculate current timezone time and
1157 * subtract GMT timnezone time
1158 * (Aleksey Dukhnyakov)
1159 */
1160 TIME_ZONE_INFORMATION tzi;
1161 FILETIME ftime1,ftime2;
1162 SYSTEMTIME stime0,stime1,stime2;
1163 LONGLONG * l1= (LONGLONG*)&ftime1;
1164 LONGLONG * l2= (LONGLONG*)&ftime2;
1165 CFRange range={0,sizeof(TIME_ZONE_INFORMATION)};
1166 double result;
1167
1168 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID, CFTimeInterval, tz, "_secondsFromGMTForAbsoluteTime:", at);
1169
1170 CFDataGetBytes(tz->_data,range,(UInt8*)&tzi);
1171
1172 if (!__CFTimeZoneGetWin32SystemTime(&stime0,at) ||
1173 !SystemTimeToTzSpecificLocalTime(&tzi,&stime0,&stime1) ||
1174 !SystemTimeToFileTime(&stime1,&ftime1) )
1175 {
1176 CFAssert(0, __kCFLogAssertion, "Win32 system time/timezone failed !\n");
1177 return 0;
1178 }
1179
1180 tzi.DaylightDate.wMonth=0;
1181 tzi.StandardDate.wMonth=0;
1182 tzi.StandardBias=0;
1183 tzi.DaylightBias=0;
1184 tzi.Bias=0;
1185
1186 if ( !SystemTimeToTzSpecificLocalTime(&tzi,&stime0,&stime2) ||
1187 !SystemTimeToFileTime(&stime2,&ftime2))
1188 {
1189 CFAssert(0, __kCFLogAssertion, "Win32 system time/timezone failed !\n");
1190 return 0;
1191 }
1192 result=(double)((*l1-*l2)/10000000);
1193 return result;
1194 #endif
1195 }
1196
1197 #if defined(__WIN32__)
1198 /*
1199 * Get abbreviation for name for WIN32 platform
1200 * (Aleksey Dukhnyakov)
1201 */
1202
1203 typedef struct {
1204 CFStringRef tzName;
1205 CFStringRef tzAbbr;
1206 } _CFAbbrFind;
1207
1208 static void _CFFindKeyForValue(const void *key, const void *value, void *context) {
1209 if ( ((_CFAbbrFind *)context)->tzAbbr != NULL ) {
1210 if ( ((_CFAbbrFind *)context)->tzName == (CFStringRef) value ) {
1211 ((_CFAbbrFind *)context)->tzAbbr = key ;
1212 }
1213 }
1214 }
1215
1216 CFIndex __CFTimeZoneInitAbbrev(CFTimeZoneRef tz) {
1217
1218 if ( tz->_periods->abbrev == NULL ) {
1219 _CFAbbrFind abbr = { NULL, NULL };
1220 CFDictionaryRef abbrevs = CFTimeZoneCopyAbbreviationDictionary();
1221
1222 CFDictionaryApplyFunction(abbrevs, _CFFindKeyForValue, &abbr);
1223
1224 if ( abbr.tzAbbr != NULL)
1225 tz->_periods->abbrev = CFStringCreateCopy(kCFAllocatorDefault, abbr.tzAbbr);
1226 else
1227 tz->_periods->abbrev = CFStringCreateCopy(kCFAllocatorDefault, tz->_name);
1228 /* We should return name of TimeZone if couldn't find abbrevation.
1229 * (Ala on MACOSX)
1230 *
1231 * old line : tz->_periods->abbrev =
1232 * CFStringCreateWithCString(kCFAllocatorDefault,"UNKNOWN",
1233 * CFStringGetSystemEncoding());
1234 *
1235 * (Aleksey Dukhnyakov)
1236 */
1237 CFRelease( abbrevs );
1238 }
1239
1240 return 0;
1241 }
1242 #endif
1243
1244 CFStringRef CFTimeZoneCopyAbbreviation(CFTimeZoneRef tz, CFAbsoluteTime at) {
1245 CFStringRef result;
1246 CFIndex idx;
1247 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID, CFStringRef, tz, "_abbreviationForAbsoluteTime:", at);
1248 __CFGenericValidateType(tz, __kCFTimeZoneTypeID);
1249 #if !defined(__WIN32__)
1250 idx = __CFBSearchTZPeriods(tz, at);
1251 #else
1252 /*
1253 * Initialize abbreviation for this TimeZone
1254 * (Aleksey Dukhnyakov)
1255 */
1256 idx = __CFTimeZoneInitAbbrev(tz);
1257 #endif
1258 result = __CFTZPeriodAbbreviation(&(tz->_periods[idx]));
1259 return result ? CFRetain(result) : NULL;
1260 }
1261
1262 Boolean CFTimeZoneIsDaylightSavingTime(CFTimeZoneRef tz, CFAbsoluteTime at) {
1263 #if !defined(__WIN32__)
1264 CFIndex idx;
1265 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID, Boolean, tz, "_isDaylightSavingTimeForAbsoluteTime:", at);
1266 __CFGenericValidateType(tz, __kCFTimeZoneTypeID);
1267 idx = __CFBSearchTZPeriods(tz, at);
1268 return __CFTZPeriodIsDST(&(tz->_periods[idx]));
1269 #else
1270 /* Compare current timezone time and current timezone time without
1271 * transition to day light saving time
1272 * (Aleskey Dukhnyakov)
1273 */
1274 TIME_ZONE_INFORMATION tzi;
1275 SYSTEMTIME stime0,stime1,stime2;
1276 CFRange range={0,sizeof(TIME_ZONE_INFORMATION)};
1277
1278 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID, Boolean, tz, "_isDaylightSavingTimeForAbsoluteTime:", at);
1279
1280 CFDataGetBytes(tz->_data,range,(UInt8*)&tzi);
1281
1282 if ( !__CFTimeZoneGetWin32SystemTime(&stime0,at) ||
1283 !SystemTimeToTzSpecificLocalTime(&tzi,&stime0,&stime1)) {
1284 CFAssert(0, __kCFLogAssertion, "Win32 system time/timezone failed !\n");
1285 return FALSE;
1286 }
1287
1288 tzi.DaylightDate.wMonth=0;
1289 tzi.StandardDate.wMonth=0;
1290
1291 if ( !SystemTimeToTzSpecificLocalTime(&tzi,&stime0,&stime2)) {
1292 CFAssert(0, __kCFLogAssertion, "Win32 system time/timezone failed !\n");
1293 return FALSE;
1294 }
1295
1296 if ( !memcmp(&stime1,&stime2,sizeof(stime1)) )
1297 return FALSE;
1298
1299 return TRUE;
1300 #endif
1301 }
1302
1303 CFTimeInterval _CFTimeZoneGetDSTDelta(CFTimeZoneRef tz, CFAbsoluteTime at) {
1304 CFIndex idx;
1305 __CFGenericValidateType(tz, __kCFTimeZoneTypeID);
1306 idx = __CFBSearchTZPeriods(tz, at);
1307 CFTimeInterval delta = __CFTZPeriodGMTOffset(&(tz->_periods[idx]));
1308 if (idx + 1 < tz->_periodCnt) {
1309 return fabs(delta - __CFTZPeriodGMTOffset(&(tz->_periods[idx + 1])));
1310 } else if (0 < idx) {
1311 return fabs(delta - __CFTZPeriodGMTOffset(&(tz->_periods[idx - 1])));
1312 }
1313 return 0.0;
1314 }
1315
1316 static CFDictionaryRef __CFTimeZoneCopyCompatibilityDictionary(void) {
1317 CFDictionaryRef dict;
1318 __CFTimeZoneLockCompatibilityMapping();
1319 if (NULL == __CFTimeZoneCompatibilityMappingDict) {
1320 __CFTimeZoneCompatibilityMappingDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 112, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1321
1322 // Empty string means delete/ignore these
1323 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Factory"), CFSTR(""));
1324 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/Pacific-New"), CFSTR(""));
1325 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Mideast/Riyadh87"), CFSTR(""));
1326 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Mideast/Riyadh88"), CFSTR(""));
1327 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Mideast/Riyadh89"), CFSTR(""));
1328 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/AST4"), CFSTR(""));
1329 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/AST4ADT"), CFSTR(""));
1330 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/CST6"), CFSTR(""));
1331 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/CST6CDT"), CFSTR(""));
1332 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/EST5"), CFSTR(""));
1333 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/EST5EDT"), CFSTR(""));
1334 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/HST10"), CFSTR(""));
1335 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/MST7"), CFSTR(""));
1336 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/MST7MDT"), CFSTR(""));
1337 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/PST8"), CFSTR(""));
1338 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/PST8PDT"), CFSTR(""));
1339 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/YST9"), CFSTR(""));
1340 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("SystemV/YST9YDT"), CFSTR(""));
1341
1342 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Atka"), CFSTR("America/Adak"));
1343 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Ensenada"), CFSTR("America/Tijuana"));
1344 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Fort_Wayne"), CFSTR("America/Indianapolis"));
1345 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Indiana/Indianapolis"), CFSTR("America/Indianapolis"));
1346 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Kentucky/Louisville"), CFSTR("America/Louisville"));
1347 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Knox_IN"), CFSTR("America/Indiana/Knox"));
1348 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Porto_Acre"), CFSTR("America/Rio_Branco"));
1349 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Rosario"), CFSTR("America/Cordoba"));
1350 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Shiprock"), CFSTR("America/Denver"));
1351 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("America/Virgin"), CFSTR("America/St_Thomas"));
1352 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Antarctica/South_Pole"), CFSTR("Antarctica/McMurdo"));
1353 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Asia/Ashkhabad"), CFSTR("Asia/Ashgabat"));
1354 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Asia/Chungking"), CFSTR("Asia/Chongqing"));
1355 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Asia/Macao"), CFSTR("Asia/Macau"));
1356 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Asia/Tel_Aviv"), CFSTR("Asia/Jerusalem"));
1357 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Asia/Thimbu"), CFSTR("Asia/Thimphu"));
1358 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Asia/Ujung_Pandang"), CFSTR("Asia/Makassar"));
1359 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Asia/Ulan_Bator"), CFSTR("Asia/Ulaanbaatar"));
1360 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/ACT"), CFSTR("Australia/Sydney"));
1361 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/LHI"), CFSTR("Australia/Lord_Howe"));
1362 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/NSW"), CFSTR("Australia/Sydney"));
1363 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/North"), CFSTR("Australia/Darwin"));
1364 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/Queensland"), CFSTR("Australia/Brisbane"));
1365 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/South"), CFSTR("Australia/Adelaide"));
1366 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/Tasmania"), CFSTR("Australia/Hobart"));
1367 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/Victoria"), CFSTR("Australia/Melbourne"));
1368 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/West"), CFSTR("Australia/Perth"));
1369 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Australia/Yancowinna"), CFSTR("Australia/Broken_Hill"));
1370 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Brazil/Acre"), CFSTR("America/Porto_Acre"));
1371 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Brazil/DeNoronha"), CFSTR("America/Noronha"));
1372 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Brazil/West"), CFSTR("America/Manaus"));
1373 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("CST6CDT"), CFSTR("America/Chicago"));
1374 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Canada/Central"), CFSTR("America/Winnipeg"));
1375 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Canada/East-Saskatchewan"), CFSTR("America/Regina"));
1376 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Canada/Pacific"), CFSTR("America/Vancouver"));
1377 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Canada/Yukon"), CFSTR("America/Whitehorse"));
1378 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Chile/Continental"), CFSTR("America/Santiago"));
1379 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Chile/EasterIsland"), CFSTR("Pacific/Easter"));
1380 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Cuba"), CFSTR("America/Havana"));
1381 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("EST5EDT"), CFSTR("America/New_York"));
1382 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Egypt"), CFSTR("Africa/Cairo"));
1383 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Eire"), CFSTR("Europe/Dublin"));
1384 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Etc/GMT+0"), CFSTR("GMT"));
1385 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Etc/GMT-0"), CFSTR("GMT"));
1386 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Etc/GMT0"), CFSTR("GMT"));
1387 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Etc/Greenwich"), CFSTR("GMT"));
1388 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Etc/Universal"), CFSTR("UTC"));
1389 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Etc/Zulu"), CFSTR("UTC"));
1390 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Europe/Nicosia"), CFSTR("Asia/Nicosia"));
1391 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Europe/Tiraspol"), CFSTR("Europe/Chisinau"));
1392 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("GB-Eire"), CFSTR("Europe/London"));
1393 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("GB"), CFSTR("Europe/London"));
1394 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("GMT+0"), CFSTR("GMT"));
1395 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("GMT-0"), CFSTR("GMT"));
1396 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("GMT0"), CFSTR("GMT"));
1397 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Greenwich"), CFSTR("GMT"));
1398 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Hongkong"), CFSTR("Asia/Hong_Kong"));
1399 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Iceland"), CFSTR("Atlantic/Reykjavik"));
1400 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Iran"), CFSTR("Asia/Tehran"));
1401 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Israel"), CFSTR("Asia/Jerusalem"));
1402 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Jamaica"), CFSTR("America/Jamaica"));
1403 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Kwajalein"), CFSTR("Pacific/Kwajalein"));
1404 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Libya"), CFSTR("Africa/Tripoli"));
1405 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("MST7MDT"), CFSTR("America/Denver"));
1406 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Mexico/BajaNorte"), CFSTR("America/Tijuana"));
1407 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Mexico/BajaSur"), CFSTR("America/Mazatlan"));
1408 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Mexico/General"), CFSTR("America/Mexico_City"));
1409 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("NZ-CHAT"), CFSTR("Pacific/Chatham"));
1410 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("NZ"), CFSTR("Pacific/Auckland"));
1411 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Navajo"), CFSTR("America/Denver"));
1412 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("PRC"), CFSTR("Asia/Shanghai"));
1413 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("PST8PDT"), CFSTR("America/Los_Angeles"));
1414 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Pacific/Samoa"), CFSTR("Pacific/Pago_Pago"));
1415 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Poland"), CFSTR("Europe/Warsaw"));
1416 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Portugal"), CFSTR("Europe/Lisbon"));
1417 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("ROC"), CFSTR("Asia/Taipei"));
1418 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("ROK"), CFSTR("Asia/Seoul"));
1419 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Singapore"), CFSTR("Asia/Singapore"));
1420 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Turkey"), CFSTR("Europe/Istanbul"));
1421 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("UCT"), CFSTR("UTC"));
1422 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/Alaska"), CFSTR("America/Anchorage"));
1423 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/Aleutian"), CFSTR("America/Adak"));
1424 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/Arizona"), CFSTR("America/Phoenix"));
1425 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/East-Indiana"), CFSTR("America/Indianapolis"));
1426 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/Hawaii"), CFSTR("Pacific/Honolulu"));
1427 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/Indiana-Starke"), CFSTR("America/Indiana/Knox"));
1428 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/Michigan"), CFSTR("America/Detroit"));
1429 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("US/Samoa"), CFSTR("Pacific/Pago_Pago"));
1430 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Universal"), CFSTR("UTC"));
1431 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("W-SU"), CFSTR("Europe/Moscow"));
1432 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict, CFSTR("Zulu"), CFSTR("UTC"));
1433 }
1434 dict = __CFTimeZoneCompatibilityMappingDict ? CFRetain(__CFTimeZoneCompatibilityMappingDict) : NULL;
1435 __CFTimeZoneUnlockCompatibilityMapping();
1436 return dict;
1437 }
1438
1439 __private_extern__ CFDictionaryRef __CFTimeZoneCopyCompatibilityDictionary2(void) {
1440 CFDictionaryRef dict;
1441 __CFTimeZoneLockCompatibilityMapping();
1442 if (NULL == __CFTimeZoneCompatibilityMappingDict2) {
1443 __CFTimeZoneCompatibilityMappingDict2 = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 16, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1444 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Asia/Dacca"), CFSTR("Asia/Dhaka"));
1445 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Asia/Istanbul"), CFSTR("Europe/Istanbul"));
1446 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Australia/Canberra"), CFSTR("Australia/Sydney"));
1447 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Brazil/East"), CFSTR("America/Sao_Paulo"));
1448 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Canada/Atlantic"), CFSTR("America/Halifax"));
1449 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Canada/Eastern"), CFSTR("America/Montreal"));
1450 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Canada/Mountain"), CFSTR("America/Edmonton"));
1451 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Canada/Newfoundland"), CFSTR("America/St_Johns"));
1452 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Canada/Saskatchewan"), CFSTR("America/Regina"));
1453 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("Japan"), CFSTR("Asia/Tokyo"));
1454 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("US/Central"), CFSTR("America/Chicago"));
1455 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("US/Eastern"), CFSTR("America/New_York"));
1456 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("US/Mountain"), CFSTR("America/Denver"));
1457 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2, CFSTR("US/Pacific"), CFSTR("America/Los_Angeles"));
1458 }
1459 dict = __CFTimeZoneCompatibilityMappingDict2 ? CFRetain(__CFTimeZoneCompatibilityMappingDict2) : NULL;
1460 __CFTimeZoneUnlockCompatibilityMapping();
1461 return dict;
1462 }
1463
1464