michael@0: /* michael@0: ******************************************************************************** michael@0: * Copyright (C) 2009-2011, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: ******************************************************************************** michael@0: * michael@0: * File WINTZIMPL.CPP michael@0: * michael@0: ******************************************************************************** michael@0: */ michael@0: michael@0: #include "unicode/utypes.h" michael@0: michael@0: #if U_PLATFORM_HAS_WIN32_API michael@0: michael@0: #include "wintzimpl.h" michael@0: michael@0: #include "unicode/unistr.h" michael@0: #include "unicode/timezone.h" michael@0: #include "unicode/basictz.h" michael@0: #include "putilimp.h" michael@0: #include "uassert.h" michael@0: #include "cmemory.h" michael@0: michael@0: # define WIN32_LEAN_AND_MEAN michael@0: # define VC_EXTRALEAN michael@0: # define NOUSER michael@0: # define NOSERVICE michael@0: # define NOIME michael@0: # define NOMCX michael@0: michael@0: #include michael@0: michael@0: U_NAMESPACE_USE michael@0: michael@0: static UBool getSystemTimeInformation(TimeZone *tz, SYSTEMTIME &daylightDate, SYSTEMTIME &standardDate, int32_t &bias, int32_t &daylightBias, int32_t &standardBias) { michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: UBool result = TRUE; michael@0: BasicTimeZone *btz = (BasicTimeZone*)tz; // we should check type michael@0: InitialTimeZoneRule *initial = NULL; michael@0: AnnualTimeZoneRule *std = NULL, *dst = NULL; michael@0: michael@0: btz->getSimpleRulesNear(uprv_getUTCtime(), initial, std, dst, status); michael@0: if (U_SUCCESS(status)) { michael@0: if (std == NULL || dst == NULL) { michael@0: bias = -1 * (initial->getRawOffset()/60000); michael@0: standardBias = 0; michael@0: daylightBias = 0; michael@0: // Do not use DST. Set 0 to all stadardDate/daylightDate fields michael@0: standardDate.wYear = standardDate.wMonth = standardDate.wDayOfWeek = standardDate.wDay = michael@0: standardDate.wHour = standardDate.wMinute = standardDate.wSecond = standardDate.wMilliseconds = 0; michael@0: daylightDate.wYear = daylightDate.wMonth = daylightDate.wDayOfWeek = daylightDate.wDay = michael@0: daylightDate.wHour = daylightDate.wMinute = daylightDate.wSecond = daylightDate.wMilliseconds = 0; michael@0: } else { michael@0: U_ASSERT(std->getRule()->getDateRuleType() == DateTimeRule::DOW); michael@0: U_ASSERT(dst->getRule()->getDateRuleType() == DateTimeRule::DOW); michael@0: michael@0: bias = -1 * (std->getRawOffset()/60000); michael@0: standardBias = 0; michael@0: daylightBias = -1 * (dst->getDSTSavings()/60000); michael@0: // Always use DOW type rule michael@0: int32_t hour, min, sec, mil; michael@0: standardDate.wYear = 0; michael@0: standardDate.wMonth = std->getRule()->getRuleMonth() + 1; michael@0: standardDate.wDay = std->getRule()->getRuleWeekInMonth(); michael@0: if (standardDate.wDay < 0) { michael@0: standardDate.wDay = 5; michael@0: } michael@0: standardDate.wDayOfWeek = std->getRule()->getRuleDayOfWeek() - 1; michael@0: michael@0: mil = std->getRule()->getRuleMillisInDay(); michael@0: hour = mil/3600000; michael@0: mil %= 3600000; michael@0: min = mil/60000; michael@0: mil %= 60000; michael@0: sec = mil/1000; michael@0: mil %= 1000; michael@0: michael@0: standardDate.wHour = hour; michael@0: standardDate.wMinute = min; michael@0: standardDate.wSecond = sec; michael@0: standardDate.wMilliseconds = mil; michael@0: michael@0: daylightDate.wYear = 0; michael@0: daylightDate.wMonth = dst->getRule()->getRuleMonth() + 1; michael@0: daylightDate.wDay = dst->getRule()->getRuleWeekInMonth(); michael@0: if (daylightDate.wDay < 0) { michael@0: daylightDate.wDay = 5; michael@0: } michael@0: daylightDate.wDayOfWeek = dst->getRule()->getRuleDayOfWeek() - 1; michael@0: michael@0: mil = dst->getRule()->getRuleMillisInDay(); michael@0: hour = mil/3600000; michael@0: mil %= 3600000; michael@0: min = mil/60000; michael@0: mil %= 60000; michael@0: sec = mil/1000; michael@0: mil %= 1000; michael@0: michael@0: daylightDate.wHour = hour; michael@0: daylightDate.wMinute = min; michael@0: daylightDate.wSecond = sec; michael@0: daylightDate.wMilliseconds = mil; michael@0: } michael@0: } else { michael@0: result = FALSE; michael@0: } michael@0: michael@0: delete initial; michael@0: delete std; michael@0: delete dst; michael@0: michael@0: return result; michael@0: } michael@0: michael@0: static UBool getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length) { michael@0: UBool result = FALSE; michael@0: UnicodeString id = UnicodeString(icuid, length); michael@0: TimeZone *tz = TimeZone::createTimeZone(id); michael@0: michael@0: if (tz != NULL) { michael@0: int32_t bias; michael@0: int32_t daylightBias; michael@0: int32_t standardBias; michael@0: SYSTEMTIME daylightDate; michael@0: SYSTEMTIME standardDate; michael@0: michael@0: if (getSystemTimeInformation(tz, daylightDate, standardDate, bias, daylightBias, standardBias)) { michael@0: uprv_memset(zoneInfo, 0, sizeof(TIME_ZONE_INFORMATION)); // We do not set standard/daylight names, so nullify first. michael@0: zoneInfo->Bias = bias; michael@0: zoneInfo->DaylightBias = daylightBias; michael@0: zoneInfo->StandardBias = standardBias; michael@0: zoneInfo->DaylightDate = daylightDate; michael@0: zoneInfo->StandardDate = standardDate; michael@0: michael@0: result = TRUE; michael@0: } michael@0: } michael@0: michael@0: return result; michael@0: } michael@0: michael@0: /* michael@0: * Given the timezone icuid, fill in zoneInfo by calling auxillary functions that creates a timezone and extract the michael@0: * information to put into zoneInfo. This includes bias and standard time date and daylight saving date. michael@0: */ michael@0: U_CAPI UBool U_EXPORT2 michael@0: uprv_getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length) michael@0: { michael@0: if (getWindowsTimeZoneInfo(zoneInfo, icuid, length)) { michael@0: return TRUE; michael@0: } else { michael@0: return FALSE; michael@0: } michael@0: } michael@0: michael@0: #endif