171 lines
6.5 KiB
C++
171 lines
6.5 KiB
C++
|
/*
|
||
|
********************************************************************************
|
||
|
* 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 "unicode/calendar.h"
|
||
|
|
||
|
# define WIN32_LEAN_AND_MEAN
|
||
|
# define VC_EXTRALEAN
|
||
|
# define NOUSER
|
||
|
# define NOSERVICE
|
||
|
# define NOIME
|
||
|
# define NOMCX
|
||
|
|
||
|
#include <windows.h>
|
||
|
|
||
|
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 = NULL;
|
||
|
Calendar *cal = NULL;
|
||
|
InitialTimeZoneRule *initial = NULL;
|
||
|
AnnualTimeZoneRule *std = NULL;
|
||
|
AnnualTimeZoneRule *dst = NULL;
|
||
|
UDate currentTime;
|
||
|
int32_t currentYear;
|
||
|
int32_t rawOffset = tz->getRawOffset();
|
||
|
int32_t dstOffset = tz->getDSTSavings();
|
||
|
|
||
|
/* Offset set needs to be normalized so to Windows */
|
||
|
bias = (tz->getRawOffset() * -1)/(60000);
|
||
|
standardBias = 0;
|
||
|
|
||
|
if (tz->useDaylightTime()) {
|
||
|
daylightBias = (tz->getDSTSavings() / 60000) * -1;
|
||
|
} else {
|
||
|
daylightBias = 0;
|
||
|
}
|
||
|
|
||
|
btz = (BasicTimeZone *)tz->clone();
|
||
|
cal = Calendar::createInstance(tz, status);
|
||
|
if (btz != NULL && cal != NULL && U_SUCCESS(status)) {
|
||
|
currentTime = cal->getTime(status);
|
||
|
currentYear = cal->get(UCAL_YEAR, status);
|
||
|
|
||
|
btz->getSimpleRulesNear(currentTime, initial, std, dst, status);
|
||
|
if (U_SUCCESS(status)) {
|
||
|
if (std == NULL || dst == NULL) {
|
||
|
/* Generally, if std is NULL, dst will also be NULL.
|
||
|
* This indicates that daylight saving is not observed
|
||
|
* in this timezone so the standarDate and daylightDate
|
||
|
* should be zero.
|
||
|
*/
|
||
|
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 {
|
||
|
/* Get the UDate value for the start of the timezone standard time and daylight saving time.
|
||
|
* Then set the standardDate and daylightDate to this. The wYear value is 0 to indicate that
|
||
|
* this is not an absolute date but a rule. (e.g. the first Sunday in November)
|
||
|
*/
|
||
|
UDate dateTime;
|
||
|
if (std->getStartInYear(currentYear, rawOffset, 0, dateTime)) {
|
||
|
cal->setTime(dateTime, status);
|
||
|
|
||
|
standardDate.wYear = 0;
|
||
|
standardDate.wMonth = cal->get(UCAL_MONTH, status) + 1;
|
||
|
standardDate.wDayOfWeek = cal->get(UCAL_DAY_OF_WEEK, status) - 1;
|
||
|
standardDate.wDay = cal->get(UCAL_DAY_OF_WEEK_IN_MONTH, status);
|
||
|
standardDate.wHour = cal->get(UCAL_HOUR_OF_DAY, status);
|
||
|
standardDate.wMinute = cal->get(UCAL_MINUTE, status);
|
||
|
standardDate.wSecond = cal->get(UCAL_SECOND, status);
|
||
|
standardDate.wMilliseconds = cal->get(UCAL_MILLISECOND, status);
|
||
|
|
||
|
if (U_SUCCESS(status) && dst->getStartInYear(currentYear, rawOffset, dstOffset, dateTime)) {
|
||
|
cal->setTime(dateTime, status);
|
||
|
|
||
|
daylightDate.wYear = 0;
|
||
|
daylightDate.wMonth = cal->get(UCAL_MONTH, status) + 1;
|
||
|
daylightDate.wDayOfWeek = cal->get(UCAL_DAY_OF_WEEK, status) - 1;
|
||
|
daylightDate.wDay = cal->get(UCAL_DAY_OF_WEEK_IN_MONTH, status);
|
||
|
daylightDate.wHour = cal->get(UCAL_HOUR_OF_DAY, status) + dstOffset/3600000;
|
||
|
daylightDate.wMinute = cal->get(UCAL_MINUTE, status);
|
||
|
daylightDate.wSecond = cal->get(UCAL_SECOND, status);
|
||
|
daylightDate.wMilliseconds = cal->get(UCAL_MILLISECOND, status);
|
||
|
} else {
|
||
|
result = FALSE;
|
||
|
}
|
||
|
} else {
|
||
|
result = FALSE;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
result = FALSE;
|
||
|
}
|
||
|
} else {
|
||
|
result = FALSE;
|
||
|
}
|
||
|
|
||
|
if (result && U_FAILURE(status)) {
|
||
|
result = FALSE;
|
||
|
}
|
||
|
|
||
|
delete btz;
|
||
|
delete cal;
|
||
|
delete initial;
|
||
|
delete std;
|
||
|
delete dst;
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
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)) {
|
||
|
result = FALSE;
|
||
|
} else {
|
||
|
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
|