/* | |
******************************************************************************** | |
* Copyright (C) 2008, International Business Machines | |
* Corporation and others. All Rights Reserved. | |
******************************************************************************** | |
* | |
* File WINTZIMPL.CPP | |
* | |
******************************************************************************** | |
*/ | |
#include "unicode/utypes.h" | |
#ifdef U_WINDOWS | |
#include "wintzimpl.h" | |
#include "unicode/unistr.h" | |
#include "unicode/timezone.h" | |
#include "unicode/basictz.h" | |
#include "putilimp.h" | |
#include "uassert.h" | |
# define WIN32_LEAN_AND_MEAN | |
# define VC_EXTRALEAN | |
# define NOUSER | |
# define NOSERVICE | |
# define NOIME | |
# define NOMCX | |
#include <windows.h> | |
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 = NULL; | |
AnnualTimeZoneRule *std = NULL, *dst = NULL; | |
btz->getSimpleRulesNear(uprv_getUTCtime(), initial, std, dst, status); | |
if (U_SUCCESS(status)) { | |
if (std == NULL || dst == NULL) { | |
bias = -1 * (initial->getRawOffset()/60000); | |
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); | |
daylightBias = -1 * (dst->getDSTSavings()/60000); | |
// Always use DOW type rule | |
int32_t hour, min, sec, mil; | |
standardDate.wYear = 0; | |
standardDate.wMonth = std->getRule()->getRuleMonth() + 1; | |
standardDate.wDay = std->getRule()->getRuleWeekInMonth(); | |
if (standardDate.wDay < 0) { | |
standardDate.wDay = 5; | |
} | |
standardDate.wDayOfWeek = 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 = hour; | |
standardDate.wMinute = min; | |
standardDate.wSecond = sec; | |
standardDate.wMilliseconds = mil; | |
daylightDate.wYear = 0; | |
daylightDate.wMonth = dst->getRule()->getRuleMonth() + 1; | |
daylightDate.wDay = dst->getRule()->getRuleWeekInMonth(); | |
if (daylightDate.wDay < 0) { | |
daylightDate.wDay = 5; | |
} | |
daylightDate.wDayOfWeek = 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 = hour; | |
daylightDate.wMinute = min; | |
daylightDate.wSecond = sec; | |
daylightDate.wMilliseconds = mil; | |
} | |
} else { | |
result = FALSE; | |
} | |
delete initial; | |
delete std; | |
delete dst; | |
return result; | |
} | |
static UBool getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length) { | |
UBool result = FALSE; | |
UnicodeString id = UnicodeString(icuid, length); | |
TimeZone *tz = TimeZone::createTimeZone(id); | |
if (tz != NULL) { | |
int32_t bias; | |
int32_t daylightBias; | |
int32_t standardBias; | |
SYSTEMTIME daylightDate; | |
SYSTEMTIME standardDate; | |
if (getSystemTimeInformation(tz, daylightDate, standardDate, bias, daylightBias, standardBias)) { | |
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 auxillary 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 UChar *icuid, int32_t length) | |
{ | |
if (getWindowsTimeZoneInfo(zoneInfo, icuid, length)) { | |
return TRUE; | |
} else { | |
return FALSE; | |
} | |
} | |
#endif |