kernel32: Implement Get{Time,Date}FormatEx.
This commit is contained in:
parent
adc091b8da
commit
6cd0eb2027
|
@ -1,6 +1,6 @@
|
||||||
@ stdcall GetDateFormatA(long long ptr str ptr long) kernel32.GetDateFormatA
|
@ stdcall GetDateFormatA(long long ptr str ptr long) kernel32.GetDateFormatA
|
||||||
@ stub GetDateFormatEx
|
@ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr) kernel32.GetDateFormatEx
|
||||||
@ stdcall GetDateFormatW(long long ptr wstr ptr long) kernel32.GetDateFormatW
|
@ stdcall GetDateFormatW(long long ptr wstr ptr long) kernel32.GetDateFormatW
|
||||||
@ stdcall GetTimeFormatA(long long ptr str ptr long) kernel32.GetTimeFormatA
|
@ stdcall GetTimeFormatA(long long ptr str ptr long) kernel32.GetTimeFormatA
|
||||||
@ stub GetTimeFormatEx
|
@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long) kernel32.GetTimeFormatEx
|
||||||
@ stdcall GetTimeFormatW(long long ptr wstr ptr long) kernel32.GetTimeFormatW
|
@ stdcall GetTimeFormatW(long long ptr wstr ptr long) kernel32.GetTimeFormatW
|
||||||
|
|
|
@ -510,6 +510,7 @@
|
||||||
@ stdcall -norelay GetCurrentThread()
|
@ stdcall -norelay GetCurrentThread()
|
||||||
@ stdcall -norelay GetCurrentThreadId()
|
@ stdcall -norelay GetCurrentThreadId()
|
||||||
@ stdcall GetDateFormatA(long long ptr str ptr long)
|
@ stdcall GetDateFormatA(long long ptr str ptr long)
|
||||||
|
@ stdcall GetDateFormatEx(wstr long ptr wstr ptr long wstr)
|
||||||
@ stdcall GetDateFormatW(long long ptr wstr ptr long)
|
@ stdcall GetDateFormatW(long long ptr wstr ptr long)
|
||||||
@ stdcall GetDaylightFlag()
|
@ stdcall GetDaylightFlag()
|
||||||
@ stdcall GetDefaultCommConfigA(str ptr long)
|
@ stdcall GetDefaultCommConfigA(str ptr long)
|
||||||
|
@ -680,6 +681,7 @@
|
||||||
@ stdcall GetTickCount()
|
@ stdcall GetTickCount()
|
||||||
@ stdcall -ret64 GetTickCount64()
|
@ stdcall -ret64 GetTickCount64()
|
||||||
@ stdcall GetTimeFormatA(long long ptr str ptr long)
|
@ stdcall GetTimeFormatA(long long ptr str ptr long)
|
||||||
|
@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long)
|
||||||
@ stdcall GetTimeFormatW(long long ptr wstr ptr long)
|
@ stdcall GetTimeFormatW(long long ptr wstr ptr long)
|
||||||
@ stdcall GetTimeZoneInformation(ptr)
|
@ stdcall GetTimeZoneInformation(ptr)
|
||||||
@ stdcall GetThreadUILanguage()
|
@ stdcall GetThreadUILanguage()
|
||||||
|
|
|
@ -846,6 +846,45 @@ INT WINAPI GetDateFormatA( LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
|
||||||
lpFormat, lpDateStr, cchOut);
|
lpFormat, lpDateStr, cchOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* GetDateFormatEx [KERNEL32.@]
|
||||||
|
*
|
||||||
|
* Format a date for a given locale.
|
||||||
|
*
|
||||||
|
* PARAMS
|
||||||
|
* localename [I] Locale to format for
|
||||||
|
* flags [I] LOCALE_ and DATE_ flags from "winnls.h"
|
||||||
|
* date [I] Date to format
|
||||||
|
* format [I] Format string, or NULL to use the locale defaults
|
||||||
|
* outbuf [O] Destination for formatted string
|
||||||
|
* bufsize [I] Size of outbuf, or 0 to calculate the resulting size
|
||||||
|
* calendar [I] Reserved, must be NULL
|
||||||
|
*
|
||||||
|
* See GetDateFormatA for notes.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Success: The number of characters written to outbuf, or that would have
|
||||||
|
* been written if bufsize is 0.
|
||||||
|
* Failure: 0. Use GetLastError() to determine the cause.
|
||||||
|
*/
|
||||||
|
INT WINAPI GetDateFormatEx(LPCWSTR localename, DWORD flags,
|
||||||
|
const SYSTEMTIME* date, LPCWSTR format,
|
||||||
|
LPWSTR outbuf, INT bufsize, LPCWSTR calendar)
|
||||||
|
{
|
||||||
|
TRACE("(%s,0x%08x,%p,%s,%p,%d,%s)\n", debugstr_w(localename), flags,
|
||||||
|
date, debugstr_w(format), outbuf, bufsize, debugstr_w(calendar));
|
||||||
|
|
||||||
|
/* Parameter is currently reserved and Windows errors if set */
|
||||||
|
if (calendar != NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NLS_GetDateTimeFormatW(LocaleNameToLCID(localename, 0),
|
||||||
|
flags | DATE_DATEVARSONLY, date, format,
|
||||||
|
outbuf, bufsize);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* GetDateFormatW [KERNEL32.@]
|
* GetDateFormatW [KERNEL32.@]
|
||||||
|
@ -913,6 +952,38 @@ INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
|
||||||
lpFormat, lpTimeStr, cchOut);
|
lpFormat, lpTimeStr, cchOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* GetTimeFormatEx [KERNEL32.@]
|
||||||
|
*
|
||||||
|
* Format a date for a given locale.
|
||||||
|
*
|
||||||
|
* PARAMS
|
||||||
|
* localename [I] Locale to format for
|
||||||
|
* flags [I] LOCALE_ and TIME_ flags from "winnls.h"
|
||||||
|
* time [I] Time to format
|
||||||
|
* format [I] Formatting overrides
|
||||||
|
* outbuf [O] Destination for formatted string
|
||||||
|
* bufsize [I] Size of outbuf, or 0 to calculate the resulting size
|
||||||
|
*
|
||||||
|
* See GetTimeFormatA for notes.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Success: The number of characters written to outbuf, or that would have
|
||||||
|
* have been written if bufsize is 0.
|
||||||
|
* Failure: 0. Use GetLastError() to determine the cause.
|
||||||
|
*/
|
||||||
|
INT WINAPI GetTimeFormatEx(LPCWSTR localename, DWORD flags,
|
||||||
|
const SYSTEMTIME* time, LPCWSTR format,
|
||||||
|
LPWSTR outbuf, INT bufsize)
|
||||||
|
{
|
||||||
|
TRACE("(%s,0x%08x,%p,%s,%p,%d)\n", debugstr_w(localename), flags, time,
|
||||||
|
debugstr_w(format), outbuf, bufsize);
|
||||||
|
|
||||||
|
return NLS_GetDateTimeFormatW(LocaleNameToLCID(localename, 0),
|
||||||
|
flags | TIME_TIMEVARSONLY, time, format,
|
||||||
|
outbuf, bufsize);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* GetTimeFormatW [KERNEL32.@]
|
* GetTimeFormatW [KERNEL32.@]
|
||||||
*
|
*
|
||||||
|
|
|
@ -39,7 +39,9 @@
|
||||||
static const WCHAR upper_case[] = {'\t','J','U','S','T','!',' ','A',',',' ','T','E','S','T',';',' ','S','T','R','I','N','G',' ','1','/','*','+','-','.','\r','\n',0};
|
static const WCHAR upper_case[] = {'\t','J','U','S','T','!',' ','A',',',' ','T','E','S','T',';',' ','S','T','R','I','N','G',' ','1','/','*','+','-','.','\r','\n',0};
|
||||||
static const WCHAR lower_case[] = {'\t','j','u','s','t','!',' ','a',',',' ','t','e','s','t',';',' ','s','t','r','i','n','g',' ','1','/','*','+','-','.','\r','\n',0};
|
static const WCHAR lower_case[] = {'\t','j','u','s','t','!',' ','a',',',' ','t','e','s','t',';',' ','s','t','r','i','n','g',' ','1','/','*','+','-','.','\r','\n',0};
|
||||||
static const WCHAR symbols_stripped[] = {'j','u','s','t','a','t','e','s','t','s','t','r','i','n','g','1',0};
|
static const WCHAR symbols_stripped[] = {'j','u','s','t','a','t','e','s','t','s','t','r','i','n','g','1',0};
|
||||||
|
static const WCHAR localeW[] = {'e','n','-','U','S',0};
|
||||||
static const WCHAR fooW[] = {'f','o','o',0};
|
static const WCHAR fooW[] = {'f','o','o',0};
|
||||||
|
static const WCHAR emptyW[] = {0};
|
||||||
|
|
||||||
static inline unsigned int strlenW( const WCHAR *str )
|
static inline unsigned int strlenW( const WCHAR *str )
|
||||||
{
|
{
|
||||||
|
@ -72,6 +74,8 @@ static inline BOOL isdigitW( WCHAR wc )
|
||||||
static HMODULE hKernel32;
|
static HMODULE hKernel32;
|
||||||
static WORD enumCount;
|
static WORD enumCount;
|
||||||
|
|
||||||
|
static INT (WINAPI *pGetTimeFormatEx)(LPCWSTR, DWORD, const SYSTEMTIME *, LPCWSTR, LPWSTR, INT);
|
||||||
|
static INT (WINAPI *pGetDateFormatEx)(LPCWSTR, DWORD, const SYSTEMTIME *, LPCWSTR, LPWSTR, INT, LPCWSTR);
|
||||||
static BOOL (WINAPI *pEnumSystemLanguageGroupsA)(LANGUAGEGROUP_ENUMPROCA, DWORD, LONG_PTR);
|
static BOOL (WINAPI *pEnumSystemLanguageGroupsA)(LANGUAGEGROUP_ENUMPROCA, DWORD, LONG_PTR);
|
||||||
static BOOL (WINAPI *pEnumLanguageGroupLocalesA)(LANGGROUPLOCALE_ENUMPROCA, LGRPID, DWORD, LONG_PTR);
|
static BOOL (WINAPI *pEnumLanguageGroupLocalesA)(LANGGROUPLOCALE_ENUMPROCA, LGRPID, DWORD, LONG_PTR);
|
||||||
static BOOL (WINAPI *pEnumUILanguagesA)(UILANGUAGE_ENUMPROCA, DWORD, LONG_PTR);
|
static BOOL (WINAPI *pEnumUILanguagesA)(UILANGUAGE_ENUMPROCA, DWORD, LONG_PTR);
|
||||||
|
@ -99,6 +103,8 @@ static void InitFunctionPointers(void)
|
||||||
hKernel32 = GetModuleHandleA("kernel32");
|
hKernel32 = GetModuleHandleA("kernel32");
|
||||||
|
|
||||||
#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
|
#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
|
||||||
|
X(GetTimeFormatEx);
|
||||||
|
X(GetDateFormatEx);
|
||||||
X(EnumSystemLanguageGroupsA);
|
X(EnumSystemLanguageGroupsA);
|
||||||
X(EnumLanguageGroupLocalesA);
|
X(EnumLanguageGroupLocalesA);
|
||||||
X(LocaleNameToLCID);
|
X(LocaleNameToLCID);
|
||||||
|
@ -612,6 +618,202 @@ static void test_GetTimeFormatA(void)
|
||||||
EXPECT_LENA; EXPECT_EQA;
|
EXPECT_LENA; EXPECT_EQA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_GetTimeFormatEx(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
SYSTEMTIME curtime;
|
||||||
|
WCHAR buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
|
||||||
|
|
||||||
|
if (!pGetTimeFormatEx)
|
||||||
|
{
|
||||||
|
win_skip("GetTimeFormatEx not supported\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&curtime, 2, sizeof(SYSTEMTIME));
|
||||||
|
STRINGSW("tt HH':'mm'@'ss", ""); /* Invalid time */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
curtime.wHour = 8;
|
||||||
|
curtime.wMinute = 56;
|
||||||
|
curtime.wSecond = 13;
|
||||||
|
curtime.wMilliseconds = 22;
|
||||||
|
STRINGSW("tt HH':'mm'@'ss", "AM 08:56@13"); /* Valid time */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
/* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetTimeFormatEx(localeW, NUO|TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
|
||||||
|
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
STRINGSW("tt HH':'mm'@'ss", "A"); /* Insufficient buffer */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, 2);
|
||||||
|
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
||||||
|
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
STRINGSW("tt HH':'mm'@'ss", "AM 08:56@13"); /* Calculate length only */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, NULL, 0);
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW;
|
||||||
|
|
||||||
|
STRINGSW("", "8 AM"); /* TIME_NOMINUTESORSECONDS, default format */
|
||||||
|
ret = pGetTimeFormatEx(localeW, NUO|TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("m1s2m3s4", ""); /* TIME_NOMINUTESORSECONDS/complex format */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_NOMINUTESORSECONDS, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret == strlenW(buffer)+1, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("", "8:56 AM"); /* TIME_NOSECONDS/Default format */
|
||||||
|
ret = pGetTimeFormatEx(localeW, NUO|TIME_NOSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("h:m:s tt", "8:56 AM"); /* TIME_NOSECONDS */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("h.@:m.@:s.@:tt", "8.@:56AM"); /* Multiple delimiters */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("s1s2s3", ""); /* Duplicate tokens */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret == strlenW(buffer)+1, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("t/tt", "A/AM"); /* AM time marker */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
curtime.wHour = 13;
|
||||||
|
STRINGSW("t/tt", "P/PM"); /* PM time marker */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("h1t2tt3m", "156"); /* TIME_NOTIMEMARKER: removes text around time marker token */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("h:m:s tt", "13:56:13 PM"); /* TIME_FORCE24HOURFORMAT */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("h:m:s", "13:56:13"); /* TIME_FORCE24HOURFORMAT doesn't add time marker */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
curtime.wHour = 14; /* change this to 14 or 2pm */
|
||||||
|
curtime.wMinute = 5;
|
||||||
|
curtime.wSecond = 3;
|
||||||
|
STRINGSW("h hh H HH m mm s ss t tt", "2 02 14 14 5 05 3 03 P PM"); /* 24 hrs, leading 0 */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
curtime.wHour = 0;
|
||||||
|
STRINGSW("h/H/hh/HH", "12/0/12/00"); /* "hh" and "HH" */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("h:m:s tt", "12:5:3 AM"); /* non-zero flags should fail with format, doesn't */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
/* try to convert formatting strings with more than two letters
|
||||||
|
* "h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS"
|
||||||
|
* NOTE: We expect any letter for which there is an upper case value
|
||||||
|
* we should see a replacement. For letters that DO NOT have
|
||||||
|
* upper case values we should see NO REPLACEMENT.
|
||||||
|
*/
|
||||||
|
curtime.wHour = 8;
|
||||||
|
curtime.wMinute = 56;
|
||||||
|
curtime.wSecond = 13;
|
||||||
|
curtime.wMilliseconds = 22;
|
||||||
|
STRINGSW("h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS",
|
||||||
|
"8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("h", "text"); /* Don't write to buffer if len is 0 */
|
||||||
|
lstrcpyW(buffer, Expected);
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, 0);
|
||||||
|
ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'",
|
||||||
|
"8 h 8 H 08 HH 56 m 13 s A t AM tt"); /* "'" preserves tokens */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("'''", "'"); /* invalid quoted string */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
/* test that msdn suggested single quotation usage works as expected */
|
||||||
|
STRINGSW("''''", "'"); /* single quote mark */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("''HHHHHH", "08"); /* Normal use */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
/* and test for normal use of the single quotation mark */
|
||||||
|
STRINGSW("'''HHHHHH'", "'HHHHHH"); /* Normal use */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("'''HHHHHH", "'HHHHHH"); /* Odd use */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("'123'tt", ""); /* TIME_NOTIMEMARKER drops literals too */
|
||||||
|
ret = pGetTimeFormatEx(localeW, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
curtime.wHour = 25;
|
||||||
|
STRINGSW("'123'tt", ""); /* Invalid time */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
curtime.wHour = 12;
|
||||||
|
curtime.wMonth = 60; /* Invalid */
|
||||||
|
STRINGSW("h:m:s", "12:56:13"); /* Invalid date */
|
||||||
|
ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
}
|
||||||
|
|
||||||
static void test_GetDateFormatA(void)
|
static void test_GetDateFormatA(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -779,6 +981,102 @@ static void test_GetDateFormatA(void)
|
||||||
"Expected '%s', got '%s'\n", Expected, buffer);
|
"Expected '%s', got '%s'\n", Expected, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_GetDateFormatEx(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
SYSTEMTIME curtime;
|
||||||
|
WCHAR buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
|
||||||
|
|
||||||
|
if (!pGetDateFormatEx)
|
||||||
|
{
|
||||||
|
win_skip("GetDateFormatEx not supported\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRINGSW("",""); /* If flags are set, then format must be NULL */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetDateFormatEx(localeW, DATE_LONGDATE, NULL,
|
||||||
|
input, buffer, COUNTOF(buffer), NULL);
|
||||||
|
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
|
||||||
|
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
|
||||||
|
EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("",""); /* NULL buffer, len > 0 */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetDateFormatEx(localeW, 0, NULL, input, NULL, COUNTOF(buffer), NULL);
|
||||||
|
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
STRINGSW("",""); /* NULL buffer, len == 0 */
|
||||||
|
ret = pGetDateFormatEx(localeW, 0, NULL, input, NULL, 0, NULL);
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
STRINGSW("",""); /* Invalid flag combination */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetDateFormatEx(localeW, DATE_LONGDATE|DATE_SHORTDATE, NULL,
|
||||||
|
input, NULL, 0, NULL);
|
||||||
|
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
|
||||||
|
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
|
||||||
|
EXPECT_EQW;
|
||||||
|
|
||||||
|
curtime.wYear = 2002;
|
||||||
|
curtime.wMonth = 10;
|
||||||
|
curtime.wDay = 23;
|
||||||
|
curtime.wDayOfWeek = 45612; /* Should be 3 - Wednesday */
|
||||||
|
curtime.wHour = 65432; /* Invalid */
|
||||||
|
curtime.wMinute = 34512; /* Invalid */
|
||||||
|
curtime.wSecond = 65535; /* Invalid */
|
||||||
|
curtime.wMilliseconds = 12345;
|
||||||
|
STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002"); /* Incorrect DOW and time */
|
||||||
|
ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer), NULL);
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
curtime.wYear = 2002;
|
||||||
|
curtime.wMonth = 10;
|
||||||
|
curtime.wDay = 23;
|
||||||
|
curtime.wDayOfWeek = 45612; /* Should be 3 - Wednesday */
|
||||||
|
curtime.wHour = 65432; /* Invalid */
|
||||||
|
curtime.wMinute = 34512; /* Invalid */
|
||||||
|
curtime.wSecond = 65535; /* Invalid */
|
||||||
|
curtime.wMilliseconds = 12345;
|
||||||
|
STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002");
|
||||||
|
ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer), emptyW); /* Use reserved arg */
|
||||||
|
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||||
|
|
||||||
|
/* Limit tests */
|
||||||
|
|
||||||
|
curtime.wYear = 1601;
|
||||||
|
curtime.wMonth = 1;
|
||||||
|
curtime.wDay = 1;
|
||||||
|
curtime.wDayOfWeek = 0; /* Irrelevant */
|
||||||
|
curtime.wHour = 0;
|
||||||
|
curtime.wMinute = 0;
|
||||||
|
curtime.wSecond = 0;
|
||||||
|
curtime.wMilliseconds = 0;
|
||||||
|
STRINGSW("dddd d MMMM yyyy","Monday 1 January 1601");
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer), NULL);
|
||||||
|
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
|
||||||
|
EXPECT_LENW; EXPECT_EQW;
|
||||||
|
|
||||||
|
curtime.wYear = 1600;
|
||||||
|
curtime.wMonth = 12;
|
||||||
|
curtime.wDay = 31;
|
||||||
|
curtime.wDayOfWeek = 0; /* Irrelevant */
|
||||||
|
curtime.wHour = 23;
|
||||||
|
curtime.wMinute = 59;
|
||||||
|
curtime.wSecond = 59;
|
||||||
|
curtime.wMilliseconds = 999;
|
||||||
|
STRINGSW("dddd d MMMM yyyy","Friday 31 December 1600");
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer), NULL);
|
||||||
|
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
|
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
static void test_GetDateFormatW(void)
|
static void test_GetDateFormatW(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -4003,7 +4301,9 @@ START_TEST(locale)
|
||||||
test_GetLocaleInfoW();
|
test_GetLocaleInfoW();
|
||||||
test_GetLocaleInfoEx();
|
test_GetLocaleInfoEx();
|
||||||
test_GetTimeFormatA();
|
test_GetTimeFormatA();
|
||||||
|
test_GetTimeFormatEx();
|
||||||
test_GetDateFormatA();
|
test_GetDateFormatA();
|
||||||
|
test_GetDateFormatEx();
|
||||||
test_GetDateFormatW();
|
test_GetDateFormatW();
|
||||||
test_GetCurrencyFormatA(); /* Also tests the W version */
|
test_GetCurrencyFormatA(); /* Also tests the W version */
|
||||||
test_GetNumberFormatA(); /* Also tests the W version */
|
test_GetNumberFormatA(); /* Also tests the W version */
|
||||||
|
|
|
@ -827,6 +827,7 @@ WINBASEAPI INT WINAPI GetCurrencyFormatA(LCID,DWORD,LPCSTR,const CURRENC
|
||||||
WINBASEAPI INT WINAPI GetCurrencyFormatW(LCID,DWORD,LPCWSTR,const CURRENCYFMTW*,LPWSTR,INT);
|
WINBASEAPI INT WINAPI GetCurrencyFormatW(LCID,DWORD,LPCWSTR,const CURRENCYFMTW*,LPWSTR,INT);
|
||||||
#define GetCurrencyFormat WINELIB_NAME_AW(GetCurrencyFormat)
|
#define GetCurrencyFormat WINELIB_NAME_AW(GetCurrencyFormat)
|
||||||
WINBASEAPI INT WINAPI GetDateFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,INT);
|
WINBASEAPI INT WINAPI GetDateFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,INT);
|
||||||
|
WINBASEAPI INT WINAPI GetDateFormatEx(LPCWSTR,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,INT,LPCWSTR);
|
||||||
WINBASEAPI INT WINAPI GetDateFormatW(LCID,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,INT);
|
WINBASEAPI INT WINAPI GetDateFormatW(LCID,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,INT);
|
||||||
#define GetDateFormat WINELIB_NAME_AW(GetDateFormat)
|
#define GetDateFormat WINELIB_NAME_AW(GetDateFormat)
|
||||||
WINBASEAPI INT WINAPI GetGeoInfoA(GEOID,GEOTYPE,LPSTR,INT,LANGID);
|
WINBASEAPI INT WINAPI GetGeoInfoA(GEOID,GEOTYPE,LPSTR,INT,LANGID);
|
||||||
|
@ -850,6 +851,7 @@ WINBASEAPI LCID WINAPI GetSystemDefaultLCID(void);
|
||||||
WINBASEAPI LANGID WINAPI GetSystemDefaultUILanguage(void);
|
WINBASEAPI LANGID WINAPI GetSystemDefaultUILanguage(void);
|
||||||
WINBASEAPI LCID WINAPI GetThreadLocale(void);
|
WINBASEAPI LCID WINAPI GetThreadLocale(void);
|
||||||
WINBASEAPI INT WINAPI GetTimeFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,INT);
|
WINBASEAPI INT WINAPI GetTimeFormatA(LCID,DWORD,const SYSTEMTIME*,LPCSTR,LPSTR,INT);
|
||||||
|
WINBASEAPI INT WINAPI GetTimeFormatEx(LPCWSTR,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,INT);
|
||||||
WINBASEAPI INT WINAPI GetTimeFormatW(LCID,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,INT);
|
WINBASEAPI INT WINAPI GetTimeFormatW(LCID,DWORD,const SYSTEMTIME*,LPCWSTR,LPWSTR,INT);
|
||||||
#define GetTimeFormat WINELIB_NAME_AW(GetTimeFormat)
|
#define GetTimeFormat WINELIB_NAME_AW(GetTimeFormat)
|
||||||
WINBASEAPI LANGID WINAPI GetUserDefaultLangID(void);
|
WINBASEAPI LANGID WINAPI GetUserDefaultLangID(void);
|
||||||
|
|
Loading…
Reference in New Issue