Home | History | Annotate | Download | only in intltest
      1 /*
      2 ********************************************************************************
      3 *   Copyright (C) 2005-2009, International Business Machines
      4 *   Corporation and others.  All Rights Reserved.
      5 ********************************************************************************
      6 *
      7 * File WINDTTST.CPP
      8 *
      9 ********************************************************************************
     10 */
     11 
     12 #include "unicode/utypes.h"
     13 
     14 #ifdef U_WINDOWS
     15 
     16 #if !UCONFIG_NO_FORMATTING
     17 
     18 #include "unicode/format.h"
     19 #include "unicode/numfmt.h"
     20 #include "unicode/locid.h"
     21 #include "unicode/ustring.h"
     22 #include "unicode/testlog.h"
     23 #include "unicode/utmscale.h"
     24 
     25 #include "windtfmt.h"
     26 #include "winutil.h"
     27 #include "windttst.h"
     28 
     29 #include "cmemory.h"
     30 #include "cstring.h"
     31 #include "locmap.h"
     32 #include "wintzimpl.h"
     33 
     34 #   define WIN32_LEAN_AND_MEAN
     35 #   define VC_EXTRALEAN
     36 #   define NOUSER
     37 #   define NOSERVICE
     38 #   define NOIME
     39 #   define NOMCX
     40 #   include <windows.h>
     41 
     42 #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
     43 
     44 static const char *getCalendarType(int32_t type)
     45 {
     46     switch (type)
     47     {
     48     case 1:
     49     case 2:
     50         return "@calendar=gregorian";
     51 
     52     case 3:
     53         return "@calendar=japanese";
     54 
     55     case 6:
     56         return "@calendar=islamic";
     57 
     58     case 7:
     59         return "@calendar=buddhist";
     60 
     61     case 8:
     62         return "@calendar=hebrew";
     63 
     64     default:
     65         return "";
     66     }
     67 }
     68 
     69 void Win32DateTimeTest::testLocales(TestLog *log)
     70 {
     71     SYSTEMTIME winNow;
     72     UDate icuNow = 0;
     73     SYSTEMTIME st;
     74     FILETIME ft;
     75     UnicodeString zoneID;
     76     const TimeZone *tz = TimeZone::createDefault();
     77     TIME_ZONE_INFORMATION tzi;
     78 
     79     tz->getID(zoneID);
     80     if (! uprv_getWindowsTimeZoneInfo(&tzi, zoneID.getBuffer(), zoneID.length())) {
     81         UBool found = FALSE;
     82         int32_t ec = TimeZone::countEquivalentIDs(zoneID);
     83 
     84         for (int z = 0; z < ec; z += 1) {
     85             UnicodeString equiv = TimeZone::getEquivalentID(zoneID, z);
     86 
     87             if (found = uprv_getWindowsTimeZoneInfo(&tzi, equiv.getBuffer(), equiv.length())) {
     88                 break;
     89             }
     90         }
     91 
     92         if (! found) {
     93             GetTimeZoneInformation(&tzi);
     94         }
     95     }
     96 
     97     GetSystemTime(&st);
     98     SystemTimeToFileTime(&st, &ft);
     99     SystemTimeToTzSpecificLocalTime(&tzi, &st, &winNow);
    100 
    101     int64_t wftNow = ((int64_t) ft.dwHighDateTime << 32) + ft.dwLowDateTime;
    102     UErrorCode status = U_ZERO_ERROR;
    103 
    104     int64_t udtsNow = utmscale_fromInt64(wftNow, UDTS_WINDOWS_FILE_TIME, &status);
    105 
    106     icuNow = (UDate) utmscale_toInt64(udtsNow, UDTS_ICU4C_TIME, &status);
    107 
    108     int32_t lcidCount = 0;
    109     Win32Utilities::LCIDRecord *lcidRecords = Win32Utilities::getLocales(lcidCount);
    110 
    111     for(int i = 0; i < lcidCount; i += 1) {
    112         UErrorCode status = U_ZERO_ERROR;
    113         WCHAR longDateFormat[81], longTimeFormat[81], wdBuffer[256], wtBuffer[256];
    114         int32_t calType = 0;
    115 
    116         // NULL localeID means ICU didn't recognize this locale
    117         if (lcidRecords[i].localeID == NULL) {
    118             continue;
    119         }
    120 
    121         GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_SLONGDATE,   longDateFormat, 81);
    122         GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_STIMEFORMAT, longTimeFormat, 81);
    123         GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_RETURN_NUMBER|LOCALE_ICALENDARTYPE, (LPWSTR) calType, sizeof(int32_t));
    124 
    125         char localeID[64];
    126 
    127         uprv_strcpy(localeID, lcidRecords[i].localeID);
    128         uprv_strcat(localeID, getCalendarType(calType));
    129 
    130         UnicodeString ubBuffer, udBuffer, utBuffer;
    131         Locale ulocale(localeID);
    132         int32_t wdLength, wtLength;
    133 
    134         wdLength = GetDateFormatW(lcidRecords[i].lcid, DATE_LONGDATE, &winNow, NULL, wdBuffer, ARRAY_SIZE(wdBuffer));
    135         wtLength = GetTimeFormatW(lcidRecords[i].lcid, 0, &winNow, NULL, wtBuffer, ARRAY_SIZE(wtBuffer));
    136 
    137         if (uprv_strchr(localeID, '@') > 0) {
    138             uprv_strcat(localeID, ";");
    139         } else {
    140             uprv_strcat(localeID, "@");
    141         }
    142 
    143         uprv_strcat(localeID, "compat=host");
    144 
    145         Locale wlocale(localeID);
    146         DateFormat *wbf = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, wlocale);
    147         DateFormat *wdf = DateFormat::createDateInstance(DateFormat::kFull, wlocale);
    148         DateFormat *wtf = DateFormat::createTimeInstance(DateFormat::kFull, wlocale);
    149 
    150         wbf->format(icuNow, ubBuffer);
    151         wdf->format(icuNow, udBuffer);
    152         wtf->format(icuNow, utBuffer);
    153 
    154         if (ubBuffer.indexOf(wdBuffer, wdLength - 1, 0) < 0) {
    155             UnicodeString baseName(wlocale.getBaseName());
    156             UnicodeString expected(wdBuffer);
    157 
    158             log->errln("DateTime format error for locale " + baseName + ": expected date \"" + expected +
    159                        "\" got \"" + ubBuffer + "\"");
    160         }
    161 
    162         if (ubBuffer.indexOf(wtBuffer, wtLength - 1, 0) < 0) {
    163             UnicodeString baseName(wlocale.getBaseName());
    164             UnicodeString expected(wtBuffer);
    165 
    166             log->errln("DateTime format error for locale " + baseName + ": expected time \"" + expected +
    167                        "\" got \"" + ubBuffer + "\"");
    168         }
    169 
    170         if (udBuffer.compare(wdBuffer) != 0) {
    171             UnicodeString baseName(wlocale.getBaseName());
    172             UnicodeString expected(wdBuffer);
    173 
    174             log->errln("Date format error for locale " + baseName + ": expected \"" + expected +
    175                        "\" got \"" + udBuffer + "\"");
    176         }
    177 
    178         if (utBuffer.compare(wtBuffer) != 0) {
    179             UnicodeString baseName(wlocale.getBaseName());
    180             UnicodeString expected(wtBuffer);
    181 
    182             log->errln("Time format error for locale " + baseName + ": expected \"" + expected +
    183                        "\" got \"" + utBuffer + "\"");
    184         }
    185         delete wbf;
    186         delete wdf;
    187         delete wtf;
    188     }
    189 
    190     Win32Utilities::freeLocales(lcidRecords);
    191     delete tz;
    192 }
    193 
    194 #endif /* #if !UCONFIG_NO_FORMATTING */
    195 
    196 #endif /* #ifdef U_WINDOWS */
    197