|
1 /* |
|
2 ******************************************************************************** |
|
3 * Copyright (C) 2009-2011, International Business Machines |
|
4 * Corporation and others. All Rights Reserved. |
|
5 ******************************************************************************** |
|
6 * |
|
7 * File WINTZIMPL.CPP |
|
8 * |
|
9 ******************************************************************************** |
|
10 */ |
|
11 |
|
12 #include "unicode/utypes.h" |
|
13 |
|
14 #if U_PLATFORM_HAS_WIN32_API |
|
15 |
|
16 #include "wintzimpl.h" |
|
17 |
|
18 #include "unicode/unistr.h" |
|
19 #include "unicode/timezone.h" |
|
20 #include "unicode/basictz.h" |
|
21 #include "putilimp.h" |
|
22 #include "uassert.h" |
|
23 #include "cmemory.h" |
|
24 |
|
25 # define WIN32_LEAN_AND_MEAN |
|
26 # define VC_EXTRALEAN |
|
27 # define NOUSER |
|
28 # define NOSERVICE |
|
29 # define NOIME |
|
30 # define NOMCX |
|
31 |
|
32 #include <windows.h> |
|
33 |
|
34 U_NAMESPACE_USE |
|
35 |
|
36 static UBool getSystemTimeInformation(TimeZone *tz, SYSTEMTIME &daylightDate, SYSTEMTIME &standardDate, int32_t &bias, int32_t &daylightBias, int32_t &standardBias) { |
|
37 UErrorCode status = U_ZERO_ERROR; |
|
38 UBool result = TRUE; |
|
39 BasicTimeZone *btz = (BasicTimeZone*)tz; // we should check type |
|
40 InitialTimeZoneRule *initial = NULL; |
|
41 AnnualTimeZoneRule *std = NULL, *dst = NULL; |
|
42 |
|
43 btz->getSimpleRulesNear(uprv_getUTCtime(), initial, std, dst, status); |
|
44 if (U_SUCCESS(status)) { |
|
45 if (std == NULL || dst == NULL) { |
|
46 bias = -1 * (initial->getRawOffset()/60000); |
|
47 standardBias = 0; |
|
48 daylightBias = 0; |
|
49 // Do not use DST. Set 0 to all stadardDate/daylightDate fields |
|
50 standardDate.wYear = standardDate.wMonth = standardDate.wDayOfWeek = standardDate.wDay = |
|
51 standardDate.wHour = standardDate.wMinute = standardDate.wSecond = standardDate.wMilliseconds = 0; |
|
52 daylightDate.wYear = daylightDate.wMonth = daylightDate.wDayOfWeek = daylightDate.wDay = |
|
53 daylightDate.wHour = daylightDate.wMinute = daylightDate.wSecond = daylightDate.wMilliseconds = 0; |
|
54 } else { |
|
55 U_ASSERT(std->getRule()->getDateRuleType() == DateTimeRule::DOW); |
|
56 U_ASSERT(dst->getRule()->getDateRuleType() == DateTimeRule::DOW); |
|
57 |
|
58 bias = -1 * (std->getRawOffset()/60000); |
|
59 standardBias = 0; |
|
60 daylightBias = -1 * (dst->getDSTSavings()/60000); |
|
61 // Always use DOW type rule |
|
62 int32_t hour, min, sec, mil; |
|
63 standardDate.wYear = 0; |
|
64 standardDate.wMonth = std->getRule()->getRuleMonth() + 1; |
|
65 standardDate.wDay = std->getRule()->getRuleWeekInMonth(); |
|
66 if (standardDate.wDay < 0) { |
|
67 standardDate.wDay = 5; |
|
68 } |
|
69 standardDate.wDayOfWeek = std->getRule()->getRuleDayOfWeek() - 1; |
|
70 |
|
71 mil = std->getRule()->getRuleMillisInDay(); |
|
72 hour = mil/3600000; |
|
73 mil %= 3600000; |
|
74 min = mil/60000; |
|
75 mil %= 60000; |
|
76 sec = mil/1000; |
|
77 mil %= 1000; |
|
78 |
|
79 standardDate.wHour = hour; |
|
80 standardDate.wMinute = min; |
|
81 standardDate.wSecond = sec; |
|
82 standardDate.wMilliseconds = mil; |
|
83 |
|
84 daylightDate.wYear = 0; |
|
85 daylightDate.wMonth = dst->getRule()->getRuleMonth() + 1; |
|
86 daylightDate.wDay = dst->getRule()->getRuleWeekInMonth(); |
|
87 if (daylightDate.wDay < 0) { |
|
88 daylightDate.wDay = 5; |
|
89 } |
|
90 daylightDate.wDayOfWeek = dst->getRule()->getRuleDayOfWeek() - 1; |
|
91 |
|
92 mil = dst->getRule()->getRuleMillisInDay(); |
|
93 hour = mil/3600000; |
|
94 mil %= 3600000; |
|
95 min = mil/60000; |
|
96 mil %= 60000; |
|
97 sec = mil/1000; |
|
98 mil %= 1000; |
|
99 |
|
100 daylightDate.wHour = hour; |
|
101 daylightDate.wMinute = min; |
|
102 daylightDate.wSecond = sec; |
|
103 daylightDate.wMilliseconds = mil; |
|
104 } |
|
105 } else { |
|
106 result = FALSE; |
|
107 } |
|
108 |
|
109 delete initial; |
|
110 delete std; |
|
111 delete dst; |
|
112 |
|
113 return result; |
|
114 } |
|
115 |
|
116 static UBool getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length) { |
|
117 UBool result = FALSE; |
|
118 UnicodeString id = UnicodeString(icuid, length); |
|
119 TimeZone *tz = TimeZone::createTimeZone(id); |
|
120 |
|
121 if (tz != NULL) { |
|
122 int32_t bias; |
|
123 int32_t daylightBias; |
|
124 int32_t standardBias; |
|
125 SYSTEMTIME daylightDate; |
|
126 SYSTEMTIME standardDate; |
|
127 |
|
128 if (getSystemTimeInformation(tz, daylightDate, standardDate, bias, daylightBias, standardBias)) { |
|
129 uprv_memset(zoneInfo, 0, sizeof(TIME_ZONE_INFORMATION)); // We do not set standard/daylight names, so nullify first. |
|
130 zoneInfo->Bias = bias; |
|
131 zoneInfo->DaylightBias = daylightBias; |
|
132 zoneInfo->StandardBias = standardBias; |
|
133 zoneInfo->DaylightDate = daylightDate; |
|
134 zoneInfo->StandardDate = standardDate; |
|
135 |
|
136 result = TRUE; |
|
137 } |
|
138 } |
|
139 |
|
140 return result; |
|
141 } |
|
142 |
|
143 /* |
|
144 * Given the timezone icuid, fill in zoneInfo by calling auxillary functions that creates a timezone and extract the |
|
145 * information to put into zoneInfo. This includes bias and standard time date and daylight saving date. |
|
146 */ |
|
147 U_CAPI UBool U_EXPORT2 |
|
148 uprv_getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length) |
|
149 { |
|
150 if (getWindowsTimeZoneInfo(zoneInfo, icuid, length)) { |
|
151 return TRUE; |
|
152 } else { |
|
153 return FALSE; |
|
154 } |
|
155 } |
|
156 |
|
157 #endif |