162 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| // © 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 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 UChar *icuid, int32_t length)
 | |
| {
 | |
|     if (getWindowsTimeZoneInfo(zoneInfo, icuid, length)) {
 | |
|         return TRUE;
 | |
|     } else {
 | |
|         return FALSE;
 | |
|     }
 | |
| }
 | |
| 
 | |
| #endif
 |