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