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
46 static const char *getCalendarType(int32_t type
)
52 return "@calendar=gregorian";
55 return "@calendar=japanese";
58 return "@calendar=islamic";
61 return "@calendar=buddhist";
64 return "@calendar=hebrew";
71 void Win32DateTimeTest::testLocales(DateFormatTest
*log
)
78 const TimeZone
*tz
= TimeZone::createDefault();
79 TIME_ZONE_INFORMATION tzi
;
82 if (! uprv_getWindowsTimeZoneInfo(&tzi
, zoneID
.getBuffer(), zoneID
.length())) {
84 int32_t ec
= TimeZone::countEquivalentIDs(zoneID
);
86 for (int z
= 0; z
< ec
; z
+= 1) {
87 UnicodeString equiv
= TimeZone::getEquivalentID(zoneID
, z
);
89 if (found
= uprv_getWindowsTimeZoneInfo(&tzi
, equiv
.getBuffer(), equiv
.length())) {
95 GetTimeZoneInformation(&tzi
);
100 SystemTimeToFileTime(&st
, &ft
);
101 SystemTimeToTzSpecificLocalTime(&tzi
, &st
, &winNow
);
103 int64_t wftNow
= ((int64_t) ft
.dwHighDateTime
<< 32) + ft
.dwLowDateTime
;
104 UErrorCode status
= U_ZERO_ERROR
;
106 int64_t udtsNow
= utmscale_fromInt64(wftNow
, UDTS_WINDOWS_FILE_TIME
, &status
);
108 icuNow
= (UDate
) utmscale_toInt64(udtsNow
, UDTS_ICU4C_TIME
, &status
);
110 int32_t lcidCount
= 0;
111 Win32Utilities::LCIDRecord
*lcidRecords
= Win32Utilities::getLocales(lcidCount
);
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];
118 // NULL localeID means ICU didn't recognize this locale
119 if (lcidRecords
[i
].localeID
== NULL
) {
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; */
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
);
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));
144 uprv_strcpy(localeID
, lcidRecords
[i
].localeID
);
145 uprv_strcat(localeID
, getCalendarType(calType
));
147 UnicodeString ubBuffer
, udBuffer
, utBuffer
;
148 Locale
ulocale(localeID
);
149 int32_t wdLength
, wtLength
;
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
));
154 if (uprv_strchr(localeID
, '@') > 0) {
155 uprv_strcat(localeID
, ";");
157 uprv_strcat(localeID
, "@");
160 uprv_strcat(localeID
, "compat=host");
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
);
167 wbf
->format(icuNow
, ubBuffer
);
168 wdf
->format(icuNow
, udBuffer
);
169 wtf
->format(icuNow
, utBuffer
);
171 if (ubBuffer
.indexOf((const UChar
*)wdBuffer
, wdLength
- 1, 0) < 0) {
172 UnicodeString
baseName(wlocale
.getBaseName());
173 UnicodeString
expected((const UChar
*)wdBuffer
);
175 log
->errln("DateTime format error for locale " + baseName
+ ": expected date \"" + expected
+
176 "\" got \"" + ubBuffer
+ "\"");
179 if (ubBuffer
.indexOf((const UChar
*)wtBuffer
, wtLength
- 1, 0) < 0) {
180 UnicodeString
baseName(wlocale
.getBaseName());
181 UnicodeString
expected((const UChar
*)wtBuffer
);
183 log
->errln("DateTime format error for locale " + baseName
+ ": expected time \"" + expected
+
184 "\" got \"" + ubBuffer
+ "\"");
187 if (udBuffer
.compare((const UChar
*)wdBuffer
) != 0) {
188 UnicodeString
baseName(wlocale
.getBaseName());
189 UnicodeString
expected((const UChar
*)wdBuffer
);
191 log
->errln("Date format error for locale " + baseName
+ ": expected \"" + expected
+
192 "\" got \"" + udBuffer
+ "\"");
195 if (utBuffer
.compare((const UChar
*)wtBuffer
) != 0) {
196 UnicodeString
baseName(wlocale
.getBaseName());
197 UnicodeString
expected((const UChar
*)wtBuffer
);
199 log
->errln("Time format error for locale " + baseName
+ ": expected \"" + expected
+
200 "\" got \"" + utBuffer
+ "\"");
207 Win32Utilities::freeLocales(lcidRecords
);
211 #endif /* #if !UCONFIG_NO_FORMATTING */
213 #endif /* U_PLATFORM_USES_ONLY_WIN32_API */