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 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 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 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