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
)) {
348 p
+= 20 + 4 + 4 + 4; /* skip reserved, ttisgmtcnt, ttisstdcnt, leapcnt */
349 timecnt
= __CFDetzcode(p
);
351 typecnt
= __CFDetzcode(p
);
353 charcnt
= __CFDetzcode(p
);
355 if (typecnt
<= 0 || timecnt
< 0 || charcnt
< 0) {
358 if (len
- (int32_t)sizeof(struct tzhead
) < (4 + 1) * timecnt
+ (4 + 1 + 1) * typecnt
+ charcnt
) {
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
++) {
374 for (idx
= 0; idx
< cnt
; idx
++) {
376 int32_t itime
, offset
;
377 uint8_t type
, dst
, abbridx
;
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
) {
390 offset
= __CFDetzcode(ttisp
+ 6 * type
);
391 dst
= (uint8_t)*(ttisp
+ 6 * type
+ 4);
392 if (0 != dst
&& 1 != dst
) {
396 abbridx
= (uint8_t)*(ttisp
+ 6 * type
+ 5);
397 if (charcnt
< abbridx
) {
401 if (NULL
== abbrs
[abbridx
]) {
402 abbrs
[abbridx
] = CFStringCreateWithCString(allocator
, &charp
[abbridx
], kCFStringEncodingASCII
);
404 __CFTZPeriodInit(*tzpp
+ idx
, itime
, abbrs
[abbridx
], offset
, (dst
? true : false));
406 for (idx
= 0; idx
< charcnt
+ 1; idx
++) {
407 if (NULL
!= abbrs
[idx
]) {
408 CFRelease(abbrs
[idx
]);
411 CFAllocatorDeallocate(allocator
, abbrs
);
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
);
418 memmove((*tzpp
+ idx
), (*tzpp
+ idx
+ 1), sizeof(CFTZPeriod
) * (cnt
- idx
));
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
);
427 memmove((*tzpp
+ idx
), (*tzpp
+ idx
+ 1), sizeof(CFTZPeriod
) * (cnt
- idx
));
431 CFQSortArray(*tzpp
, cnt
, sizeof(CFTZPeriod
), __CFCompareTZPeriods
, NULL
);
434 CFAllocatorDeallocate(allocator
, *tzpp
);
439 /* We use Win32 function to find TimeZone
440 * (Aleksey Dukhnyakov)
442 *tzpp
= CFAllocatorAllocate(allocator
, sizeof(CFTZPeriod
), 0);
443 __CFTZPeriodInit(*tzpp
, 0, NULL
, 0, false);
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;
457 static CFHashCode
__CFTimeZoneHash(CFTypeRef cf
) {
458 CFTimeZoneRef tz
= (CFTimeZoneRef
)cf
;
459 return CFHash(CFTimeZoneGetName(tz
));
462 static CFStringRef
__CFTimeZoneCopyDescription(CFTypeRef cf
) {
463 CFTimeZoneRef tz
= (CFTimeZoneRef
)cf
;
464 CFStringRef result
, abbrev
;
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");
473 static void __CFTimeZoneDeallocate(CFTypeRef cf
) {
474 CFTimeZoneRef tz
= (CFTimeZoneRef
)cf
;
475 CFAllocatorRef allocator
= CFGetAllocator(tz
);
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
);
482 if (NULL
!= tz
->_periods
) CFAllocatorDeallocate(allocator
, tz
->_periods
);
485 static CFTypeID __kCFTimeZoneTypeID
= _kCFRuntimeNotATypeID
;
487 static const CFRuntimeClass __CFTimeZoneClass
= {
492 __CFTimeZoneDeallocate
,
496 __CFTimeZoneCopyDescription
499 __private_extern__
void __CFTimeZoneInitialize(void) {
500 __kCFTimeZoneTypeID
= _CFRuntimeRegisterClass(&__CFTimeZoneClass
);
503 CFTypeID
CFTimeZoneGetTypeID(void) {
504 return __kCFTimeZoneTypeID
;
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)
515 TIME_ZONE_INFORMATION tz
;
517 dw_result
=GetTimeZoneInformation(&tz
);
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
);
526 if (result
) return result
;
531 char linkbuf
[CFMaxPathSize
];
533 tzenv
= getenv("TZFILE");
535 CFStringRef name
= CFStringCreateWithBytes(kCFAllocatorDefault
, tzenv
, strlen(tzenv
), kCFStringEncodingUTF8
, false);
536 result
= CFTimeZoneCreateWithName(kCFAllocatorSystemDefault
, name
, false);
538 if (result
) return result
;
540 tzenv
= getenv("TZ");
542 CFStringRef name
= CFStringCreateWithBytes(kCFAllocatorDefault
, tzenv
, strlen(tzenv
), kCFStringEncodingUTF8
, false);
543 result
= CFTimeZoneCreateWithName(kCFAllocatorSystemDefault
, name
, true);
545 if (result
) return result
;
547 ret
= readlink(TZZONELINK
, linkbuf
, sizeof(linkbuf
));
551 if (strncmp(linkbuf
, TZZONEINFO
, sizeof(TZZONEINFO
) - 1) == 0) {
552 name
= CFStringCreateWithBytes(kCFAllocatorDefault
, linkbuf
+ sizeof(TZZONEINFO
) - 1, strlen(linkbuf
) - sizeof(TZZONEINFO
) + 1, kCFStringEncodingUTF8
, false);
554 name
= CFStringCreateWithBytes(kCFAllocatorDefault
, linkbuf
, strlen(linkbuf
), kCFStringEncodingUTF8
, false);
556 result
= CFTimeZoneCreateWithName(kCFAllocatorSystemDefault
, name
, false);
558 if (result
) return result
;
561 return CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorSystemDefault
, 0.0);
564 CFTimeZoneRef
CFTimeZoneCopySystem(void) {
566 __CFTimeZoneLockGlobal();
567 if (NULL
== __CFTimeZoneSystem
) {
568 __CFTimeZoneUnlockGlobal();
569 tz
= __CFTimeZoneCreateSystem();
570 __CFTimeZoneLockGlobal();
571 if (NULL
== __CFTimeZoneSystem
) {
572 __CFTimeZoneSystem
= tz
;
574 if (tz
) CFRelease(tz
);
577 tz
= __CFTimeZoneSystem
? CFRetain(__CFTimeZoneSystem
) : NULL
;
578 __CFTimeZoneUnlockGlobal();
582 void CFTimeZoneResetSystem(void) {
583 __CFTimeZoneLockGlobal();
584 if (__CFTimeZoneDefault
== __CFTimeZoneSystem
) {
585 if (__CFTimeZoneDefault
) CFRelease(__CFTimeZoneDefault
);
586 __CFTimeZoneDefault
= NULL
;
588 if (__CFTimeZoneSystem
) CFRelease(__CFTimeZoneSystem
);
589 __CFTimeZoneSystem
= NULL
;
590 __CFTimeZoneUnlockGlobal();
593 CFTimeZoneRef
CFTimeZoneCopyDefault(void) {
595 __CFTimeZoneLockGlobal();
596 if (NULL
== __CFTimeZoneDefault
) {
597 __CFTimeZoneUnlockGlobal();
598 tz
= CFTimeZoneCopySystem();
599 __CFTimeZoneLockGlobal();
600 if (NULL
== __CFTimeZoneDefault
) {
601 __CFTimeZoneDefault
= tz
;
603 if (tz
) CFRelease(tz
);
606 tz
= __CFTimeZoneDefault
? CFRetain(__CFTimeZoneDefault
) : NULL
;
607 __CFTimeZoneUnlockGlobal();
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
;
619 __CFTimeZoneUnlockGlobal();
622 static CFDictionaryRef
__CFTimeZoneCopyCompatibilityDictionary(void);
624 CFArrayRef
CFTimeZoneCopyKnownNames(void) {
626 __CFTimeZoneLockGlobal();
627 if (NULL
== __CFKnownTimeZoneList
) {
628 CFMutableArrayRef list
;
629 /* TimeZone information locate in the registry for Win32
630 * (Aleksey Dukhnyakov)
632 #if !defined(__WIN32__)
633 list
= __CFCopyRecursiveDirectoryList(TZZONEINFO
);
635 list
= __CFCopyWindowsTimeZoneList();
637 // Remove undesirable ancient cruft
638 CFDictionaryRef dict
= __CFTimeZoneCopyCompatibilityDictionary();
640 for (idx
= CFArrayGetCount(list
); idx
--; ) {
641 CFStringRef item
= CFArrayGetValueAtIndex(list
, idx
);
642 if (CFDictionaryContainsKey(dict
, item
)) {
643 CFArrayRemoveValueAtIndex(list
, idx
);
646 __CFKnownTimeZoneList
= CFArrayCreateCopy(kCFAllocatorSystemDefault
, list
);
649 tzs
= __CFKnownTimeZoneList
? CFRetain(__CFKnownTimeZoneList
) : NULL
;
650 __CFTimeZoneUnlockGlobal();
654 static const unsigned char *__CFTimeZoneAbbreviationDefaults
=
655 #if defined(__WIN32__)
657 * TimeZone abbreviations for Win32
658 * (Andrew Dzubandovsky)
661 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
662 " <!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">"
663 " <plist version=\"1.0\">"
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>"
742 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
743 " <!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">"
744 " <plist version=\"1.0\">"
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>"
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
);
788 if (NULL
== __CFTimeZoneAbbreviationDict
) {
789 __CFTimeZoneAbbreviationDict
= CFDictionaryCreate(kCFAllocatorDefault
, NULL
, NULL
, 0, NULL
, NULL
);
791 dict
= __CFTimeZoneAbbreviationDict
? CFRetain(__CFTimeZoneAbbreviationDict
) : NULL
;
792 __CFTimeZoneUnlockAbbreviations();
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
;
804 __CFTimeZoneUnlockGlobal();
807 CFTimeZoneRef
CFTimeZoneCreate(CFAllocatorRef allocator
, CFStringRef name
, CFDataRef data
) {
808 // assert: (NULL != name && NULL != data);
809 CFTimeZoneRef memory
;
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
);
823 if (!__CFParseTimeZoneData(allocator
, data
, &tzp
, &cnt
)) {
824 __CFTimeZoneUnlockGlobal();
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
);
834 if (NULL
!= tzp
) CFAllocatorDeallocate(allocator
, tzp
);
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
);
846 CFDictionaryAddValue(__CFTimeZoneCache
, ((struct __CFTimeZone
*)memory
)->_name
, memory
);
847 __CFTimeZoneUnlockGlobal();
851 #if !defined(__WIN32__)
852 static CFTimeZoneRef
__CFTimeZoneCreateFixed(CFAllocatorRef allocator
, int32_t seconds
, CFStringRef name
, int isDST
) {
853 CFTimeZoneRef result
;
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)");
861 unsigned char dataBytes
[52 + nameLen
+ 1];
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
);
874 #if defined(__WIN32__)
875 CFAllocatorDeallocate(allocator
, dataBytes
);
881 // rounds offset to nearest minute
882 CFTimeZoneRef
CFTimeZoneCreateWithTimeIntervalFromGMT(CFAllocatorRef allocator
, CFTimeInterval ti
) {
883 CFTimeZoneRef result
;
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"));
897 name
= CFStringCreateWithFormat(allocator
, NULL
, CFSTR("GMT%c%02d%02d"), (ti
< 0.0 ? '-' : '+'), hour
, minute
);
899 #if !defined(__WIN32__)
900 result
= __CFTimeZoneCreateFixed(allocator
, (int32_t)ti
, name
, 0);
902 /* CFTimeZoneRef->_data will contain TIME_ZONE_INFORMATION structure
903 * to find current timezone
904 * (Aleksey Dukhnyakov)
907 TIME_ZONE_INFORMATION tzi
;
909 CFIndex length
= CFStringGetLength(name
);
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
);
923 CFTimeZoneRef
CFTimeZoneCreateWithName(CFAllocatorRef allocator
, CFStringRef name
, Boolean tryAbbrev
) {
924 CFTimeZoneRef result
= NULL
;
925 CFStringRef tzName
= NULL
;
926 CFDataRef data
= NULL
;
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
936 __CFTimeZoneLockGlobal();
937 if (NULL
!= __CFTimeZoneCache
&& CFDictionaryGetValueIfPresent(__CFTimeZoneCache
, name
, (const void **)&result
)) {
938 __CFTimeZoneUnlockGlobal();
939 return (CFTimeZoneRef
)CFRetain(result
);
941 __CFTimeZoneUnlockGlobal();
942 #if !defined(__WIN32__)
943 CFURLRef baseURL
, tempURL
;
947 baseURL
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, CFSTR(TZZONEINFO
), kCFURLPOSIXPathStyle
, true);
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
);
963 CFDictionaryRef dict
= __CFTimeZoneCopyCompatibilityDictionary();
964 CFStringRef mapping
= CFDictionaryGetValue(dict
, name
);
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
);
974 CFRelease(unprefixed
);
977 if (CFEqual(CFSTR(""), 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
);
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
);
1003 result
= CFTimeZoneCreate(allocator
, tzName
, data
);
1007 /* Reading GMT offset and daylight flag from the registry
1009 * (Aleksey Dukhnyakov)
1012 CFStringRef safeName
= name
;
1017 SYSTEMTIME StandardDate
;
1018 SYSTEMTIME DaylightDate
;
1020 TIME_ZONE_INFORMATION tzi_system
;
1023 DWORD dwType
, dwSize
=sizeof(tzi
),
1024 dwSize_name1
=sizeof(tzi_system
.StandardName
),
1025 dwSize_name2
=sizeof(tzi_system
.DaylightName
);
1028 CFDictionaryRef abbrevs
= CFTimeZoneCopyAbbreviationDictionary();
1029 tzName
= CFDictionaryGetValue(abbrevs
, name
);
1030 if (NULL
== tzName
) {
1037 /* Open regestry and move down to the TimeZone information
1039 if (RegOpenKey(HKEY_LOCAL_MACHINE
,_T(TZZONEINFO
),&hkResult
) !=
1043 /* Move down to specific TimeZone name
1045 #if defined(UNICODE)
1046 if (RegOpenKey(hkResult
,CFStringGetCharactersPtr(name
) ,&hkResult
) !=
1049 if (RegOpenKey(hkResult
,CFStringGetCStringPtr(name
, CFStringGetSystemEncoding()),&hkResult
) != ERROR_SUCCESS
) {
1053 /* TimeZone information(offsets, daylight flag, ...) assign to tzi structure
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
)
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
;
1068 /* CFTimeZoneRef->_data will contain TIME_ZONE_INFORMATION structure
1069 * to find current timezone
1070 * (Aleksey Dukhnyakov)
1072 data
= CFDataCreate(allocator
,(UInt8
*)&tzi_system
, sizeof(tzi_system
));
1074 RegCloseKey(hkResult
);
1075 result
= CFTimeZoneCreate(allocator
, name
, data
);
1078 result
->_periods
->abbrev
= CFStringCreateCopy(allocator
,safeName
);
1088 CFStringRef
CFTimeZoneGetName(CFTimeZoneRef tz
) {
1089 CF_OBJC_FUNCDISPATCH0(__kCFTimeZoneTypeID
, CFStringRef
, tz
, "name");
1090 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1094 CFDataRef
CFTimeZoneGetData(CFTimeZoneRef tz
) {
1095 CF_OBJC_FUNCDISPATCH0(__kCFTimeZoneTypeID
, CFDataRef
, tz
, "data");
1096 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1100 /* This function converts CFAbsoluteTime to (Win32) SYSTEMTIME
1101 * (Aleksey Dukhnyakov)
1103 #if defined(__WIN32__)
1104 BOOL
__CFTimeZoneGetWin32SystemTime(SYSTEMTIME
* sys_time
, CFAbsoluteTime time
)
1107 FILETIME
* ftime
=(FILETIME
*)&l
;
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
1113 l
=(time
+11644473600LL+978307200)*10000000;
1114 if (FileTimeToSystemTime(ftime
,sys_time
))
1121 CFTimeInterval
_CFTimeZoneGetDSTOffset(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1122 #if !defined(__WIN32__)
1123 // #warning this does not work for non-CFTimeZoneRefs
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]));
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
1139 idx
= __CFBSearchTZPeriods(tz
, at
);
1140 if (tz
->_periodCnt
<= idx
+ 1) {
1143 return (CFAbsoluteTime
)__CFTZPeriodStartSeconds(&(tz
->_periods
[idx
+ 1]));
1148 CFTimeInterval
CFTimeZoneGetSecondsFromGMT(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1149 #if !defined(__WIN32__)
1151 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, CFTimeInterval
, tz
, "_secondsFromGMTForAbsoluteTime:", at
);
1152 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1153 idx
= __CFBSearchTZPeriods(tz
, at
);
1154 return __CFTZPeriodGMTOffset(&(tz
->_periods
[idx
]));
1156 /* To calculate seconds from GMT, calculate current timezone time and
1157 * subtract GMT timnezone time
1158 * (Aleksey Dukhnyakov)
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
)};
1168 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, CFTimeInterval
, tz
, "_secondsFromGMTForAbsoluteTime:", at
);
1170 CFDataGetBytes(tz
->_data
,range
,(UInt8
*)&tzi
);
1172 if (!__CFTimeZoneGetWin32SystemTime(&stime0
,at
) ||
1173 !SystemTimeToTzSpecificLocalTime(&tzi
,&stime0
,&stime1
) ||
1174 !SystemTimeToFileTime(&stime1
,&ftime1
) )
1176 CFAssert(0, __kCFLogAssertion
, "Win32 system time/timezone failed !\n");
1180 tzi
.DaylightDate
.wMonth
=0;
1181 tzi
.StandardDate
.wMonth
=0;
1186 if ( !SystemTimeToTzSpecificLocalTime(&tzi
,&stime0
,&stime2
) ||
1187 !SystemTimeToFileTime(&stime2
,&ftime2
))
1189 CFAssert(0, __kCFLogAssertion
, "Win32 system time/timezone failed !\n");
1192 result
=(double)((*l1
-*l2
)/10000000);
1197 #if defined(__WIN32__)
1199 * Get abbreviation for name for WIN32 platform
1200 * (Aleksey Dukhnyakov)
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
;
1216 CFIndex
__CFTimeZoneInitAbbrev(CFTimeZoneRef tz
) {
1218 if ( tz
->_periods
->abbrev
== NULL
) {
1219 _CFAbbrFind abbr
= { NULL
, NULL
};
1220 CFDictionaryRef abbrevs
= CFTimeZoneCopyAbbreviationDictionary();
1222 CFDictionaryApplyFunction(abbrevs
, _CFFindKeyForValue
, &abbr
);
1224 if ( abbr
.tzAbbr
!= NULL
)
1225 tz
->_periods
->abbrev
= CFStringCreateCopy(kCFAllocatorDefault
, abbr
.tzAbbr
);
1227 tz
->_periods
->abbrev
= CFStringCreateCopy(kCFAllocatorDefault
, tz
->_name
);
1228 /* We should return name of TimeZone if couldn't find abbrevation.
1231 * old line : tz->_periods->abbrev =
1232 * CFStringCreateWithCString(kCFAllocatorDefault,"UNKNOWN",
1233 * CFStringGetSystemEncoding());
1235 * (Aleksey Dukhnyakov)
1237 CFRelease( abbrevs
);
1244 CFStringRef
CFTimeZoneCopyAbbreviation(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1247 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, CFStringRef
, tz
, "_abbreviationForAbsoluteTime:", at
);
1248 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1249 #if !defined(__WIN32__)
1250 idx
= __CFBSearchTZPeriods(tz
, at
);
1253 * Initialize abbreviation for this TimeZone
1254 * (Aleksey Dukhnyakov)
1256 idx
= __CFTimeZoneInitAbbrev(tz
);
1258 result
= __CFTZPeriodAbbreviation(&(tz
->_periods
[idx
]));
1259 return result
? CFRetain(result
) : NULL
;
1262 Boolean
CFTimeZoneIsDaylightSavingTime(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
1263 #if !defined(__WIN32__)
1265 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, Boolean
, tz
, "_isDaylightSavingTimeForAbsoluteTime:", at
);
1266 __CFGenericValidateType(tz
, __kCFTimeZoneTypeID
);
1267 idx
= __CFBSearchTZPeriods(tz
, at
);
1268 return __CFTZPeriodIsDST(&(tz
->_periods
[idx
]));
1270 /* Compare current timezone time and current timezone time without
1271 * transition to day light saving time
1272 * (Aleskey Dukhnyakov)
1274 TIME_ZONE_INFORMATION tzi
;
1275 SYSTEMTIME stime0
,stime1
,stime2
;
1276 CFRange range
={0,sizeof(TIME_ZONE_INFORMATION
)};
1278 CF_OBJC_FUNCDISPATCH1(__kCFTimeZoneTypeID
, Boolean
, tz
, "_isDaylightSavingTimeForAbsoluteTime:", at
);
1280 CFDataGetBytes(tz
->_data
,range
,(UInt8
*)&tzi
);
1282 if ( !__CFTimeZoneGetWin32SystemTime(&stime0
,at
) ||
1283 !SystemTimeToTzSpecificLocalTime(&tzi
,&stime0
,&stime1
)) {
1284 CFAssert(0, __kCFLogAssertion
, "Win32 system time/timezone failed !\n");
1288 tzi
.DaylightDate
.wMonth
=0;
1289 tzi
.StandardDate
.wMonth
=0;
1291 if ( !SystemTimeToTzSpecificLocalTime(&tzi
,&stime0
,&stime2
)) {
1292 CFAssert(0, __kCFLogAssertion
, "Win32 system time/timezone failed !\n");
1296 if ( !memcmp(&stime1
,&stime2
,sizeof(stime1
)) )
1303 CFTimeInterval
_CFTimeZoneGetDSTDelta(CFTimeZoneRef tz
, CFAbsoluteTime at
) {
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])));
1316 static CFDictionaryRef
__CFTimeZoneCopyCompatibilityDictionary(void) {
1317 CFDictionaryRef dict
;
1318 __CFTimeZoneLockCompatibilityMapping();
1319 if (NULL
== __CFTimeZoneCompatibilityMappingDict
) {
1320 __CFTimeZoneCompatibilityMappingDict
= CFDictionaryCreateMutable(kCFAllocatorSystemDefault
, 112, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
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(""));
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"));
1434 dict
= __CFTimeZoneCompatibilityMappingDict
? CFRetain(__CFTimeZoneCompatibilityMappingDict
) : NULL
;
1435 __CFTimeZoneUnlockCompatibilityMapping();
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"));
1459 dict
= __CFTimeZoneCompatibilityMappingDict2
? CFRetain(__CFTimeZoneCompatibilityMappingDict2
) : NULL
;
1460 __CFTimeZoneUnlockCompatibilityMapping();