| // © 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 "unicode/utypes.h" |
| |
| #if U_PLATFORM_USES_ONLY_WIN32_API && !UCONFIG_NO_FORMATTING |
| |
| #include "wintzimpl.h" |
| |
| #include "unicode/unistr.h" |
| #include "unicode/timezone.h" |
| #include "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 = 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); |
| 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 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)) { |
| 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 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 |