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