]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
73c04bcf A |
3 | /* |
4 | ******************************************************************************** | |
2ca993e8 | 5 | * Copyright (C) 2005-2016, International Business Machines |
73c04bcf A |
6 | * Corporation and others. All Rights Reserved. |
7 | ******************************************************************************** | |
8 | * | |
9 | * File WINDTTST.CPP | |
10 | * | |
11 | ******************************************************************************** | |
12 | */ | |
13 | ||
14 | #include "unicode/utypes.h" | |
15 | ||
f3c0d7a5 | 16 | #if U_PLATFORM_USES_ONLY_WIN32_API |
73c04bcf A |
17 | |
18 | #if !UCONFIG_NO_FORMATTING | |
19 | ||
20 | #include "unicode/format.h" | |
21 | #include "unicode/numfmt.h" | |
22 | #include "unicode/locid.h" | |
23 | #include "unicode/ustring.h" | |
24 | #include "unicode/testlog.h" | |
25 | #include "unicode/utmscale.h" | |
26 | ||
27 | #include "windtfmt.h" | |
28 | #include "winutil.h" | |
29 | #include "windttst.h" | |
30 | ||
f3c0d7a5 A |
31 | #include "dtfmttst.h" |
32 | ||
73c04bcf A |
33 | #include "cmemory.h" |
34 | #include "cstring.h" | |
35 | #include "locmap.h" | |
729e4ab9 | 36 | #include "wintzimpl.h" |
73c04bcf A |
37 | |
38 | # define WIN32_LEAN_AND_MEAN | |
39 | # define VC_EXTRALEAN | |
40 | # define NOUSER | |
41 | # define NOSERVICE | |
42 | # define NOIME | |
43 | # define NOMCX | |
44 | # include <windows.h> | |
45 | ||
73c04bcf A |
46 | static const char *getCalendarType(int32_t type) |
47 | { | |
48 | switch (type) | |
49 | { | |
50 | case 1: | |
51 | case 2: | |
52 | return "@calendar=gregorian"; | |
53 | ||
54 | case 3: | |
55 | return "@calendar=japanese"; | |
56 | ||
57 | case 6: | |
58 | return "@calendar=islamic"; | |
59 | ||
60 | case 7: | |
61 | return "@calendar=buddhist"; | |
62 | ||
63 | case 8: | |
64 | return "@calendar=hebrew"; | |
65 | ||
66 | default: | |
67 | return ""; | |
68 | } | |
69 | } | |
70 | ||
f3c0d7a5 | 71 | void Win32DateTimeTest::testLocales(DateFormatTest *log) |
73c04bcf A |
72 | { |
73 | SYSTEMTIME winNow; | |
74 | UDate icuNow = 0; | |
75 | SYSTEMTIME st; | |
76 | FILETIME ft; | |
77 | UnicodeString zoneID; | |
78 | const TimeZone *tz = TimeZone::createDefault(); | |
79 | TIME_ZONE_INFORMATION tzi; | |
80 | ||
73c04bcf A |
81 | tz->getID(zoneID); |
82 | if (! uprv_getWindowsTimeZoneInfo(&tzi, zoneID.getBuffer(), zoneID.length())) { | |
83 | UBool found = FALSE; | |
84 | int32_t ec = TimeZone::countEquivalentIDs(zoneID); | |
85 | ||
86 | for (int z = 0; z < ec; z += 1) { | |
87 | UnicodeString equiv = TimeZone::getEquivalentID(zoneID, z); | |
88 | ||
89 | if (found = uprv_getWindowsTimeZoneInfo(&tzi, equiv.getBuffer(), equiv.length())) { | |
90 | break; | |
91 | } | |
92 | } | |
93 | ||
94 | if (! found) { | |
95 | GetTimeZoneInformation(&tzi); | |
96 | } | |
97 | } | |
98 | ||
99 | GetSystemTime(&st); | |
100 | SystemTimeToFileTime(&st, &ft); | |
101 | SystemTimeToTzSpecificLocalTime(&tzi, &st, &winNow); | |
102 | ||
103 | int64_t wftNow = ((int64_t) ft.dwHighDateTime << 32) + ft.dwLowDateTime; | |
104 | UErrorCode status = U_ZERO_ERROR; | |
105 | ||
106 | int64_t udtsNow = utmscale_fromInt64(wftNow, UDTS_WINDOWS_FILE_TIME, &status); | |
107 | ||
108 | icuNow = (UDate) utmscale_toInt64(udtsNow, UDTS_ICU4C_TIME, &status); | |
109 | ||
110 | int32_t lcidCount = 0; | |
111 | Win32Utilities::LCIDRecord *lcidRecords = Win32Utilities::getLocales(lcidCount); | |
112 | ||
113 | for(int i = 0; i < lcidCount; i += 1) { | |
114 | UErrorCode status = U_ZERO_ERROR; | |
115 | WCHAR longDateFormat[81], longTimeFormat[81], wdBuffer[256], wtBuffer[256]; | |
116 | int32_t calType = 0; | |
117 | ||
729e4ab9 A |
118 | // NULL localeID means ICU didn't recognize this locale |
119 | if (lcidRecords[i].localeID == NULL) { | |
120 | continue; | |
121 | } | |
73c04bcf | 122 | |
f3c0d7a5 A |
123 | // Some locales have had their names change over various OS releases; skip them in the test for now. |
124 | int32_t failingLocaleLCIDs[] = { | |
125 | 0x040a, /* es-ES_tradnl;es-ES-u-co-trad; */ | |
126 | 0x048c, /* fa-AF;prs-AF;prs-Arab-AF; */ | |
127 | 0x046b, /* qu-BO;quz-BO;quz-Latn-BO; */ | |
128 | 0x086b, /* qu-EC;quz-EC;quz-Latn-EC; */ | |
129 | 0x0c6b, /* qu-PE;quz-PE;quz-Latn-PE; */ | |
130 | 0x0492 /* ckb-IQ;ku-Arab-IQ; */ | |
131 | }; | |
132 | bool skip = (std::find(std::begin(failingLocaleLCIDs), std::end(failingLocaleLCIDs), lcidRecords[i].lcid) != std::end(failingLocaleLCIDs)); | |
133 | if (skip && log->logKnownIssue("13119", "Windows '@compat=host' fails on down-level versions of the OS")) { | |
134 | log->logln("ticket:13119 - Skipping LCID = 0x%04x", lcidRecords[i].lcid); | |
135 | continue; | |
136 | } | |
137 | ||
73c04bcf A |
138 | GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_SLONGDATE, longDateFormat, 81); |
139 | GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_STIMEFORMAT, longTimeFormat, 81); | |
140 | GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_RETURN_NUMBER|LOCALE_ICALENDARTYPE, (LPWSTR) calType, sizeof(int32_t)); | |
141 | ||
142 | char localeID[64]; | |
143 | ||
144 | uprv_strcpy(localeID, lcidRecords[i].localeID); | |
145 | uprv_strcat(localeID, getCalendarType(calType)); | |
146 | ||
147 | UnicodeString ubBuffer, udBuffer, utBuffer; | |
148 | Locale ulocale(localeID); | |
149 | int32_t wdLength, wtLength; | |
150 | ||
2ca993e8 A |
151 | wdLength = GetDateFormatW(lcidRecords[i].lcid, DATE_LONGDATE, &winNow, NULL, wdBuffer, UPRV_LENGTHOF(wdBuffer)); |
152 | wtLength = GetTimeFormatW(lcidRecords[i].lcid, 0, &winNow, NULL, wtBuffer, UPRV_LENGTHOF(wtBuffer)); | |
73c04bcf A |
153 | |
154 | if (uprv_strchr(localeID, '@') > 0) { | |
155 | uprv_strcat(localeID, ";"); | |
156 | } else { | |
157 | uprv_strcat(localeID, "@"); | |
158 | } | |
159 | ||
160 | uprv_strcat(localeID, "compat=host"); | |
161 | ||
162 | Locale wlocale(localeID); | |
163 | DateFormat *wbf = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, wlocale); | |
164 | DateFormat *wdf = DateFormat::createDateInstance(DateFormat::kFull, wlocale); | |
165 | DateFormat *wtf = DateFormat::createTimeInstance(DateFormat::kFull, wlocale); | |
166 | ||
167 | wbf->format(icuNow, ubBuffer); | |
168 | wdf->format(icuNow, udBuffer); | |
169 | wtf->format(icuNow, utBuffer); | |
170 | ||
f3c0d7a5 | 171 | if (ubBuffer.indexOf((const UChar *)wdBuffer, wdLength - 1, 0) < 0) { |
73c04bcf | 172 | UnicodeString baseName(wlocale.getBaseName()); |
f3c0d7a5 | 173 | UnicodeString expected((const UChar *)wdBuffer); |
73c04bcf A |
174 | |
175 | log->errln("DateTime format error for locale " + baseName + ": expected date \"" + expected + | |
176 | "\" got \"" + ubBuffer + "\""); | |
177 | } | |
178 | ||
f3c0d7a5 | 179 | if (ubBuffer.indexOf((const UChar *)wtBuffer, wtLength - 1, 0) < 0) { |
73c04bcf | 180 | UnicodeString baseName(wlocale.getBaseName()); |
f3c0d7a5 | 181 | UnicodeString expected((const UChar *)wtBuffer); |
73c04bcf A |
182 | |
183 | log->errln("DateTime format error for locale " + baseName + ": expected time \"" + expected + | |
184 | "\" got \"" + ubBuffer + "\""); | |
185 | } | |
186 | ||
f3c0d7a5 | 187 | if (udBuffer.compare((const UChar *)wdBuffer) != 0) { |
73c04bcf | 188 | UnicodeString baseName(wlocale.getBaseName()); |
f3c0d7a5 | 189 | UnicodeString expected((const UChar *)wdBuffer); |
73c04bcf A |
190 | |
191 | log->errln("Date format error for locale " + baseName + ": expected \"" + expected + | |
192 | "\" got \"" + udBuffer + "\""); | |
193 | } | |
194 | ||
f3c0d7a5 | 195 | if (utBuffer.compare((const UChar *)wtBuffer) != 0) { |
73c04bcf | 196 | UnicodeString baseName(wlocale.getBaseName()); |
f3c0d7a5 | 197 | UnicodeString expected((const UChar *)wtBuffer); |
73c04bcf A |
198 | |
199 | log->errln("Time format error for locale " + baseName + ": expected \"" + expected + | |
200 | "\" got \"" + utBuffer + "\""); | |
201 | } | |
202 | delete wbf; | |
203 | delete wdf; | |
204 | delete wtf; | |
205 | } | |
206 | ||
207 | Win32Utilities::freeLocales(lcidRecords); | |
208 | delete tz; | |
209 | } | |
210 | ||
211 | #endif /* #if !UCONFIG_NO_FORMATTING */ | |
212 | ||
f3c0d7a5 | 213 | #endif /* U_PLATFORM_USES_ONLY_WIN32_API */ |