• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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