219 lines
7.0 KiB
C++
219 lines
7.0 KiB
C++
// © 2016 and later: Unicode, Inc. and others.
|
|
// License & terms of use: http://www.unicode.org/copyright.html
|
|
/*
|
|
********************************************************************************
|
|
* Copyright (C) 2005-2016, International Business Machines
|
|
* Corporation and others. All Rights Reserved.
|
|
********************************************************************************
|
|
*
|
|
* File WINDTTST.CPP
|
|
*
|
|
********************************************************************************
|
|
*/
|
|
|
|
#include "unicode/utypes.h"
|
|
|
|
#if U_PLATFORM_USES_ONLY_WIN32_API
|
|
|
|
#if !UCONFIG_NO_FORMATTING
|
|
|
|
#include "unicode/format.h"
|
|
#include "unicode/numfmt.h"
|
|
#include "unicode/locid.h"
|
|
#include "unicode/ustring.h"
|
|
#include "unicode/testlog.h"
|
|
#include "unicode/utmscale.h"
|
|
|
|
#include "windtfmt.h"
|
|
#include "winutil.h"
|
|
#include "windttst.h"
|
|
|
|
#include "dtfmttst.h"
|
|
|
|
#include "cmemory.h"
|
|
#include "cstring.h"
|
|
#include "locmap.h"
|
|
#include "wintzimpl.h"
|
|
|
|
# define WIN32_LEAN_AND_MEAN
|
|
# define VC_EXTRALEAN
|
|
# define NOUSER
|
|
# define NOSERVICE
|
|
# define NOIME
|
|
# define NOMCX
|
|
# include <windows.h>
|
|
|
|
#include <algorithm>
|
|
|
|
static const char *getCalendarType(int32_t type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case 1:
|
|
case 2:
|
|
return "@calendar=gregorian";
|
|
|
|
case 3:
|
|
return "@calendar=japanese";
|
|
|
|
case 6:
|
|
return "@calendar=islamic";
|
|
|
|
case 7:
|
|
return "@calendar=buddhist";
|
|
|
|
case 8:
|
|
return "@calendar=hebrew";
|
|
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
void Win32DateTimeTest::testLocales(DateFormatTest *log)
|
|
{
|
|
SYSTEMTIME winNow;
|
|
UDate icuNow = 0;
|
|
SYSTEMTIME st;
|
|
FILETIME ft;
|
|
UnicodeString zoneID;
|
|
const TimeZone *tz = TimeZone::createDefault();
|
|
TIME_ZONE_INFORMATION tzi;
|
|
|
|
tz->getID(zoneID);
|
|
if (! uprv_getWindowsTimeZoneInfo(&tzi, zoneID.getBuffer(), zoneID.length())) {
|
|
UBool found = FALSE;
|
|
int32_t ec = TimeZone::countEquivalentIDs(zoneID);
|
|
|
|
for (int z = 0; z < ec; z += 1) {
|
|
UnicodeString equiv = TimeZone::getEquivalentID(zoneID, z);
|
|
|
|
found = uprv_getWindowsTimeZoneInfo(&tzi, equiv.getBuffer(), equiv.length());
|
|
if (found) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (! found) {
|
|
GetTimeZoneInformation(&tzi);
|
|
}
|
|
}
|
|
|
|
GetSystemTime(&st);
|
|
SystemTimeToFileTime(&st, &ft);
|
|
SystemTimeToTzSpecificLocalTime(&tzi, &st, &winNow);
|
|
|
|
int64_t wftNow = ((int64_t) ft.dwHighDateTime << 32) + ft.dwLowDateTime;
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
|
|
int64_t udtsNow = utmscale_fromInt64(wftNow, UDTS_WINDOWS_FILE_TIME, &status);
|
|
|
|
icuNow = (UDate) utmscale_toInt64(udtsNow, UDTS_ICU4C_TIME, &status);
|
|
|
|
int32_t lcidCount = 0;
|
|
Win32Utilities::LCIDRecord *lcidRecords = Win32Utilities::getLocales(lcidCount);
|
|
|
|
for(int i = 0; i < lcidCount; i += 1) {
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
WCHAR longDateFormat[81], longTimeFormat[81], wdBuffer[256], wtBuffer[256];
|
|
DWORD value = 0;
|
|
int32_t calType = 0;
|
|
|
|
// NULL localeID means ICU didn't recognize this locale
|
|
if (lcidRecords[i].localeID == NULL) {
|
|
continue;
|
|
}
|
|
|
|
// Some locales have had their names change over various OS releases; skip them in the test for now.
|
|
int32_t failingLocaleLCIDs[] = {
|
|
0x040a, /* es-ES_tradnl;es-ES-u-co-trad; */
|
|
0x048c, /* fa-AF;prs-AF;prs-Arab-AF; */
|
|
0x046b, /* qu-BO;quz-BO;quz-Latn-BO; */
|
|
0x086b, /* qu-EC;quz-EC;quz-Latn-EC; */
|
|
0x0c6b, /* qu-PE;quz-PE;quz-Latn-PE; */
|
|
0x0492 /* ckb-IQ;ku-Arab-IQ; */
|
|
};
|
|
bool skip = (std::find(std::begin(failingLocaleLCIDs), std::end(failingLocaleLCIDs), lcidRecords[i].lcid) != std::end(failingLocaleLCIDs));
|
|
if (skip && log->logKnownIssue("13119", "Windows '@compat=host' fails on down-level versions of the OS")) {
|
|
log->logln("ticket:13119 - Skipping LCID = 0x%04x", lcidRecords[i].lcid);
|
|
continue;
|
|
}
|
|
|
|
GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_SLONGDATE, longDateFormat, 81);
|
|
GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_STIMEFORMAT, longTimeFormat, 81);
|
|
GetLocaleInfoW(lcidRecords[i].lcid, LOCALE_RETURN_NUMBER|LOCALE_ICALENDARTYPE, (LPWSTR)&value, sizeof(value)/sizeof(WCHAR));
|
|
|
|
calType = value;
|
|
char localeID[64];
|
|
|
|
uprv_strcpy(localeID, lcidRecords[i].localeID);
|
|
uprv_strcat(localeID, getCalendarType(calType));
|
|
|
|
UnicodeString ubBuffer, udBuffer, utBuffer;
|
|
Locale ulocale(localeID);
|
|
int32_t wdLength, wtLength;
|
|
|
|
wdLength = GetDateFormatW(lcidRecords[i].lcid, DATE_LONGDATE, &winNow, NULL, wdBuffer, UPRV_LENGTHOF(wdBuffer));
|
|
wtLength = GetTimeFormatW(lcidRecords[i].lcid, 0, &winNow, NULL, wtBuffer, UPRV_LENGTHOF(wtBuffer));
|
|
|
|
if (uprv_strchr(localeID, '@') > 0) {
|
|
uprv_strcat(localeID, ";");
|
|
} else {
|
|
uprv_strcat(localeID, "@");
|
|
}
|
|
|
|
uprv_strcat(localeID, "compat=host");
|
|
|
|
Locale wlocale(localeID);
|
|
DateFormat *wbf = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull, wlocale);
|
|
DateFormat *wdf = DateFormat::createDateInstance(DateFormat::kFull, wlocale);
|
|
DateFormat *wtf = DateFormat::createTimeInstance(DateFormat::kFull, wlocale);
|
|
|
|
wbf->format(icuNow, ubBuffer);
|
|
wdf->format(icuNow, udBuffer);
|
|
wtf->format(icuNow, utBuffer);
|
|
|
|
if (ubBuffer.indexOf((const UChar *)wdBuffer, wdLength - 1, 0) < 0) {
|
|
UnicodeString baseName(wlocale.getBaseName());
|
|
UnicodeString expected((const UChar *)wdBuffer);
|
|
|
|
log->errln("DateTime format error for locale " + baseName + ": expected date \"" + expected +
|
|
"\" got \"" + ubBuffer + "\"");
|
|
}
|
|
|
|
if (ubBuffer.indexOf((const UChar *)wtBuffer, wtLength - 1, 0) < 0) {
|
|
UnicodeString baseName(wlocale.getBaseName());
|
|
UnicodeString expected((const UChar *)wtBuffer);
|
|
|
|
log->errln("DateTime format error for locale " + baseName + ": expected time \"" + expected +
|
|
"\" got \"" + ubBuffer + "\"");
|
|
}
|
|
|
|
if (udBuffer.compare((const UChar *)wdBuffer) != 0) {
|
|
UnicodeString baseName(wlocale.getBaseName());
|
|
UnicodeString expected((const UChar *)wdBuffer);
|
|
|
|
log->errln("Date format error for locale " + baseName + ": expected \"" + expected +
|
|
"\" got \"" + udBuffer + "\"");
|
|
}
|
|
|
|
if (utBuffer.compare((const UChar *)wtBuffer) != 0) {
|
|
UnicodeString baseName(wlocale.getBaseName());
|
|
UnicodeString expected((const UChar *)wtBuffer);
|
|
|
|
log->errln("Time format error for locale " + baseName + ": expected \"" + expected +
|
|
"\" got \"" + utBuffer + "\"");
|
|
}
|
|
delete wbf;
|
|
delete wdf;
|
|
delete wtf;
|
|
}
|
|
|
|
Win32Utilities::freeLocales(lcidRecords);
|
|
delete tz;
|
|
}
|
|
|
|
#endif /* #if !UCONFIG_NO_FORMATTING */
|
|
|
|
#endif /* U_PLATFORM_USES_ONLY_WIN32_API */
|