wintzimpl.cpp (5879B)
1 // © 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_USES_ONLY_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 #ifndef WIN32_LEAN_AND_MEAN 28 # define WIN32_LEAN_AND_MEAN 29 #endif 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 = nullptr; 45 AnnualTimeZoneRule *std = nullptr, *dst = nullptr; 46 47 btz->getSimpleRulesNear(uprv_getUTCtime(), initial, std, dst, status); 48 if (U_SUCCESS(status)) { 49 if (std == nullptr || dst == nullptr) { 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; 68 standardDate.wMonth = static_cast<WORD>(std->getRule()->getRuleMonth()) + 1; 69 standardDate.wDay = static_cast<WORD>(std->getRule()->getRuleWeekInMonth()); 70 if (standardDate.wDay < 0) { 71 standardDate.wDay = 5; 72 } 73 standardDate.wDayOfWeek = static_cast<WORD>(std->getRule()->getRuleDayOfWeek()) - 1; 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 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); 87 88 daylightDate.wYear = 0; 89 daylightDate.wMonth = static_cast<WORD>(dst->getRule()->getRuleMonth()) + 1; 90 daylightDate.wDay = static_cast<WORD>(dst->getRule()->getRuleWeekInMonth()); 91 if (daylightDate.wDay < 0) { 92 daylightDate.wDay = 5; 93 } 94 daylightDate.wDayOfWeek = static_cast<WORD>(dst->getRule()->getRuleDayOfWeek()) - 1; 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 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); 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 char16_t *icuid, int32_t length) { 121 UBool result = false; 122 UnicodeString id = UnicodeString(icuid, length); 123 TimeZone *tz = TimeZone::createTimeZone(id); 124 125 if (tz != nullptr) { 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 auxiliary 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 char16_t *icuid, int32_t length) 153 { 154 if (getWindowsTimeZoneInfo(zoneInfo, icuid, length)) { 155 return true; 156 } else { 157 return false; 158 } 159 } 160 161 #endif