Home | History | Annotate | Download | only in i18n
      1 /*
      2 ********************************************************************************
      3 *   Copyright (C) 2009, International Business Machines
      4 *   Corporation and others.  All Rights Reserved.
      5 ********************************************************************************
      6 *
      7 * File WINTZIMPL.CPP
      8 *
      9 ********************************************************************************
     10 */
     11 
     12 #include "unicode/utypes.h"
     13 
     14 #ifdef U_WINDOWS
     15 
     16 #include "wintzimpl.h"
     17 
     18 #include "unicode/unistr.h"
     19 #include "unicode/timezone.h"
     20 #include "unicode/basictz.h"
     21 #include "putilimp.h"
     22 #include "uassert.h"
     23 #include "cmemory.h"
     24 
     25 #   define WIN32_LEAN_AND_MEAN
     26 #   define VC_EXTRALEAN
     27 #   define NOUSER
     28 #   define NOSERVICE
     29 #   define NOIME
     30 #   define NOMCX
     31 
     32 #include <windows.h>
     33 
     34 U_NAMESPACE_USE
     35 
     36 static UBool getSystemTimeInformation(TimeZone *tz, SYSTEMTIME &daylightDate, SYSTEMTIME &standardDate, int32_t &bias, int32_t &daylightBias, int32_t &standardBias) {
     37     UErrorCode status = U_ZERO_ERROR;
     38     UBool result = TRUE;
     39     BasicTimeZone *btz = (BasicTimeZone*)tz; // we should check type
     40     InitialTimeZoneRule *initial = NULL;
     41     AnnualTimeZoneRule *std = NULL, *dst = NULL;
     42 
     43     btz->getSimpleRulesNear(uprv_getUTCtime(), initial, std, dst, status);
     44     if (U_SUCCESS(status)) {
     45         if (std == NULL || dst == NULL) {
     46             bias = -1 * (initial->getRawOffset()/60000);
     47             standardBias = 0;
     48             daylightBias = 0;
     49             // Do not use DST.  Set 0 to all stadardDate/daylightDate fields
     50             standardDate.wYear = standardDate.wMonth  = standardDate.wDayOfWeek = standardDate.wDay =
     51             standardDate.wHour = standardDate.wMinute = standardDate.wSecond    = standardDate.wMilliseconds = 0;
     52             daylightDate.wYear = daylightDate.wMonth  = daylightDate.wDayOfWeek = daylightDate.wDay =
     53             daylightDate.wHour = daylightDate.wMinute = daylightDate.wSecond    = daylightDate.wMilliseconds = 0;
     54         } else {
     55             U_ASSERT(std->getRule()->getDateRuleType() == DateTimeRule::DOW);
     56             U_ASSERT(dst->getRule()->getDateRuleType() == DateTimeRule::DOW);
     57 
     58             bias = -1 * (std->getRawOffset()/60000);
     59             standardBias = 0;
     60             daylightBias = -1 * (dst->getDSTSavings()/60000);
     61             // Always use DOW type rule
     62             int32_t hour, min, sec, mil;
     63             standardDate.wYear = 0;
     64             standardDate.wMonth = std->getRule()->getRuleMonth() + 1;
     65             standardDate.wDay = std->getRule()->getRuleWeekInMonth();
     66             if (standardDate.wDay < 0) {
     67                 standardDate.wDay = 5;
     68             }
     69             standardDate.wDayOfWeek = std->getRule()->getRuleDayOfWeek() - 1;
     70 
     71             mil = std->getRule()->getRuleMillisInDay();
     72             hour = mil/3600000;
     73             mil %= 3600000;
     74             min = mil/60000;
     75             mil %= 60000;
     76             sec = mil/1000;
     77             mil %= 1000;
     78 
     79             standardDate.wHour = hour;
     80             standardDate.wMinute = min;
     81             standardDate.wSecond = sec;
     82             standardDate.wMilliseconds = mil;
     83 
     84             daylightDate.wYear = 0;
     85             daylightDate.wMonth = dst->getRule()->getRuleMonth() + 1;
     86             daylightDate.wDay = dst->getRule()->getRuleWeekInMonth();
     87             if (daylightDate.wDay < 0) {
     88                 daylightDate.wDay = 5;
     89             }
     90             daylightDate.wDayOfWeek = dst->getRule()->getRuleDayOfWeek() - 1;
     91 
     92             mil = dst->getRule()->getRuleMillisInDay();
     93             hour = mil/3600000;
     94             mil %= 3600000;
     95             min = mil/60000;
     96             mil %= 60000;
     97             sec = mil/1000;
     98             mil %= 1000;
     99 
    100             daylightDate.wHour = hour;
    101             daylightDate.wMinute = min;
    102             daylightDate.wSecond = sec;
    103             daylightDate.wMilliseconds = mil;
    104         }
    105     } else {
    106         result = FALSE;
    107     }
    108 
    109     delete initial;
    110     delete std;
    111     delete dst;
    112 
    113     return result;
    114 }
    115 
    116 static UBool getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length) {
    117     UBool result = FALSE;
    118     UnicodeString id = UnicodeString(icuid, length);
    119     TimeZone *tz = TimeZone::createTimeZone(id);
    120 
    121     if (tz != NULL) {
    122         int32_t bias;
    123         int32_t daylightBias;
    124         int32_t standardBias;
    125         SYSTEMTIME daylightDate;
    126         SYSTEMTIME standardDate;
    127 
    128         if (getSystemTimeInformation(tz, daylightDate, standardDate, bias, daylightBias, standardBias)) {
    129             uprv_memset(zoneInfo, 0, sizeof(TIME_ZONE_INFORMATION)); // We do not set standard/daylight names, so nullify first.
    130             zoneInfo->Bias          = bias;
    131             zoneInfo->DaylightBias  = daylightBias;
    132             zoneInfo->StandardBias  = standardBias;
    133             zoneInfo->DaylightDate  = daylightDate;
    134             zoneInfo->StandardDate  = standardDate;
    135 
    136             result = TRUE;
    137         }
    138     }
    139 
    140     return result;
    141 }
    142 
    143 /*
    144  * Given the timezone icuid, fill in zoneInfo by calling auxillary functions that creates a timezone and extract the
    145  * information to put into zoneInfo. This includes bias and standard time date and daylight saving date.
    146  */
    147 U_CAPI UBool U_EXPORT2
    148 uprv_getWindowsTimeZoneInfo(TIME_ZONE_INFORMATION *zoneInfo, const UChar *icuid, int32_t length)
    149 {
    150     if (getWindowsTimeZoneInfo(zoneInfo, icuid, length)) {
    151         return TRUE;
    152     } else {
    153         return FALSE;
    154     }
    155 }
    156 
    157 #endif
    158