kernelbase: Reimplement GetTimeFormatW/Ex() using get_locale_info().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2022-05-04 08:52:08 +02:00
parent 6ccdd7f8f5
commit 1b127e24dc
4 changed files with 157 additions and 51 deletions

View File

@ -870,8 +870,8 @@
@ stdcall GetTickCount()
@ stdcall -ret64 GetTickCount64()
@ 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 -import GetTimeFormatEx(wstr long ptr wstr ptr long)
@ stdcall -import GetTimeFormatW(long long ptr wstr ptr long)
@ stdcall -import GetTimeZoneInformation(ptr)
@ stdcall -import GetTimeZoneInformationForYear(long ptr ptr)
# @ stub GetUILanguageInfo

View File

@ -830,50 +830,3 @@ INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
return NLS_GetDateTimeFormatA(lcid, dwFlags|TIME_TIMEVARSONLY, lpTime,
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%08lx,%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.@]
*
* See GetTimeFormatA.
*/
INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
LPCWSTR lpFormat, LPWSTR lpTimeStr, INT cchOut)
{
TRACE("(0x%04lx,0x%08lx,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
debugstr_w(lpFormat), lpTimeStr, cchOut);
return NLS_GetDateTimeFormatW(lcid, dwFlags|TIME_TIMEVARSONLY, lpTime,
lpFormat, lpTimeStr, cchOut);
}

View File

@ -756,8 +756,8 @@
@ stdcall GetTickCount()
@ stdcall -ret64 GetTickCount64()
@ stdcall GetTimeFormatA(long long ptr str ptr long) kernel32.GetTimeFormatA
@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long) kernel32.GetTimeFormatEx
@ stdcall GetTimeFormatW(long long ptr wstr ptr long) kernel32.GetTimeFormatW
@ stdcall GetTimeFormatEx(wstr long ptr wstr ptr long)
@ stdcall GetTimeFormatW(long long ptr wstr ptr long)
@ stdcall GetTimeZoneInformation(ptr)
@ stdcall GetTimeZoneInformationForYear(long ptr ptr)
@ stdcall GetTokenInformation(long long ptr long ptr)

View File

@ -6966,6 +6966,120 @@ static int get_date_format( const NLS_LOCALE_DATA *locale, DWORD flags, const SY
}
static int get_time_format( const NLS_LOCALE_DATA *locale, DWORD flags, const SYSTEMTIME *systime,
const WCHAR *format, WCHAR *buffer, int len )
{
DWORD override = flags & LOCALE_NOUSEROVERRIDE;
WCHAR *p, *last, fmt[80], output[256];
SYSTEMTIME time;
int i, ret, val, count;
BOOL skip = FALSE;
if (!format)
{
get_locale_info( locale, 0, LOCALE_STIMEFORMAT | override, fmt, ARRAY_SIZE(fmt) );
format = fmt;
}
else if (override)
{
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
if (systime)
{
time = *systime;
if (time.wMilliseconds > 999 || time.wSecond > 59 || time.wMinute > 59 || time.wHour > 23)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
}
else GetLocalTime( &time );
for (p = last = output; *format; format += count)
{
count = get_pattern_len( format, L"Hhmst" );
switch (*format)
{
case '\'':
for (i = 1; i < count; i++)
{
if (format[i] == '\'') i++;
if (!skip && i < count) *p++ = format[i];
}
continue;
case 'H':
val = time.wHour;
break;
case 'h':
val = time.wHour;
if (!(flags & TIME_FORCE24HOURFORMAT))
{
val %= 12;
if (!val) val = 12;
}
break;
case 'm':
if (flags & TIME_NOMINUTESORSECONDS)
{
p = last;
skip = TRUE;
continue;
}
val = time.wMinute;
break;
case 's':
if (flags & (TIME_NOMINUTESORSECONDS | TIME_NOSECONDS))
{
p = last;
skip = TRUE;
continue;
}
val = time.wSecond;
break;
case 't':
if (flags & TIME_NOTIMEMARKER)
{
p = last;
skip = TRUE;
continue;
}
val = time.wHour < 12 ? LOCALE_S1159 : LOCALE_S2359;
ret = get_locale_info( locale, 0, val | override, p, output + ARRAY_SIZE(output) - p );
p += (count > 1) ? ret - 1 : 1;
skip = FALSE;
continue;
default:
if (!skip || *format == ' ') *p++ = *format;
continue;
}
p += swprintf( p, output + ARRAY_SIZE(output) - p, L"%.*u", min( 2, count ), val );
last = p;
skip = FALSE;
}
*p++ = 0;
ret = p - output;
if (!len) return ret;
lstrcpynW( buffer, output, len );
if (ret > len)
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
return 0;
}
return ret;
}
/**************************************************************************
* GetNumberFormatW (kernelbase.@)
*/
@ -7081,3 +7195,42 @@ int WINAPI GetDateFormatEx( const WCHAR *name, DWORD flags, const SYSTEMTIME *sy
TRACE( "(%s,%lx,%p,%s,%p,%d)\n", debugstr_w(name), flags, systime, debugstr_w(format), buffer, len );
return get_date_format( locale, flags, systime, format, buffer, len );
}
/***********************************************************************
* GetTimeFormatW (kernelbase.@)
*/
int WINAPI GetTimeFormatW( LCID lcid, DWORD flags, const SYSTEMTIME *systime,
const WCHAR *format, WCHAR *buffer, int len )
{
const NLS_LOCALE_DATA *locale = NlsValidateLocale( &lcid, 0 );
if (len < 0 || (len && !buffer) || !locale)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
TRACE( "(%04lx,%lx,%p,%s,%p,%d)\n", lcid, flags, systime, debugstr_w(format), buffer, len );
return get_time_format( locale, flags, systime, format, buffer, len );
}
/***********************************************************************
* GetTimeFormatEx (kernelbase.@)
*/
int WINAPI GetTimeFormatEx( const WCHAR *name, DWORD flags, const SYSTEMTIME *systime,
const WCHAR *format, WCHAR *buffer, int len )
{
LCID lcid;
const NLS_LOCALE_DATA *locale = get_locale_by_name( name, &lcid );
if (len < 0 || (len && !buffer) || !locale)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
TRACE( "(%s,%lx,%p,%s,%p,%d)\n", debugstr_w(name), flags, systime, debugstr_w(format), buffer, len );
return get_time_format( locale, flags, systime, format, buffer, len );
}