1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 ********************************************************************************
5 * Copyright (C) 2005-2016, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 ********************************************************************************
11 ********************************************************************************
14 #include "unicode/utypes.h"
16 #if U_PLATFORM_USES_ONLY_WIN32_API
18 #if !UCONFIG_NO_FORMATTING
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"
36 #include "wintzimpl.h"
38 # define WIN32_LEAN_AND_MEAN
48 static const char *getCalendarType(int32_t type
)
54 return "@calendar=gregorian";
57 return "@calendar=japanese";
60 return "@calendar=islamic";
63 return "@calendar=buddhist";
66 return "@calendar=hebrew";
73 void Win32DateTimeTest::testLocales(DateFormatTest
*log
)
80 const TimeZone
*tz
= TimeZone::createDefault();
81 TIME_ZONE_INFORMATION tzi
;
84 if (! uprv_getWindowsTimeZoneInfo(&tzi
, zoneID
.getBuffer(), zoneID
.length())) {
86 int32_t ec
= TimeZone::countEquivalentIDs(zoneID
);
88 for (int z
= 0; z
< ec
; z
+= 1) {
89 UnicodeString equiv
= TimeZone::getEquivalentID(zoneID
, z
);
91 found
= uprv_getWindowsTimeZoneInfo(&tzi
, equiv
.getBuffer(), equiv
.length());
98 GetTimeZoneInformation(&tzi
);
103 SystemTimeToFileTime(&st
, &ft
);
104 SystemTimeToTzSpecificLocalTime(&tzi
, &st
, &winNow
);
106 int64_t wftNow
= ((int64_t) ft
.dwHighDateTime
<< 32) + ft
.dwLowDateTime
;
107 UErrorCode status
= U_ZERO_ERROR
;
109 int64_t udtsNow
= utmscale_fromInt64(wftNow
, UDTS_WINDOWS_FILE_TIME
, &status
);
111 icuNow
= (UDate
) utmscale_toInt64(udtsNow
, UDTS_ICU4C_TIME
, &status
);
113 int32_t lcidCount
= 0;
114 Win32Utilities::LCIDRecord
*lcidRecords
= Win32Utilities::getLocales(lcidCount
);
116 for(int i
= 0; i
< lcidCount
; i
+= 1) {
117 UErrorCode status
= U_ZERO_ERROR
;
118 WCHAR longDateFormat
[81], longTimeFormat
[81], wdBuffer
[256], wtBuffer
[256];
121 // NULL localeID means ICU didn't recognize this locale
122 if (lcidRecords
[i
].localeID
== NULL
) {
126 // Some locales have had their names change over various OS releases; skip them in the test for now.
127 int32_t failingLocaleLCIDs
[] = {
128 0x040a, /* es-ES_tradnl;es-ES-u-co-trad; */
129 0x048c, /* fa-AF;prs-AF;prs-Arab-AF; */
130 0x046b, /* qu-BO;quz-BO;quz-Latn-BO; */
131 0x086b, /* qu-EC;quz-EC;quz-Latn-EC; */
132 0x0c6b, /* qu-PE;quz-PE;quz-Latn-PE; */
133 0x0492 /* ckb-IQ;ku-Arab-IQ; */
135 bool skip
= (std::find(std::begin(failingLocaleLCIDs
), std::end(failingLocaleLCIDs
), lcidRecords
[i
].lcid
) != std::end(failingLocaleLCIDs
));
136 if (skip
&& log
->logKnownIssue("13119", "Windows '@compat=host' fails on down-level versions of the OS")) {
137 log
->logln("ticket:13119 - Skipping LCID = 0x%04x", lcidRecords
[i
].lcid
);
141 GetLocaleInfoW(lcidRecords
[i
].lcid
, LOCALE_SLONGDATE
, longDateFormat
, 81);
142 GetLocaleInfoW(lcidRecords
[i
].lcid
, LOCALE_STIMEFORMAT
, longTimeFormat
, 81);
143 GetLocaleInfoW(lcidRecords
[i
].lcid
, LOCALE_RETURN_NUMBER
|LOCALE_ICALENDARTYPE
, (LPWSTR
) calType
, sizeof(int32_t));
147 uprv_strcpy(localeID
, lcidRecords
[i
].localeID
);
148 uprv_strcat(localeID
, getCalendarType(calType
));
150 UnicodeString ubBuffer
, udBuffer
, utBuffer
;
151 Locale
ulocale(localeID
);
152 int32_t wdLength
, wtLength
;
154 wdLength
= GetDateFormatW(lcidRecords
[i
].lcid
, DATE_LONGDATE
, &winNow
, NULL
, wdBuffer
, UPRV_LENGTHOF(wdBuffer
));
155 wtLength
= GetTimeFormatW(lcidRecords
[i
].lcid
, 0, &winNow
, NULL
, wtBuffer
, UPRV_LENGTHOF(wtBuffer
));
157 if (uprv_strchr(localeID
, '@') > 0) {
158 uprv_strcat(localeID
, ";");
160 uprv_strcat(localeID
, "@");
163 uprv_strcat(localeID
, "compat=host");
165 Locale
wlocale(localeID
);
166 DateFormat
*wbf
= DateFormat::createDateTimeInstance(DateFormat::kFull
, DateFormat::kFull
, wlocale
);
167 DateFormat
*wdf
= DateFormat::createDateInstance(DateFormat::kFull
, wlocale
);
168 DateFormat
*wtf
= DateFormat::createTimeInstance(DateFormat::kFull
, wlocale
);
170 wbf
->format(icuNow
, ubBuffer
);
171 wdf
->format(icuNow
, udBuffer
);
172 wtf
->format(icuNow
, utBuffer
);
174 if (ubBuffer
.indexOf((const UChar
*)wdBuffer
, wdLength
- 1, 0) < 0) {
175 UnicodeString
baseName(wlocale
.getBaseName());
176 UnicodeString
expected((const UChar
*)wdBuffer
);
178 log
->errln("DateTime format error for locale " + baseName
+ ": expected date \"" + expected
+
179 "\" got \"" + ubBuffer
+ "\"");
182 if (ubBuffer
.indexOf((const UChar
*)wtBuffer
, wtLength
- 1, 0) < 0) {
183 UnicodeString
baseName(wlocale
.getBaseName());
184 UnicodeString
expected((const UChar
*)wtBuffer
);
186 log
->errln("DateTime format error for locale " + baseName
+ ": expected time \"" + expected
+
187 "\" got \"" + ubBuffer
+ "\"");
190 if (udBuffer
.compare((const UChar
*)wdBuffer
) != 0) {
191 UnicodeString
baseName(wlocale
.getBaseName());
192 UnicodeString
expected((const UChar
*)wdBuffer
);
194 log
->errln("Date format error for locale " + baseName
+ ": expected \"" + expected
+
195 "\" got \"" + udBuffer
+ "\"");
198 if (utBuffer
.compare((const UChar
*)wtBuffer
) != 0) {
199 UnicodeString
baseName(wlocale
.getBaseName());
200 UnicodeString
expected((const UChar
*)wtBuffer
);
202 log
->errln("Time format error for locale " + baseName
+ ": expected \"" + expected
+
203 "\" got \"" + utBuffer
+ "\"");
210 Win32Utilities::freeLocales(lcidRecords
);
214 #endif /* #if !UCONFIG_NO_FORMATTING */
216 #endif /* U_PLATFORM_USES_ONLY_WIN32_API */