16d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru/*
26d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru********************************************************************************
3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius*   Copyright (C) 2009-2013, International Business Machines
46d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
56d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru********************************************************************************
66d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru*
76d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru* File WINTZIMPL.CPP
86d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru*
96d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru********************************************************************************
106d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru*/
116d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
126d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#include "unicode/utypes.h"
136d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
14fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if U_PLATFORM_HAS_WIN32_API && !UCONFIG_NO_FORMATTING
156d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
166d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#include "wintzimpl.h"
176d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
186d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#include "unicode/unistr.h"
196d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#include "unicode/timezone.h"
206d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#include "unicode/basictz.h"
216d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#include "putilimp.h"
226d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#include "uassert.h"
2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h"
246d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
256d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#   define WIN32_LEAN_AND_MEAN
266d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#   define VC_EXTRALEAN
276d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#   define NOUSER
286d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#   define NOSERVICE
296d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#   define NOIME
306d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#   define NOMCX
316d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
326d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#include <windows.h>
336d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
3450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_USE
3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
366d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Querustatic UBool getSystemTimeInformation(TimeZone *tz, SYSTEMTIME &daylightDate, SYSTEMTIME &standardDate, int32_t &bias, int32_t &daylightBias, int32_t &standardBias) {
376d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
386d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    UBool result = TRUE;
396d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    BasicTimeZone *btz = (BasicTimeZone*)tz; // we should check type
406d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    InitialTimeZoneRule *initial = NULL;
416d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    AnnualTimeZoneRule *std = NULL, *dst = NULL;
426d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
436d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    btz->getSimpleRulesNear(uprv_getUTCtime(), initial, std, dst, status);
446d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    if (U_SUCCESS(status)) {
456d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        if (std == NULL || dst == NULL) {
466d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            bias = -1 * (initial->getRawOffset()/60000);
4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            standardBias = 0;
486d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightBias = 0;
496d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            // Do not use DST.  Set 0 to all stadardDate/daylightDate fields
506d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wYear = standardDate.wMonth  = standardDate.wDayOfWeek = standardDate.wDay =
516d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wHour = standardDate.wMinute = standardDate.wSecond    = standardDate.wMilliseconds = 0;
526d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wYear = daylightDate.wMonth  = daylightDate.wDayOfWeek = daylightDate.wDay =
536d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wHour = daylightDate.wMinute = daylightDate.wSecond    = daylightDate.wMilliseconds = 0;
546d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        } else {
556d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            U_ASSERT(std->getRule()->getDateRuleType() == DateTimeRule::DOW);
566d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            U_ASSERT(dst->getRule()->getDateRuleType() == DateTimeRule::DOW);
576d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
586d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            bias = -1 * (std->getRawOffset()/60000);
5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            standardBias = 0;
606d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightBias = -1 * (dst->getDSTSavings()/60000);
616d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            // Always use DOW type rule
626d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            int32_t hour, min, sec, mil;
636d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wYear = 0;
646d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wMonth = std->getRule()->getRuleMonth() + 1;
656d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wDay = std->getRule()->getRuleWeekInMonth();
666d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            if (standardDate.wDay < 0) {
676d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                standardDate.wDay = 5;
686d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            }
696d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wDayOfWeek = std->getRule()->getRuleDayOfWeek() - 1;
706d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
716d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            mil = std->getRule()->getRuleMillisInDay();
726d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            hour = mil/3600000;
736d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            mil %= 3600000;
746d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            min = mil/60000;
756d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            mil %= 60000;
766d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            sec = mil/1000;
776d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            mil %= 1000;
786d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
796d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wHour = hour;
806d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wMinute = min;
816d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wSecond = sec;
826d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            standardDate.wMilliseconds = mil;
836d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
846d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wYear = 0;
856d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wMonth = dst->getRule()->getRuleMonth() + 1;
866d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wDay = dst->getRule()->getRuleWeekInMonth();
876d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            if (daylightDate.wDay < 0) {
886d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru                daylightDate.wDay = 5;
896d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            }
906d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wDayOfWeek = dst->getRule()->getRuleDayOfWeek() - 1;
916d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
926d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            mil = dst->getRule()->getRuleMillisInDay();
936d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            hour = mil/3600000;
946d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            mil %= 3600000;
956d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            min = mil/60000;
966d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            mil %= 60000;
976d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            sec = mil/1000;
986d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            mil %= 1000;
996d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1006d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wHour = hour;
1016d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wMinute = min;
1026d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wSecond = sec;
1036d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            daylightDate.wMilliseconds = mil;
1046d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        }
1056d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    } else {
1066d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        result = FALSE;
1076d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    }
1086d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1096d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    delete initial;
1106d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    delete std;
1116d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    delete dst;
1126d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1136d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    return result;
1146d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru}
1156d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1166d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Querustatic UBool getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length) {
1176d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    UBool result = FALSE;
1186d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    UnicodeString id = UnicodeString(icuid, length);
1196d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    TimeZone *tz = TimeZone::createTimeZone(id);
1206d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1216d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    if (tz != NULL) {
1226d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        int32_t bias;
1236d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        int32_t daylightBias;
1246d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        int32_t standardBias;
1256d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        SYSTEMTIME daylightDate;
1266d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        SYSTEMTIME standardDate;
12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
1286d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        if (getSystemTimeInformation(tz, daylightDate, standardDate, bias, daylightBias, standardBias)) {
12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            uprv_memset(zoneInfo, 0, sizeof(TIME_ZONE_INFORMATION)); // We do not set standard/daylight names, so nullify first.
1306d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            zoneInfo->Bias          = bias;
1316d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            zoneInfo->DaylightBias  = daylightBias;
1326d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            zoneInfo->StandardBias  = standardBias;
1336d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            zoneInfo->DaylightDate  = daylightDate;
1346d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            zoneInfo->StandardDate  = standardDate;
1356d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1366d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru            result = TRUE;
1376d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        }
1386d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    }
1396d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1406d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    return result;
1416d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru}
1426d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1436d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru/*
1446d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru * Given the timezone icuid, fill in zoneInfo by calling auxillary functions that creates a timezone and extract the
1456d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru * information to put into zoneInfo. This includes bias and standard time date and daylight saving date.
1466d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru */
1476d5deb12725f146643d443090dfa11b206df528aJean-Baptiste QueruU_CAPI UBool U_EXPORT2
1486d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queruuprv_getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length)
1496d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru{
1506d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    if (getWindowsTimeZoneInfo(zoneInfo, icuid, length)) {
1516d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        return TRUE;
1526d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    } else {
1536d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru        return FALSE;
1546d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru    }
1556d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru}
1566d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru
1576d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru#endif
158