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