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