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