2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 Copyright 1998-2002, Apple, Inc. All rights reserved.
25 Responsibility: Christopher Kane
28 #include <CoreFoundation/CFTimeZone.h>
29 #include <CoreFoundation/CFPropertyList.h>
30 #include "CFUtilitiesPriv.h"
31 #include "CFInternal.h"
35 #if !defined(__WIN32__)
47 #if defined(__WIN32__)
51 // For Windows(TM) time zone information, see registry key:
52 // HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Time Zones
54 #if defined(__WIN32__)
55 #define TZZONEINFO "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"
57 #define TZZONELINK "/etc/localtime"
58 #define TZZONEINFO "/usr/share/zoneinfo/"
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;
72 CF_INLINE
void __CFTimeZoneLockGlobal(void) {
73 __CFSpinLock(&__CFTimeZoneGlobalLock
);
76 CF_INLINE
void __CFTimeZoneUnlockGlobal(void) {
77 __CFSpinUnlock(&__CFTimeZoneGlobalLock
);
80 CF_INLINE
void __CFTimeZoneLockAbbreviations(void) {
81 __CFSpinLock(&__CFTimeZoneAbbreviationLock
);
84 CF_INLINE
void __CFTimeZoneUnlockAbbreviations(void) {
85 __CFSpinUnlock(&__CFTimeZoneAbbreviationLock
);
88 CF_INLINE
void __CFTimeZoneLockCompatibilityMapping(void) {
89 __CFSpinLock(&__CFTimeZoneCompatibilityMappingLock
);
92 CF_INLINE
void __CFTimeZoneUnlockCompatibilityMapping(void) {
93 __CFSpinUnlock(&__CFTimeZoneCompatibilityMappingLock
);
96 /* This function should be used for WIN32 instead of
97 * __CFCopyRecursiveDirectoryList function.
98 * It takes TimeZone names from the registry
99 * (Aleksey Dukhnyakov)
101 #if defined(__WIN32__)
102 static CFMutableArrayRef
__CFCopyWindowsTimeZoneList() {
103 CFMutableArrayRef result
= NULL
;
105 TCHAR lpName
[MAX_PATH
+1];
106 DWORD dwIndex
, retCode
;
108 if (RegOpenKey(HKEY_LOCAL_MACHINE
,_T(TZZONEINFO
),&hkResult
) !=
112 result
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
);
114 for (dwIndex
=0; (retCode
= RegEnumKey(hkResult
,dwIndex
,lpName
,MAX_PATH
)) != ERROR_NO_MORE_ITEMS
; dwIndex
++) {
116 if (retCode
!= ERROR_SUCCESS
) {
117 RegCloseKey(hkResult
);
123 CFStringRef string
= CFStringCreateWithBytes(kCFAllocatorDefault
, lpName
, _tcslen(lpName
), kCFStringEncodingUnicode
, false);
125 CFStringRef string
= CFStringCreateWithBytes(kCFAllocatorDefault
, lpName
, _tcslen(lpName
), CFStringGetSystemEncoding(), false);
127 CFArrayAppendValue(result
, string
);
132 RegCloseKey(hkResult
);
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
];
144 // No d_namlen in dirent struct on Linux
145 #if defined(__LINUX__)
146 #define dentDNameLen strlen(dent->d_name)
148 #define dentDNameLen dent->d_namlen
150 fd
= open(topDir
, O_RDONLY
, 0);
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
) {
165 strcpy(path
, topDir
);
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
;
174 if (DT_DIR
== dent
->d_type
) {
175 strcpy(path
, topDir
);
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
);
192 CFStringRef string
= CFStringCreateWithBytes(kCFAllocatorDefault
, dent
->d_name
, dentDNameLen
, kCFStringEncodingUTF8
, false);
193 CFArrayAppendValue(result
, string
);
197 numread
= getdirentries(fd
, dirge
, 8192, &basep
);
209 typedef struct _CFTZPeriod
{
215 struct __CFTimeZone
{
217 CFStringRef _name
; /* immutable */
218 CFDataRef _data
; /* immutable */
219 CFTZPeriod
*_periods
; /* immutable */
220 int32_t _periodCnt
; /* immutable */
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 */
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));
238 CF_INLINE
int32_t __CFTZPeriodStartSeconds(const CFTZPeriod
*period
) {
239 return period
->startSec
;
242 CF_INLINE CFStringRef
__CFTZPeriodAbbreviation(const CFTZPeriod
*period
) {
243 return period
->abbrev
;
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
;
252 CF_INLINE Boolean
__CFTZPeriodIsDST(const CFTZPeriod
*period
) {
253 return (Boolean
)__CFBitfieldGetValue(period
->info
, 17, 17);
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
;
266 static CFIndex
__CFBSearchTZPeriods(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
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;
282 ** Each time zone data file begins with. . .
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 */
296 ** . . .followed by. . .
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
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);
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;
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
;
341 Boolean result
= true;
343 p
= CFDataGetBytePtr(data
);
344 len
= CFDataGetLength(data
);
345 if (len
< (int32_t)sizeof(struct tzhead
)) {
349 if (!(p
[0] == 'T' && p
[1] == 'Z' && p
[2] == 'i' && p
[3] == 'f')) return false; /* Don't parse without TZif at head of file */
351 p
+= 20 + 4 + 4 + 4; /* skip reserved, ttisgmtcnt, ttisstdcnt, leapcnt */
352 timecnt
= __CFDetzcode(p
);
354 typecnt
= __CFDetzcode(p
);
356 charcnt
= __CFDetzcode(p
);
358 if (typecnt
<= 0 || timecnt
< 0 || charcnt
< 0) {
361 if (len
- (int32_t)sizeof(struct tzhead
) < (4 + 1) * timecnt
+ (4 + 1 + 1) * typecnt
+ charcnt
) {
365 typep
= timep
+ 4 * timecnt
;
366 ttisp
= typep
+ timecnt
;
367 charp
= ttisp
+ (4 + 1 + 1) * typecnt
;
368 cnt
= (0 < timecnt
) ? timecnt
: 1;
369 *tzpp
= CFAllocatorAllocate(allocator
, cnt
* sizeof(CFTZPeriod
), 0);
370 if (__CFOASafe
) __CFSetLastAllocationEventName(*tzpp
, "CFTimeZone (store)");
371 memset(*tzpp
, 0, cnt
* sizeof(CFTZPeriod
));
372 abbrs
= CFAllocatorAllocate(allocator
, (charcnt
+ 1) * sizeof(CFStringRef
), 0);
373 if (__CFOASafe
) __CFSetLastAllocationEventName(abbrs
, "CFTimeZone (temp)");
374 for (idx
= 0; idx
< charcnt
+ 1; idx
++) {
377 for (idx
= 0; idx
< cnt
; idx
++) {
379 int32_t itime
, offset
;
380 uint8_t type
, dst
, abbridx
;
382 at
= (CFAbsoluteTime
)(__CFDetzcode(timep
) + 0.0) - kCFAbsoluteTimeIntervalSince1970
;
383 if (0 == timecnt
) itime
= INT_MIN
;
384 else if (at
< (CFAbsoluteTime
)INT_MIN
) itime
= INT_MIN
;
385 else if ((CFAbsoluteTime
)INT_MAX
< at
) itime
= INT_MAX
;
386 else itime
= (int32_t)at
;
387 timep
+= 4; /* harmless if 0 == timecnt */
388 type
= (0 < timecnt
) ? (uint8_t)*typep
++ : 0;
389 if (typecnt
<= type
) {
393 offset
= __CFDetzcode(ttisp
+ 6 * type
);
394 dst
= (uint8_t)*(ttisp
+ 6 * type
+ 4);
395 if (0 != dst
&& 1 != dst
) {
399 abbridx
= (uint8_t)*(ttisp
+ 6 * type
+ 5);
400 if (charcnt
< abbridx
) {
404 if (NULL
== abbrs
[abbridx
]) {
405 abbrs
[abbridx
] = CFStringCreateWithCString(allocator
, &charp
[abbridx
], kCFStringEncodingASCII
);
407 __CFTZPeriodInit(*tzpp
+ idx
, itime
, abbrs
[abbridx
], offset
, (dst
? true : false));
409 for (idx
= 0; idx
< charcnt
+ 1; idx
++) {
410 if (NULL
!= abbrs
[idx
]) {
411 CFRelease(abbrs
[idx
]);
414 CFAllocatorDeallocate(allocator
, abbrs
);
416 // dump all but the last INT_MIN and the first INT_MAX
417 for (idx
= 0; idx
< cnt
; idx
++) {
418 if (((*tzpp
+ idx
)->startSec
== INT_MIN
) && (idx
+ 1 < cnt
) && (((*tzpp
+ idx
+ 1)->startSec
== INT_MIN
))) {
419 if (NULL
!= (*tzpp
+ idx
)->abbrev
) CFRelease((*tzpp
+ idx
)->abbrev
);
421 memmove((*tzpp
+ idx
), (*tzpp
+ idx
+ 1), sizeof(CFTZPeriod
) * (cnt
- idx
));
425 // Don't combine these loops! Watch the idx decrementing...
426 for (idx
= 0; idx
< cnt
; idx
++) {
427 if (((*tzpp
+ idx
)->startSec
== INT_MAX
) && (0 < idx
) && (((*tzpp
+ idx
- 1)->startSec
== INT_MAX
))) {
428 if (NULL
!= (*tzpp
+ idx
)->abbrev
) CFRelease((*tzpp
+ idx
)->abbrev
);
430 memmove((*tzpp
+ idx
), (*tzpp
+ idx
+ 1), sizeof(CFTZPeriod
) * (cnt
- idx
));
434 CFQSortArray(*tzpp
, cnt
, sizeof(CFTZPeriod
), __CFCompareTZPeriods
, NULL
);
437 CFAllocatorDeallocate(allocator
, *tzpp
);
442 /* We use Win32 function to find TimeZone
443 * (Aleksey Dukhnyakov)
445 *tzpp
= CFAllocatorAllocate(allocator
, sizeof(CFTZPeriod
), 0);
446 __CFTZPeriodInit(*tzpp
, 0, NULL
, 0, false);
452 static Boolean
__CFTimeZoneEqual(CFTypeRef cf1
, CFTypeRef cf2
) {
453 CFTimeZoneRef tz1
= (CFTimeZoneRef
)cf1
;
454 CFTimeZoneRef tz2
= (CFTimeZoneRef
)cf2
;
455 if (!CFEqual(CFTimeZoneGetName(tz1
), CFTimeZoneGetName(tz2
))) return false;
456 if (!CFEqual(CFTimeZoneGetData(tz1
), CFTimeZoneGetData(tz2
))) return false;
460 static CFHashCode
__CFTimeZoneHash(CFTypeRef cf
) {
461 CFTimeZoneRef tz
= (CFTimeZoneRef
)cf
;
462 return CFHash(CFTimeZoneGetName(tz
));
465 static CFStringRef
__CFTimeZoneCopyDescription(CFTypeRef cf
) {
466 CFTimeZoneRef tz
= (CFTimeZoneRef
)cf
;
467 CFStringRef result
, abbrev
;
469 at
= CFAbsoluteTimeGetCurrent();
470 abbrev
= CFTimeZoneCopyAbbreviation(tz
, at
);
471 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");
476 static void __CFTimeZoneDeallocate(CFTypeRef cf
) {
477 CFTimeZoneRef tz
= (CFTimeZoneRef
)cf
;
478 CFAllocatorRef allocator
= CFGetAllocator(tz
);
480 if (tz
->_name
) CFRelease(tz
->_name
);
481 if (tz
->_data
) CFRelease(tz
->_data
);
482 for (idx
= 0; idx
< tz
->_periodCnt
; idx
++) {
483 if (NULL
!= tz
->_periods
[idx
].abbrev
) CFRelease(tz
->_periods
[idx
].abbrev
);
485 if (NULL
!= tz
->_periods
) CFAllocatorDeallocate(allocator
, tz
->_periods
);
488 static CFTypeID __kCFTimeZoneTypeID
= _kCFRuntimeNotATypeID
;
490 static const CFRuntimeClass __CFTimeZoneClass
= {
495 __CFTimeZoneDeallocate
,
499 __CFTimeZoneCopyDescription
502 __private_extern__
void __CFTimeZoneInitialize(void) {
503 __kCFTimeZoneTypeID
= _CFRuntimeRegisterClass(&__CFTimeZoneClass
);
506 CFTypeID
CFTimeZoneGetTypeID(void) {
507 return __kCFTimeZoneTypeID
;
510 static CFTimeZoneRef
__CFTimeZoneCreateSystem(void) {
511 CFTimeZoneRef result
= NULL
;
512 #if defined(__WIN32__)
513 /* The GetTimeZoneInformation function retrieves the current
514 * time-zone parameters for Win32
515 * (Aleksey Dukhnyakov)
518 TIME_ZONE_INFORMATION tz
;
520 dw_result
=GetTimeZoneInformation(&tz
);
522 if ( dw_result
== TIME_ZONE_ID_STANDARD
||
523 dw_result
== TIME_ZONE_ID_DAYLIGHT
) {
524 CFStringRef name
= CFStringCreateWithCharacters(kCFAllocatorDefault
, tz
.StandardName
, wcslen(tz
.StandardName
));
525 data
= CFDataCreate(kCFAllocatorDefault
, (UInt8
*)&tz
, sizeof(tz
));
526 result
= CFTimeZoneCreate(kCFAllocatorSystemDefault
, name
, data
);
529 if (result
) return result
;
534 char linkbuf
[CFMaxPathSize
];
536 tzenv
= getenv("TZFILE");
538 CFStringRef name
= CFStringCreateWithBytes(kCFAllocatorDefault
, tzenv
, strlen(tzenv
), kCFStringEncodingUTF8
, false);
539 result
= CFTimeZoneCreateWithName(kCFAllocatorSystemDefault
, name
, false);
541 if (result
) return result
;
543 tzenv
= getenv("TZ");
545 CFStringRef name
= CFStringCreateWithBytes(kCFAllocatorDefault
, tzenv
, strlen(tzenv
), kCFStringEncodingUTF8
, false);
546 result
= CFTimeZoneCreateWithName(kCFAllocatorSystemDefault
, name
, true);
548 if (result
) return result
;
550 ret
= readlink(TZZONELINK
, linkbuf
, sizeof(linkbuf
));
554 if (strncmp(linkbuf
, TZZONEINFO
, sizeof(TZZONEINFO
) - 1) == 0) {
555 name
= CFStringCreateWithBytes(kCFAllocatorDefault
, linkbuf
+ sizeof(TZZONEINFO
) - 1, strlen(linkbuf
) - sizeof(TZZONEINFO
) + 1, kCFStringEncodingUTF8
, false);
557 name
= CFStringCreateWithBytes(kCFAllocatorDefault
, linkbuf
, strlen(linkbuf
), kCFStringEncodingUTF8
, false);
559 result
= CFTimeZoneCreateWithName(kCFAllocatorSystemDefault
, name
, false);
561 if (result
) return result
;
564 return CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorSystemDefault
, 0.0);
567 CFTimeZoneRef
CFTimeZoneCopySystem(void) {
569 __CFTimeZoneLockGlobal();
570 if (NULL
== __CFTimeZoneSystem
) {
571 __CFTimeZoneUnlockGlobal();
572 tz
= __CFTimeZoneCreateSystem();
573 __CFTimeZoneLockGlobal();
574 if (NULL
== __CFTimeZoneSystem
) {
575 __CFTimeZoneSystem
= tz
;
577 if (tz
) CFRelease(tz
);
580 tz
= __CFTimeZoneSystem
? CFRetain(__CFTimeZoneSystem
) : NULL
;
581 __CFTimeZoneUnlockGlobal();
585 void CFTimeZoneResetSystem(void) {
586 __CFTimeZoneLockGlobal();
587 if (__CFTimeZoneDefault
== __CFTimeZoneSystem
) {
588 if (__CFTimeZoneDefault
) CFRelease(__CFTimeZoneDefault
);
589 __CFTimeZoneDefault
= NULL
;
591 if (__CFTimeZoneSystem
) CFRelease(__CFTimeZoneSystem
);
592 __CFTimeZoneSystem
= NULL
;
593 __CFTimeZoneUnlockGlobal();
596 CFTimeZoneRef
CFTimeZoneCopyDefault(void) {
598 __CFTimeZoneLockGlobal();
599 if (NULL
== __CFTimeZoneDefault
) {
600 __CFTimeZoneUnlockGlobal();
601 tz
= CFTimeZoneCopySystem();
602 __CFTimeZoneLockGlobal();
603 if (NULL
== __CFTimeZoneDefault
) {
604 __CFTimeZoneDefault
= tz
;
606 if (tz
) CFRelease(tz
);
609 tz
= __CFTimeZoneDefault
? CFRetain(__CFTimeZoneDefault
) : NULL
;
610 __CFTimeZoneUnlockGlobal();
614 void CFTimeZoneSetDefault(CFTimeZoneRef tz
) {
615 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
616 __CFTimeZoneLockGlobal();
617 if (tz
!= __CFTimeZoneDefault
) {
618 if (tz
) CFRetain(tz
);
619 if (__CFTimeZoneDefault
) CFRelease(__CFTimeZoneDefault
);
620 __CFTimeZoneDefault
= tz
;
622 __CFTimeZoneUnlockGlobal();
625 static CFDictionaryRef
__CFTimeZoneCopyCompatibilityDictionary(void);
627 CFArrayRef
CFTimeZoneCopyKnownNames(void) {
629 __CFTimeZoneLockGlobal();
630 if (NULL
== __CFKnownTimeZoneList
) {
631 CFMutableArrayRef list
;
632 /* TimeZone information locate in the registry for Win32
633 * (Aleksey Dukhnyakov)
635 #if !defined(__WIN32__)
636 list
= __CFCopyRecursiveDirectoryList(TZZONEINFO
);
638 list
= __CFCopyWindowsTimeZoneList();
640 // Remove undesirable ancient cruft
641 CFDictionaryRef dict
= __CFTimeZoneCopyCompatibilityDictionary();
643 for (idx
= CFArrayGetCount(list
); idx
--; ) {
644 CFStringRef item
= CFArrayGetValueAtIndex(list
, idx
);
645 if (CFDictionaryContainsKey(dict
, item
)) {
646 CFArrayRemoveValueAtIndex(list
, idx
);
649 __CFKnownTimeZoneList
= CFArrayCreateCopy(kCFAllocatorSystemDefault
, list
);
652 tzs
= __CFKnownTimeZoneList
? CFRetain(__CFKnownTimeZoneList
) : NULL
;
653 __CFTimeZoneUnlockGlobal();
657 static const unsigned char *__CFTimeZoneAbbreviationDefaults
=
658 #if defined(__WIN32__)
660 * TimeZone abbreviations for Win32
661 * (Andrew Dzubandovsky)
664 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
665 " <!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">"
666 " <plist version=\"1.0\">"
668 " <key>AFG</key> <string>Afghanistan Standard Time</string>"
669 " <key>ALS</key> <string>Alaskan Standard Time</string>"
670 " <key>ARA</key> <string>Arab Standard Time</string>"
671 " <key>ARB</key> <string>Arabian Standard Time</string>"
672 " <key>ARC</key> <string>Arabic Standard Time</string>"
673 " <key>ATL</key> <string>Atlantic Standard Time</string>"
674 " <key>ASC</key> <string>AUS Central Standard Time</string>"
675 " <key>ASE</key> <string>AUS Eastern Standard Time</string>"
676 " <key>AZS</key> <string>Azores Standard Time</string>"
677 " <key>CND</key> <string>Canada Central Standard Time</string>"
678 " <key>CPV</key> <string>Cape Verde Standard Time</string>"
679 " <key>CCS</key> <string>Caucasus Standard Time</string>"
680 " <key>CNAS</key> <string>Cen. Australia Standard Time</string>"
681 " <key>CAMR</key> <string>Central America Standard Time</string>"
682 " <key>CAS</key> <string>Central Asia Standard Time</string>"
683 " <key>CER</key> <string>Central Europe Standard Time</string>"
684 " <key>CEPN</key> <string>Central European Standard Time</string>"
685 " <key>CPC</key> <string>Central Pacific Standard Time</string>"
686 " <key>CSTD</key> <string>Central Standard Time</string>"
687 " <key>CHN</key> <string>China Standard Time</string>"
688 " <key>DTLN</key> <string>Dateline Standard Time</string>"
689 " <key>EAFR</key> <string>E. Africa Standard Time</string>"
690 " <key>EAS</key> <string>E. Australia Standard Time</string>"
691 " <key>ERP</key> <string>E. Europe Standard Time</string>"
692 " <key>ESTH</key> <string>E. South America Standard Time</string>"
693 " <key>ESTM</key> <string>Eastern Standard Time</string>"
694 " <key>EGP</key> <string>Egypt Standard Time</string>"
695 " <key>EKT</key> <string>Ekaterinburg Standard Time</string>"
696 " <key>FST</key> <string>Fiji Standard Time</string>"
697 " <key>FLE</key> <string>FLE Standard Time</string>"
698 " <key>GMT</key> <string>GMT Standard Time</string>"
699 " <key>GRLD</key> <string>Greenland Standard Time</string>"
700 " <key>GRW</key> <string>Greenwich Standard Time</string>"
701 " <key>GTB</key> <string>GTB Standard Time</string>"
702 " <key>HWT</key> <string>Hawaiian Standard Time</string>"
703 " <key>INT</key> <string>India Standard Time</string>"
704 " <key>IRT</key> <string>Iran Standard Time</string>"
705 " <key>ISL</key> <string>Israel Standard Time</string>"
706 " <key>KRT</key> <string>Korea Standard Time</string>"
707 " <key>MXST</key> <string>Mexico Standard Time</string>"
708 " <key>MTL</key> <string>Mid-Atlantic Standard Time</string>"
709 " <key>MNT</key> <string>Mountain Standard Time</string>"
710 " <key>MNM</key> <string>Myanmar Standard Time</string>"
711 " <key>NCNA</key> <string>N. Central Asia Standard Time</string>"
712 " <key>MPL</key> <string>Nepal Standard Time</string>"
713 " <key>NWZ</key> <string>New Zealand Standard Time</string>"
714 " <key>NWF</key> <string>Newfoundland Standard Time</string>"
715 " <key>NTAE</key> <string>North Asia East Standard Time</string>"
716 " <key>NTAS</key> <string>North Asia Standard Time</string>"
717 " <key>HSAT</key> <string>Pacific SA Standard Time</string>"
718 " <key>PST</key> <string>Pacific Standard Time</string>"
719 " <key>RMC</key> <string>Romance Standard Time</string>"
720 " <key>MSK</key> <string>Russian Standard Time</string>"
721 " <key>SSS</key> <string>SA Eastern Standard Time</string>"
722 " <key>SPS</key> <string>SA Pacific Standard Time</string>"
723 " <key>SWS</key> <string>SA Western Standard Time</string>"
724 " <key>SMS</key> <string>Samoa Standard Time</string>"
725 " <key>SAS</key> <string>SE Asia Standard Time</string>"
726 " <key>SNG</key> <string>Singapore Standard Time</string>"
727 " <key>STAF</key> <string>South Africa Standard Time</string>"
728 " <key>SRLK</key> <string>Sri Lanka Standard Time</string>"
729 " <key>TPS</key> <string>Taipei Standard Time</string>"
730 " <key>TSM</key> <string>Tasmania Standard Time</string>"
731 " <key>JPN</key> <string>Tokyo Standard Time</string>"
732 " <key>TNG</key> <string>Tonga Standard Time</string>"
733 " <key>AEST</key> <string>US Eastern Standard Time</string>"
734 " <key>AMST</key> <string>US Mountain Standard Time</string>"
735 " <key>VLD</key> <string>Vladivostok Standard Time</string>"
736 " <key>AUSW</key> <string>W. Australia Standard Time</string>"
737 " <key>AFCW</key> <string>W. Central Africa Standard Time</string>"
738 " <key>EWS</key> <string>W. Europe Standard Time</string>"
739 " <key>ASW</key> <string>West Asia Standard Time</string>"
740 " <key>PWS</key> <string>West Pacific Standard Time</string>"
741 " <key>RKS</key> <string>Yakutsk Standard Time</string>"
745 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
746 " <!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">"
747 " <plist version=\"1.0\">"
749 " <key>ADT</key> <string>America/Halifax</string>"
750 " <key>AFT</key> <string>Asia/Kabul</string>"
751 " <key>AKDT</key> <string>America/Juneau</string>"
752 " <key>AKST</key> <string>America/Juneau</string>"
753 " <key>AST</key> <string>America/Halifax</string>"
754 " <key>CDT</key> <string>America/Chicago</string>"
755 " <key>CEST</key> <string>Europe/Rome</string>"
756 " <key>CET</key> <string>Europe/Rome</string>"
757 " <key>CST</key> <string>America/Chicago</string>"
758 " <key>EDT</key> <string>America/New_York</string>"
759 " <key>EEST</key> <string>Europe/Warsaw</string>"
760 " <key>EET</key> <string>Europe/Warsaw</string>"
761 " <key>EST</key> <string>America/New_York</string>"
762 " <key>GMT</key> <string>GMT</string>"
763 " <key>HKST</key> <string>Asia/Hong_Kong</string>"
764 " <key>HST</key> <string>Pacific/Honolulu</string>"
765 " <key>JST</key> <string>Asia/Tokyo</string>"
766 " <key>MDT</key> <string>America/Denver</string>"
767 " <key>MSD</key> <string>Europe/Moscow</string>"
768 " <key>MSK</key> <string>Europe/Moscow</string>"
769 " <key>MST</key> <string>America/Denver</string>"
770 " <key>NZDT</key> <string>Pacific/Auckland</string>"
771 " <key>NZST</key> <string>Pacific/Auckland</string>"
772 " <key>PDT</key> <string>America/Los_Angeles</string>"
773 " <key>PST</key> <string>America/Los_Angeles</string>"
774 " <key>UTC</key> <string>UTC</string>"
775 " <key>WEST</key> <string>Europe/Paris</string>"
776 " <key>WET</key> <string>Europe/Paris</string>"
777 " <key>YDT</key> <string>America/Yakutat</string>"
778 " <key>YST</key> <string>America/Yakutat</string>"
783 CFDictionaryRef
CFTimeZoneCopyAbbreviationDictionary(void) {
784 CFDictionaryRef dict
;
785 __CFTimeZoneLockAbbreviations();
786 if (NULL
== __CFTimeZoneAbbreviationDict
) {
787 CFDataRef data
= CFDataCreate(kCFAllocatorDefault
, __CFTimeZoneAbbreviationDefaults
, strlen(__CFTimeZoneAbbreviationDefaults
));
788 __CFTimeZoneAbbreviationDict
= CFPropertyListCreateFromXMLData(kCFAllocatorDefault
, data
, kCFPropertyListImmutable
, NULL
);
791 if (NULL
== __CFTimeZoneAbbreviationDict
) {
792 __CFTimeZoneAbbreviationDict
= CFDictionaryCreate(kCFAllocatorDefault
, NULL
, NULL
, 0, NULL
, NULL
);
794 dict
= __CFTimeZoneAbbreviationDict
? CFRetain(__CFTimeZoneAbbreviationDict
) : NULL
;
795 __CFTimeZoneUnlockAbbreviations();
799 void CFTimeZoneSetAbbreviationDictionary(CFDictionaryRef dict
) {
800 __CFGenericValidateType(dict
, CFDictionaryGetTypeID());
801 __CFTimeZoneLockGlobal();
802 if (dict
!= __CFTimeZoneAbbreviationDict
) {
803 if (dict
) CFRetain(dict
);
804 if (__CFTimeZoneAbbreviationDict
) CFRelease(__CFTimeZoneAbbreviationDict
);
805 __CFTimeZoneAbbreviationDict
= dict
;
807 __CFTimeZoneUnlockGlobal();
810 CFTimeZoneRef
CFTimeZoneCreate(CFAllocatorRef allocator
, CFStringRef name
, CFDataRef data
) {
811 // assert: (NULL != name && NULL != data);
812 CFTimeZoneRef memory
;
817 if (allocator
== NULL
) allocator
= __CFGetDefaultAllocator();
818 __CFGenericValidateType(allocator
, CFAllocatorGetTypeID());
819 __CFGenericValidateType(name
, CFStringGetTypeID());
820 __CFGenericValidateType(data
, CFDataGetTypeID());
821 __CFTimeZoneLockGlobal();
822 if (NULL
!= __CFTimeZoneCache
&& CFDictionaryGetValueIfPresent(__CFTimeZoneCache
, name
, (const void **)&memory
)) {
823 __CFTimeZoneUnlockGlobal();
824 return (CFTimeZoneRef
)CFRetain(memory
);
826 if (!__CFParseTimeZoneData(allocator
, data
, &tzp
, &cnt
)) {
827 __CFTimeZoneUnlockGlobal();
830 size
= sizeof(struct __CFTimeZone
) - sizeof(CFRuntimeBase
);
831 memory
= _CFRuntimeCreateInstance(allocator
, __kCFTimeZoneTypeID
, size
, NULL
);
832 if (NULL
== memory
) {
833 __CFTimeZoneUnlockGlobal();
834 for (idx
= 0; idx
< cnt
; idx
++) {
835 if (NULL
!= tzp
[idx
].abbrev
) CFRelease(tzp
[idx
].abbrev
);
837 if (NULL
!= tzp
) CFAllocatorDeallocate(allocator
, tzp
);
840 ((struct __CFTimeZone
*)memory
)->_name
= CFStringCreateCopy(allocator
, name
);
841 ((struct __CFTimeZone
*)memory
)->_data
= CFDataCreateCopy(allocator
, data
);
842 ((struct __CFTimeZone
*)memory
)->_periods
= tzp
;
843 ((struct __CFTimeZone
*)memory
)->_periodCnt
= cnt
;
844 if (NULL
== __CFTimeZoneCache
) {
845 CFDictionaryKeyCallBacks kcb
= kCFTypeDictionaryKeyCallBacks
;
846 kcb
.retain
= kcb
.release
= NULL
;
847 __CFTimeZoneCache
= CFDictionaryCreateMutable(kCFAllocatorSystemDefault
, 0, &kcb
, &kCFTypeDictionaryValueCallBacks
);
849 CFDictionaryAddValue(__CFTimeZoneCache
, ((struct __CFTimeZone
*)memory
)->_name
, memory
);
850 __CFTimeZoneUnlockGlobal();
854 #if !defined(__WIN32__)
855 static CFTimeZoneRef
__CFTimeZoneCreateFixed(CFAllocatorRef allocator
, int32_t seconds
, CFStringRef name
, int isDST
) {
856 CFTimeZoneRef result
;
858 int32_t nameLen
= CFStringGetLength(name
);
859 #if defined(__WIN32__)
860 unsigned char *dataBytes
= CFAllocatorAllocate(allocator
, 52 + nameLen
+ 1, 0);
861 if (!dataBytes
) return NULL
;
862 if (__CFOASafe
) __CFSetLastAllocationEventName(dataBytes
, "CFTimeZone (temp)");
864 unsigned char dataBytes
[52 + nameLen
+ 1];
866 memset(dataBytes
, 0, sizeof(dataBytes
));
868 // Put in correct magic bytes for timezone structures
874 __CFEntzcode(1, dataBytes
+ 20);
875 __CFEntzcode(1, dataBytes
+ 24);
876 __CFEntzcode(1, dataBytes
+ 36);
877 __CFEntzcode(nameLen
+ 1, dataBytes
+ 40);
878 __CFEntzcode(seconds
, dataBytes
+ 44);
879 dataBytes
[48] = isDST
? 1 : 0;
880 CFStringGetCString(name
, dataBytes
+ 50, nameLen
+ 1, kCFStringEncodingASCII
);
881 data
= CFDataCreate(allocator
, dataBytes
, 52 + nameLen
+ 1);
882 result
= CFTimeZoneCreate(allocator
, name
, data
);
884 #if defined(__WIN32__)
885 CFAllocatorDeallocate(allocator
, dataBytes
);
891 // rounds offset to nearest minute
892 CFTimeZoneRef
CFTimeZoneCreateWithTimeIntervalFromGMT(CFAllocatorRef allocator
, CFTimeInterval ti
) {
893 CFTimeZoneRef result
;
895 int32_t seconds
, minute
, hour
;
896 if (allocator
== NULL
) allocator
= __CFGetDefaultAllocator();
897 __CFGenericValidateType(allocator
, CFAllocatorGetTypeID());
898 if (ti
< -18.0 * 3600 || 18.0 * 3600 < ti
) return NULL
;
899 ti
= (ti
< 0.0) ? ceil((ti
/ 60.0) - 0.5) * 60.0 : floor((ti
/ 60.0) + 0.5) * 60.0;
900 seconds
= (int32_t)ti
;
901 hour
= (ti
< 0) ? (-seconds
/ 3600) : (seconds
/ 3600);
902 seconds
-= ((ti
< 0) ? -hour
: hour
) * 3600;
903 minute
= (ti
< 0) ? (-seconds
/ 60) : (seconds
/ 60);
904 if (fabs(ti
) < 1.0) {
905 name
= CFRetain(CFSTR("GMT"));
907 name
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("GMT%c%02d%02d"), (ti
< 0.0 ? '-' : '+'), hour
, minute
);
909 #if !defined(__WIN32__)
910 result
= __CFTimeZoneCreateFixed(allocator
, (int32_t)ti
, name
, 0);
912 /* CFTimeZoneRef->_data will contain TIME_ZONE_INFORMATION structure
913 * to find current timezone
914 * (Aleksey Dukhnyakov)
917 TIME_ZONE_INFORMATION tzi
;
919 CFIndex length
= CFStringGetLength(name
);
921 memset(&tzi
,0,sizeof(tzi
));
922 tzi
.Bias
=(long)(-ti
/60);
923 CFStringGetCharacters(name
, CFRangeMake(0, length
< 31 ? length
: 31 ), tzi
.StandardName
);
924 data
= CFDataCreate(allocator
,(UInt8
*)&tzi
, sizeof(tzi
));
925 result
= CFTimeZoneCreate(allocator
, name
, data
);
933 CFTimeZoneRef
CFTimeZoneCreateWithName(CFAllocatorRef allocator
, CFStringRef name
, Boolean tryAbbrev
) {
934 CFTimeZoneRef result
= NULL
;
935 CFStringRef tzName
= NULL
;
936 CFDataRef data
= NULL
;
938 if (allocator
== NULL
) allocator
= __CFGetDefaultAllocator();
939 __CFGenericValidateType(allocator
, CFAllocatorGetTypeID());
940 __CFGenericValidateType(name
, CFStringGetTypeID());
941 if (CFEqual(CFSTR(""), name
)) {
942 // empty string is not a time zone name, just abort now,
943 // following stuff will fail anyway
946 __CFTimeZoneLockGlobal();
947 if (NULL
!= __CFTimeZoneCache
&& CFDictionaryGetValueIfPresent(__CFTimeZoneCache
, name
, (const void **)&result
)) {
948 __CFTimeZoneUnlockGlobal();
949 return (CFTimeZoneRef
)CFRetain(result
);
951 __CFTimeZoneUnlockGlobal();
952 #if !defined(__WIN32__)
953 CFURLRef baseURL
, tempURL
;
957 baseURL
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, CFSTR(TZZONEINFO
), kCFURLPOSIXPathStyle
, true);
959 CFDictionaryRef abbrevs
= CFTimeZoneCopyAbbreviationDictionary();
960 tzName
= CFDictionaryGetValue(abbrevs
, name
);
961 if (NULL
!= tzName
) {
962 tempURL
= CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault
, baseURL
, tzName
, false);
963 if (NULL
!= tempURL
) {
964 if (_CFReadBytesFromFile(kCFAllocatorDefault
, tempURL
, &bytes
, &length
, 0)) {
965 data
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, bytes
, length
, kCFAllocatorDefault
);
973 CFDictionaryRef dict
= __CFTimeZoneCopyCompatibilityDictionary();
974 CFStringRef mapping
= CFDictionaryGetValue(dict
, name
);
977 } else if (CFStringHasPrefix(name
, CFSTR(TZZONEINFO
))) {
978 CFMutableStringRef unprefixed
= CFStringCreateMutableCopy(kCFAllocatorDefault
, CFStringGetLength(name
), name
);
979 CFStringDelete(unprefixed
, CFRangeMake(0, sizeof(TZZONEINFO
)));
980 mapping
= CFDictionaryGetValue(dict
, unprefixed
);
984 CFRelease(unprefixed
);
987 if (CFEqual(CFSTR(""), name
)) {
993 tempURL
= CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault
, baseURL
, tzName
, false);
994 if (NULL
!= tempURL
) {
995 if (_CFReadBytesFromFile(kCFAllocatorDefault
, tempURL
, &bytes
, &length
, 0)) {
996 data
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, bytes
, length
, kCFAllocatorDefault
);
1004 tempURL
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, tzName
, kCFURLPOSIXPathStyle
, false);
1005 if (NULL
!= tempURL
) {
1006 if (_CFReadBytesFromFile(kCFAllocatorDefault
, tempURL
, &bytes
, &length
, 0)) {
1007 data
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, bytes
, length
, kCFAllocatorDefault
);
1013 result
= CFTimeZoneCreate(allocator
, tzName
, data
);
1017 /* Reading GMT offset and daylight flag from the registry
1019 * (Aleksey Dukhnyakov)
1022 CFStringRef safeName
= name
;
1027 SYSTEMTIME StandardDate
;
1028 SYSTEMTIME DaylightDate
;
1030 TIME_ZONE_INFORMATION tzi_system
;
1033 DWORD dwType
, dwSize
=sizeof(tzi
),
1034 dwSize_name1
=sizeof(tzi_system
.StandardName
),
1035 dwSize_name2
=sizeof(tzi_system
.DaylightName
);
1038 CFDictionaryRef abbrevs
= CFTimeZoneCopyAbbreviationDictionary();
1039 tzName
= CFDictionaryGetValue(abbrevs
, name
);
1040 if (NULL
== tzName
) {
1047 /* Open regestry and move down to the TimeZone information
1049 if (RegOpenKey(HKEY_LOCAL_MACHINE
,_T(TZZONEINFO
),&hkResult
) !=
1053 /* Move down to specific TimeZone name
1055 #if defined(UNICODE)
1056 if (RegOpenKey(hkResult
,CFStringGetCharactersPtr(name
) ,&hkResult
) !=
1059 if (RegOpenKey(hkResult
,CFStringGetCStringPtr(name
, CFStringGetSystemEncoding()),&hkResult
) != ERROR_SUCCESS
) {
1063 /* TimeZone information(offsets, daylight flag, ...) assign to tzi structure
1065 if ( RegQueryValueEx(hkResult
,_T("TZI"),NULL
,&dwType
,(LPBYTE
)&tzi
,&dwSize
) != ERROR_SUCCESS
&&
1066 RegQueryValueEx(hkResult
,_T("Std"),NULL
,&dwType
,(LPBYTE
)&tzi_system
.StandardName
,&dwSize_name1
) != ERROR_SUCCESS
&&
1067 RegQueryValueEx(hkResult
,_T("Dlt"),NULL
,&dwType
,(LPBYTE
)&tzi_system
.DaylightName
,&dwSize_name2
) != ERROR_SUCCESS
)
1072 tzi_system
.Bias
=tzi
.Bias
;
1073 tzi_system
.StandardBias
=tzi
.StandardBias
;
1074 tzi_system
.DaylightBias
=tzi
.DaylightBias
;
1075 tzi_system
.StandardDate
=tzi
.StandardDate
;
1076 tzi_system
.DaylightDate
=tzi
.DaylightDate
;
1078 /* CFTimeZoneRef->_data will contain TIME_ZONE_INFORMATION structure
1079 * to find current timezone
1080 * (Aleksey Dukhnyakov)
1082 data
= CFDataCreate(allocator
,(UInt8
*)&tzi_system
, sizeof(tzi_system
));
1084 RegCloseKey(hkResult
);
1085 result
= CFTimeZoneCreate(allocator
, name
, data
);
1088 result
->_periods
->abbrev
= CFStringCreateCopy(allocator
,safeName
);
1098 CFStringRef
CFTimeZoneGetName(CFTimeZoneRef tz
) {
1099 CF_OBJC_FUNCDISPATCH0(__kCFTimeZoneTypeID
, CFStringRef
, tz
, "name");
1100 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1104 CFDataRef
CFTimeZoneGetData(CFTimeZoneRef tz
) {
1105 CF_OBJC_FUNCDISPATCH0(__kCFTimeZoneTypeID
, CFDataRef
, tz
, "data");
1106 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1110 /* This function converts CFAbsoluteTime to (Win32) SYSTEMTIME
1111 * (Aleksey Dukhnyakov)
1113 #if defined(__WIN32__)
1114 BOOL
__CFTimeZoneGetWin32SystemTime(SYSTEMTIME
* sys_time
, CFAbsoluteTime time
)
1117 FILETIME
* ftime
=(FILETIME
*)&l
;
1119 /* seconds between 1601 and 1970 : 11644473600,
1120 * seconds between 1970 and 2001 : 978307200,
1121 * FILETIME - number of 100-nanosecond intervals since January 1, 1601
1123 l
=(time
+11644473600LL+978307200)*10000000;
1124 if (FileTimeToSystemTime(ftime
,sys_time
))
1131 CFTimeInterval
_CFTimeZoneGetDSTOffset(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1132 #if !defined(__WIN32__)
1133 // #warning this does not work for non-CFTimeZoneRefs
1135 idx
= __CFBSearchTZPeriods(tz
, at
);
1136 // idx 0 is never returned if it is in DST
1137 if (__CFTZPeriodIsDST(&(tz
->_periods
[idx
]))) {
1138 return __CFTZPeriodGMTOffset(&(tz
->_periods
[idx
])) - __CFTZPeriodGMTOffset(&(tz
->_periods
[idx
- 1]));
1144 // returns 0.0 if there is no data for the next switch after 'at'
1145 CFAbsoluteTime
_CFTimeZoneGetNextDSTSwitch(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1146 #if !defined(__WIN32__)
1147 // #warning this does not work for non-CFTimeZoneRefs
1149 idx
= __CFBSearchTZPeriods(tz
, at
);
1150 if (tz
->_periodCnt
<= idx
+ 1) {
1153 return (CFAbsoluteTime
)__CFTZPeriodStartSeconds(&(tz
->_periods
[idx
+ 1]));
1158 CFTimeInterval
CFTimeZoneGetSecondsFromGMT(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1159 #if !defined(__WIN32__)
1161 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, CFTimeInterval
, tz
, "_secondsFromGMTForAbsoluteTime:", at
);
1162 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1163 idx
= __CFBSearchTZPeriods(tz
, at
);
1164 return __CFTZPeriodGMTOffset(&(tz
->_periods
[idx
]));
1166 /* To calculate seconds from GMT, calculate current timezone time and
1167 * subtract GMT timnezone time
1168 * (Aleksey Dukhnyakov)
1170 TIME_ZONE_INFORMATION tzi
;
1171 FILETIME ftime1
,ftime2
;
1172 SYSTEMTIME stime0
,stime1
,stime2
;
1173 LONGLONG
* l1
= (LONGLONG
*)&ftime1
;
1174 LONGLONG
* l2
= (LONGLONG
*)&ftime2
;
1175 CFRange range
={0,sizeof(TIME_ZONE_INFORMATION
)};
1178 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, CFTimeInterval
, tz
, "_secondsFromGMTForAbsoluteTime:", at
);
1180 CFDataGetBytes(tz
->_data
,range
,(UInt8
*)&tzi
);
1182 if (!__CFTimeZoneGetWin32SystemTime(&stime0
,at
) ||
1183 !SystemTimeToTzSpecificLocalTime(&tzi
,&stime0
,&stime1
) ||
1184 !SystemTimeToFileTime(&stime1
,&ftime1
) )
1186 CFAssert(0, __kCFLogAssertion
, "Win32 system time/timezone failed !\n");
1190 tzi
.DaylightDate
.wMonth
=0;
1191 tzi
.StandardDate
.wMonth
=0;
1196 if ( !SystemTimeToTzSpecificLocalTime(&tzi
,&stime0
,&stime2
) ||
1197 !SystemTimeToFileTime(&stime2
,&ftime2
))
1199 CFAssert(0, __kCFLogAssertion
, "Win32 system time/timezone failed !\n");
1202 result
=(double)((*l1
-*l2
)/10000000);
1207 #if defined(__WIN32__)
1209 * Get abbreviation for name for WIN32 platform
1210 * (Aleksey Dukhnyakov)
1218 static void _CFFindKeyForValue(const void *key
, const void *value
, void *context
) {
1219 if ( ((_CFAbbrFind
*)context
)->tzAbbr
!= NULL
) {
1220 if ( ((_CFAbbrFind
*)context
)->tzName
== (CFStringRef
) value
) {
1221 ((_CFAbbrFind
*)context
)->tzAbbr
= key
;
1226 CFIndex
__CFTimeZoneInitAbbrev(CFTimeZoneRef tz
) {
1228 if ( tz
->_periods
->abbrev
== NULL
) {
1229 _CFAbbrFind abbr
= { NULL
, NULL
};
1230 CFDictionaryRef abbrevs
= CFTimeZoneCopyAbbreviationDictionary();
1232 CFDictionaryApplyFunction(abbrevs
, _CFFindKeyForValue
, &abbr
);
1234 if ( abbr
.tzAbbr
!= NULL
)
1235 tz
->_periods
->abbrev
= CFStringCreateCopy(kCFAllocatorDefault
, abbr
.tzAbbr
);
1237 tz
->_periods
->abbrev
= CFStringCreateCopy(kCFAllocatorDefault
, tz
->_name
);
1238 /* We should return name of TimeZone if couldn't find abbrevation.
1241 * old line : tz->_periods->abbrev =
1242 * CFStringCreateWithCString(kCFAllocatorDefault,"UNKNOWN",
1243 * CFStringGetSystemEncoding());
1245 * (Aleksey Dukhnyakov)
1247 CFRelease( abbrevs
);
1254 CFStringRef
CFTimeZoneCopyAbbreviation(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1257 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, CFStringRef
, tz
, "_abbreviationForAbsoluteTime:", at
);
1258 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1259 #if !defined(__WIN32__)
1260 idx
= __CFBSearchTZPeriods(tz
, at
);
1263 * Initialize abbreviation for this TimeZone
1264 * (Aleksey Dukhnyakov)
1266 idx
= __CFTimeZoneInitAbbrev(tz
);
1268 result
= __CFTZPeriodAbbreviation(&(tz
->_periods
[idx
]));
1269 return result
? CFRetain(result
) : NULL
;
1272 Boolean
CFTimeZoneIsDaylightSavingTime(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1273 #if !defined(__WIN32__)
1275 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, Boolean
, tz
, "_isDaylightSavingTimeForAbsoluteTime:", at
);
1276 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1277 idx
= __CFBSearchTZPeriods(tz
, at
);
1278 return __CFTZPeriodIsDST(&(tz
->_periods
[idx
]));
1280 /* Compare current timezone time and current timezone time without
1281 * transition to day light saving time
1282 * (Aleskey Dukhnyakov)
1284 TIME_ZONE_INFORMATION tzi
;
1285 SYSTEMTIME stime0
,stime1
,stime2
;
1286 CFRange range
={0,sizeof(TIME_ZONE_INFORMATION
)};
1288 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, Boolean
, tz
, "_isDaylightSavingTimeForAbsoluteTime:", at
);
1290 CFDataGetBytes(tz
->_data
,range
,(UInt8
*)&tzi
);
1292 if ( !__CFTimeZoneGetWin32SystemTime(&stime0
,at
) ||
1293 !SystemTimeToTzSpecificLocalTime(&tzi
,&stime0
,&stime1
)) {
1294 CFAssert(0, __kCFLogAssertion
, "Win32 system time/timezone failed !\n");
1298 tzi
.DaylightDate
.wMonth
=0;
1299 tzi
.StandardDate
.wMonth
=0;
1301 if ( !SystemTimeToTzSpecificLocalTime(&tzi
,&stime0
,&stime2
)) {
1302 CFAssert(0, __kCFLogAssertion
, "Win32 system time/timezone failed !\n");
1306 if ( !memcmp(&stime1
,&stime2
,sizeof(stime1
)) )
1313 CFTimeInterval
_CFTimeZoneGetDSTDelta(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1315 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1316 idx
= __CFBSearchTZPeriods(tz
, at
);
1317 CFTimeInterval delta
= __CFTZPeriodGMTOffset(&(tz
->_periods
[idx
]));
1318 if (idx
+ 1 < tz
->_periodCnt
) {
1319 return fabs(delta
- __CFTZPeriodGMTOffset(&(tz
->_periods
[idx
+ 1])));
1320 } else if (0 < idx
) {
1321 return fabs(delta
- __CFTZPeriodGMTOffset(&(tz
->_periods
[idx
- 1])));
1326 static CFDictionaryRef
__CFTimeZoneCopyCompatibilityDictionary(void) {
1327 CFDictionaryRef dict
;
1328 __CFTimeZoneLockCompatibilityMapping();
1329 if (NULL
== __CFTimeZoneCompatibilityMappingDict
) {
1330 __CFTimeZoneCompatibilityMappingDict
= CFDictionaryCreateMutable(kCFAllocatorSystemDefault
, 112, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1332 // Empty string means delete/ignore these
1333 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Factory"), CFSTR(""));
1334 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/Pacific-New"), CFSTR(""));
1335 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Mideast/Riyadh87"), CFSTR(""));
1336 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Mideast/Riyadh88"), CFSTR(""));
1337 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Mideast/Riyadh89"), CFSTR(""));
1338 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/AST4"), CFSTR(""));
1339 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/AST4ADT"), CFSTR(""));
1340 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/CST6"), CFSTR(""));
1341 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/CST6CDT"), CFSTR(""));
1342 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/EST5"), CFSTR(""));
1343 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/EST5EDT"), CFSTR(""));
1344 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/HST10"), CFSTR(""));
1345 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/MST7"), CFSTR(""));
1346 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/MST7MDT"), CFSTR(""));
1347 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/PST8"), CFSTR(""));
1348 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/PST8PDT"), CFSTR(""));
1349 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/YST9"), CFSTR(""));
1350 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("SystemV/YST9YDT"), CFSTR(""));
1352 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Atka"), CFSTR("America/Adak"));
1353 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Ensenada"), CFSTR("America/Tijuana"));
1354 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Fort_Wayne"), CFSTR("America/Indianapolis"));
1355 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Indiana/Indianapolis"), CFSTR("America/Indianapolis"));
1356 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Kentucky/Louisville"), CFSTR("America/Louisville"));
1357 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Knox_IN"), CFSTR("America/Indiana/Knox"));
1358 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Porto_Acre"), CFSTR("America/Rio_Branco"));
1359 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Rosario"), CFSTR("America/Cordoba"));
1360 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Shiprock"), CFSTR("America/Denver"));
1361 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("America/Virgin"), CFSTR("America/St_Thomas"));
1362 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Antarctica/South_Pole"), CFSTR("Antarctica/McMurdo"));
1363 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Asia/Ashkhabad"), CFSTR("Asia/Ashgabat"));
1364 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Asia/Chungking"), CFSTR("Asia/Chongqing"));
1365 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Asia/Macao"), CFSTR("Asia/Macau"));
1366 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Asia/Tel_Aviv"), CFSTR("Asia/Jerusalem"));
1367 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Asia/Thimbu"), CFSTR("Asia/Thimphu"));
1368 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Asia/Ujung_Pandang"), CFSTR("Asia/Makassar"));
1369 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Asia/Ulan_Bator"), CFSTR("Asia/Ulaanbaatar"));
1370 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/ACT"), CFSTR("Australia/Sydney"));
1371 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/LHI"), CFSTR("Australia/Lord_Howe"));
1372 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/NSW"), CFSTR("Australia/Sydney"));
1373 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/North"), CFSTR("Australia/Darwin"));
1374 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/Queensland"), CFSTR("Australia/Brisbane"));
1375 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/South"), CFSTR("Australia/Adelaide"));
1376 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/Tasmania"), CFSTR("Australia/Hobart"));
1377 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/Victoria"), CFSTR("Australia/Melbourne"));
1378 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/West"), CFSTR("Australia/Perth"));
1379 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Australia/Yancowinna"), CFSTR("Australia/Broken_Hill"));
1380 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Brazil/Acre"), CFSTR("America/Porto_Acre"));
1381 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Brazil/DeNoronha"), CFSTR("America/Noronha"));
1382 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Brazil/West"), CFSTR("America/Manaus"));
1383 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("CST6CDT"), CFSTR("America/Chicago"));
1384 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Canada/Central"), CFSTR("America/Winnipeg"));
1385 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Canada/East-Saskatchewan"), CFSTR("America/Regina"));
1386 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Canada/Pacific"), CFSTR("America/Vancouver"));
1387 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Canada/Yukon"), CFSTR("America/Whitehorse"));
1388 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Chile/Continental"), CFSTR("America/Santiago"));
1389 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Chile/EasterIsland"), CFSTR("Pacific/Easter"));
1390 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Cuba"), CFSTR("America/Havana"));
1391 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("EST5EDT"), CFSTR("America/New_York"));
1392 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Egypt"), CFSTR("Africa/Cairo"));
1393 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Eire"), CFSTR("Europe/Dublin"));
1394 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Etc/GMT+0"), CFSTR("GMT"));
1395 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Etc/GMT-0"), CFSTR("GMT"));
1396 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Etc/GMT0"), CFSTR("GMT"));
1397 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Etc/Greenwich"), CFSTR("GMT"));
1398 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Etc/Universal"), CFSTR("UTC"));
1399 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Etc/Zulu"), CFSTR("UTC"));
1400 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Europe/Nicosia"), CFSTR("Asia/Nicosia"));
1401 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Europe/Tiraspol"), CFSTR("Europe/Chisinau"));
1402 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("GB-Eire"), CFSTR("Europe/London"));
1403 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("GB"), CFSTR("Europe/London"));
1404 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("GMT+0"), CFSTR("GMT"));
1405 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("GMT-0"), CFSTR("GMT"));
1406 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("GMT0"), CFSTR("GMT"));
1407 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Greenwich"), CFSTR("GMT"));
1408 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Hongkong"), CFSTR("Asia/Hong_Kong"));
1409 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Iceland"), CFSTR("Atlantic/Reykjavik"));
1410 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Iran"), CFSTR("Asia/Tehran"));
1411 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Israel"), CFSTR("Asia/Jerusalem"));
1412 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Jamaica"), CFSTR("America/Jamaica"));
1413 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Kwajalein"), CFSTR("Pacific/Kwajalein"));
1414 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Libya"), CFSTR("Africa/Tripoli"));
1415 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("MST7MDT"), CFSTR("America/Denver"));
1416 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Mexico/BajaNorte"), CFSTR("America/Tijuana"));
1417 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Mexico/BajaSur"), CFSTR("America/Mazatlan"));
1418 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Mexico/General"), CFSTR("America/Mexico_City"));
1419 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("NZ-CHAT"), CFSTR("Pacific/Chatham"));
1420 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("NZ"), CFSTR("Pacific/Auckland"));
1421 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Navajo"), CFSTR("America/Denver"));
1422 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("PRC"), CFSTR("Asia/Shanghai"));
1423 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("PST8PDT"), CFSTR("America/Los_Angeles"));
1424 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Pacific/Samoa"), CFSTR("Pacific/Pago_Pago"));
1425 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Poland"), CFSTR("Europe/Warsaw"));
1426 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Portugal"), CFSTR("Europe/Lisbon"));
1427 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("ROC"), CFSTR("Asia/Taipei"));
1428 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("ROK"), CFSTR("Asia/Seoul"));
1429 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Singapore"), CFSTR("Asia/Singapore"));
1430 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Turkey"), CFSTR("Europe/Istanbul"));
1431 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("UCT"), CFSTR("UTC"));
1432 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/Alaska"), CFSTR("America/Anchorage"));
1433 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/Aleutian"), CFSTR("America/Adak"));
1434 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/Arizona"), CFSTR("America/Phoenix"));
1435 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/East-Indiana"), CFSTR("America/Indianapolis"));
1436 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/Hawaii"), CFSTR("Pacific/Honolulu"));
1437 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/Indiana-Starke"), CFSTR("America/Indiana/Knox"));
1438 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/Michigan"), CFSTR("America/Detroit"));
1439 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("US/Samoa"), CFSTR("Pacific/Pago_Pago"));
1440 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Universal"), CFSTR("UTC"));
1441 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("W-SU"), CFSTR("Europe/Moscow"));
1442 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict
, CFSTR("Zulu"), CFSTR("UTC"));
1444 dict
= __CFTimeZoneCompatibilityMappingDict
? CFRetain(__CFTimeZoneCompatibilityMappingDict
) : NULL
;
1445 __CFTimeZoneUnlockCompatibilityMapping();
1449 __private_extern__ CFDictionaryRef
__CFTimeZoneCopyCompatibilityDictionary2(void) {
1450 CFDictionaryRef dict
;
1451 __CFTimeZoneLockCompatibilityMapping();
1452 if (NULL
== __CFTimeZoneCompatibilityMappingDict2
) {
1453 __CFTimeZoneCompatibilityMappingDict2
= CFDictionaryCreateMutable(kCFAllocatorSystemDefault
, 16, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
1454 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Asia/Dacca"), CFSTR("Asia/Dhaka"));
1455 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Asia/Istanbul"), CFSTR("Europe/Istanbul"));
1456 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Australia/Canberra"), CFSTR("Australia/Sydney"));
1457 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Brazil/East"), CFSTR("America/Sao_Paulo"));
1458 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Canada/Atlantic"), CFSTR("America/Halifax"));
1459 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Canada/Eastern"), CFSTR("America/Montreal"));
1460 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Canada/Mountain"), CFSTR("America/Edmonton"));
1461 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Canada/Newfoundland"), CFSTR("America/St_Johns"));
1462 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Canada/Saskatchewan"), CFSTR("America/Regina"));
1463 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("Japan"), CFSTR("Asia/Tokyo"));
1464 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("US/Central"), CFSTR("America/Chicago"));
1465 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("US/Eastern"), CFSTR("America/New_York"));
1466 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("US/Mountain"), CFSTR("America/Denver"));
1467 CFDictionaryAddValue(__CFTimeZoneCompatibilityMappingDict2
, CFSTR("US/Pacific"), CFSTR("America/Los_Angeles"));
1469 dict
= __CFTimeZoneCompatibilityMappingDict2
? CFRetain(__CFTimeZoneCompatibilityMappingDict2
) : NULL
;
1470 __CFTimeZoneUnlockCompatibilityMapping();