1 /*
2 ********************************************************************************
3 * Copyright (C) 2009, 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 #ifdef U_WINDOWS
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
getSystemTimeInformation(TimeZone * tz,SYSTEMTIME & daylightDate,SYSTEMTIME & standardDate,int32_t & bias,int32_t & daylightBias,int32_t & standardBias)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
getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION * zoneInfo,const UChar * icuid,int32_t length)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
uprv_getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION * zoneInfo,const UChar * icuid,int32_t length)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
158