kernel32: Implement Get{Time,Date}FormatEx.

This commit is contained in:
Seán de Búrca 2014-12-24 11:52:04 -05:00 committed by Alexandre Julliard
parent adc091b8da
commit 6cd0eb2027
5 changed files with 377 additions and 2 deletions

View File

@ -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

View File

@ -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()

View File

@ -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.@]
* *

View File

@ -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 */

View File

@ -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);