Home | History | Annotate | Download | only in intltest
      1 /*
      2 ********************************************************************************
      3 *   Copyright (C) 2005-2008, 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     uprv_memset(&tzi, 0, sizeof(tzi));
     80     tz->getID(zoneID);
     81     if (! uprv_getWindowsTimeZoneInfo(&tzi, zoneID.getBuffer(), zoneID.length())) {
     82         UBool found = FALSE;
     83         int32_t ec = TimeZone::countEquivalentIDs(zoneID);
     84 
     85         for (int z = 0; z < ec; z += 1) {
     86             UnicodeString equiv = TimeZone::getEquivalentID(zoneID, z);
     87 
     88             if (found = uprv_getWindowsTimeZoneInfo(&tzi, equiv.getBuffer(), equiv.length())) {
     89                 break;
     90             }
     91         }
     92 
     93         if (! found) {
     94             GetTimeZoneInformation(&tzi);
     95         }
     96     }
     97 
     98     GetSystemTime(&st);
     99     SystemTimeToFileTime(&st, &ft);
    100     SystemTimeToTzSpecificLocalTime(&tzi, &st, &winNow);
    101 
    102     int64_t wftNow = ((int64_t) ft.dwHighDateTime << 32) + ft.dwLowDateTime;
    103     UErrorCode status = U_ZERO_ERROR;
    104 
    105     int64_t udtsNow = utmscale_fromInt64(wftNow, UDTS_WINDOWS_FILE_TIME, &status);
    106 
    107     icuNow = (UDate) utmscale_toInt64(udtsNow, UDTS_ICU4C_TIME, &status);
    108 
    109     int32_t lcidCount = 0;
    110     Win32Utilities::LCIDRecord *lcidRecords = Win32Utilities::getLocales(lcidCount);
    111 
    112     for(int i = 0; i < lcidCount; i += 1) {
    113         UErrorCode status = U_ZERO_ERROR;
    114         WCHAR longDateFormat[81], longTimeFormat[81], wdBuffer[256], wtBuffer[256];
    115         int32_t calType = 0;
    116 
    117 		// NULL localeID means ICU didn't recognize this locale
    118 		if (lcidRecords[i].localeID == NULL) {
    119 			continue;
    120 		}
    121 
    122         GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_SLONGDATE,   longDateFormat, 81);
    123         GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_STIMEFORMAT, longTimeFormat, 81);
    124         GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_RETURN_NUMBER|LOCALE_ICALENDARTYPE, (LPWSTR) calType, sizeof(int32_t));
    125 
    126         char localeID[64];
    127 
    128         uprv_strcpy(localeID, lcidRecords[i].localeID);
    129         uprv_strcat(localeID, getCalendarType(calType));
    130 
    131         UnicodeString ubBuffer, udBuffer, utBuffer;
    132         Locale ulocale(localeID);
    133         int32_t wdLength, wtLength;
    134 
    135         wdLength = GetDateFormatW(lcidRecords[i].lcid, DATE_LONGDATE, &winNow, NULL, wdBuffer, ARRAY_SIZE(wdBuffer));
    136         wtLength = GetTimeFormatW(lcidRecords[i].lcid, 0, &winNow, NULL, wtBuffer, ARRAY_SIZE(wtBuffer));
    137 
    138         if (uprv_strchr(localeID, '@') > 0) {
    139             uprv_strcat(localeID, ";");
    140         } else {
    141             uprv_strcat(localeID, "@");
    142         }
    143 
    144         uprv_strcat(localeID, "compat=host");
    145 
    146         Locale wlocale(localeID);
    147         DateFormat *wbf = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, wlocale);
    148         DateFormat *wdf = DateFormat::createDateInstance(DateFormat::kFull, wlocale);
    149         DateFormat *wtf = DateFormat::createTimeInstance(DateFormat::kFull, wlocale);
    150 
    151         wbf->format(icuNow, ubBuffer);
    152         wdf->format(icuNow, udBuffer);
    153         wtf->format(icuNow, utBuffer);
    154 
    155         if (ubBuffer.indexOf(wdBuffer, wdLength - 1, 0) < 0) {
    156             UnicodeString baseName(wlocale.getBaseName());
    157             UnicodeString expected(wdBuffer);
    158 
    159             log->errln("DateTime format error for locale " + baseName + ": expected date \"" + expected +
    160                        "\" got \"" + ubBuffer + "\"");
    161         }
    162 
    163         if (ubBuffer.indexOf(wtBuffer, wtLength - 1, 0) < 0) {
    164             UnicodeString baseName(wlocale.getBaseName());
    165             UnicodeString expected(wtBuffer);
    166 
    167             log->errln("DateTime format error for locale " + baseName + ": expected time \"" + expected +
    168                        "\" got \"" + ubBuffer + "\"");
    169         }
    170 
    171         if (udBuffer.compare(wdBuffer) != 0) {
    172             UnicodeString baseName(wlocale.getBaseName());
    173             UnicodeString expected(wdBuffer);
    174 
    175             log->errln("Date format error for locale " + baseName + ": expected \"" + expected +
    176                        "\" got \"" + udBuffer + "\"");
    177         }
    178 
    179         if (utBuffer.compare(wtBuffer) != 0) {
    180             UnicodeString baseName(wlocale.getBaseName());
    181             UnicodeString expected(wtBuffer);
    182 
    183             log->errln("Time format error for locale " + baseName + ": expected \"" + expected +
    184                        "\" got \"" + utBuffer + "\"");
    185         }
    186         delete wbf;
    187         delete wdf;
    188         delete wtf;
    189     }
    190 
    191     Win32Utilities::freeLocales(lcidRecords);
    192     delete tz;
    193 }
    194 
    195 #endif /* #if !UCONFIG_NO_FORMATTING */
    196 
    197 #endif /* #ifdef U_WINDOWS */
    198