📄 lcformat.c
字号:
}
}
if (!lpFormat)
{
/* Use the appropriate default format */
if (dwFlags & DATE_DATEVARSONLY)
{
if (dwFlags & DATE_YEARMONTH)
lpFormat = GetYearMonth(node);
else if (dwFlags & DATE_LONGDATE)
lpFormat = GetLongDate(node);
else
lpFormat = GetShortDate(node);
}
else
lpFormat = GetTime(node);
}
if (!lpTime)
{
GetSystemTime(&st); /* Default to current time */
lpTime = &st;
}
else
{
if (dwFlags & DATE_DATEVARSONLY)
{
FILETIME ftTmp;
/* Verify the date and correct the D.O.W. if needed */
memset(&st, 0, sizeof(st));
st.wYear = lpTime->wYear;
st.wMonth = lpTime->wMonth;
st.wDay = lpTime->wDay;
if (st.wDay > 31 || st.wMonth > 12 || !SystemTimeToFileTime(&st, &ftTmp))
goto NLS_GetDateTimeFormatW_InvalidParameter;
FileTimeToSystemTime(&ftTmp, &st);
lpTime = &st;
}
if (dwFlags & TIME_TIMEVARSONLY)
{
/* Verify the time */
if (lpTime->wHour > 24 || lpTime->wMinute > 59 || lpTime->wSecond > 59)
goto NLS_GetDateTimeFormatW_InvalidParameter;
}
}
/* Format the output */
while (*lpFormat)
{
if (IsLiteralMarker(*lpFormat))
{
/* Start of a literal string */
lpFormat++;
/* Loop until the end of the literal marker or end of the string */
while (*lpFormat)
{
if (IsLiteralMarker(*lpFormat))
{
lpFormat++;
if (!IsLiteralMarker(*lpFormat))
break; /* Terminating literal marker */
}
if (!cchOut)
cchWritten++; /* Count size only */
else if (cchWritten >= cchOut)
goto NLS_GetDateTimeFormatW_Overrun;
else if (!bSkipping)
{
lpStr[cchWritten] = *lpFormat;
cchWritten++;
}
lpFormat++;
}
}
else if ((dwFlags & DATE_DATEVARSONLY && IsDateFmtChar(*lpFormat)) ||
(dwFlags & TIME_TIMEVARSONLY && IsTimeFmtChar(*lpFormat)))
{
char buffA[32];
WCHAR buff[32], fmtChar;
LPCWSTR szAdd = NULL;
DWORD dwVal = 0;
int count = 0, dwLen;
bSkipping = FALSE;
fmtChar = *lpFormat;
while (*lpFormat == fmtChar)
{
count++;
lpFormat++;
}
buff[0] = '\0';
switch(fmtChar)
{
case 'd':
if (count >= 4)
szAdd = GetLongDay(node, (lpTime->wDayOfWeek + 6) % 7);
else if (count == 3)
szAdd = GetShortDay(node, (lpTime->wDayOfWeek + 6) % 7);
else
{
dwVal = lpTime->wDay;
szAdd = buff;
}
break;
case 'M':
if (count >= 4)
szAdd = GetLongMonth(node, lpTime->wMonth - 1);
else if (count == 3)
szAdd = GetShortMonth(node, lpTime->wMonth - 1);
else
{
dwVal = lpTime->wMonth;
szAdd = buff;
}
break;
case 'y':
if (count >= 4)
{
count = 4;
dwVal = lpTime->wYear;
}
else
{
count = count > 2 ? 2 : count;
dwVal = lpTime->wYear % 100;
}
szAdd = buff;
break;
case 'g':
if (count == 2)
{
/* FIXME: Our GetCalendarInfo() does not yet support CAL_SERASTRING.
* When it is fixed, this string should be cached in 'node'.
*/
FIXME("Should be using GetCalendarInfo(CAL_SERASTRING), defaulting to 'AD'\n");
buff[0] = 'A'; buff[1] = 'D'; buff[2] = '\0';
}
else
{
buff[0] = 'g'; buff[1] = '\0'; /* Add a literal 'g' */
}
szAdd = buff;
break;
case 'h':
if (!(dwFlags & TIME_FORCE24HOURFORMAT))
{
count = count > 2 ? 2 : count;
dwVal = lpTime->wHour == 0 ? 12 : (lpTime->wHour - 1) % 12 + 1;
szAdd = buff;
break;
}
/* .. fall through if we are forced to output in 24 hour format */
case 'H':
count = count > 2 ? 2 : count;
dwVal = lpTime->wHour;
szAdd = buff;
break;
case 'm':
if (dwFlags & TIME_NOMINUTESORSECONDS)
{
cchWritten = lastFormatPos; /* Skip */
bSkipping = TRUE;
}
else
{
count = count > 2 ? 2 : count;
dwVal = lpTime->wMinute;
szAdd = buff;
}
break;
case 's':
if (dwFlags & (TIME_NOSECONDS|TIME_NOMINUTESORSECONDS))
{
cchWritten = lastFormatPos; /* Skip */
bSkipping = TRUE;
}
else
{
count = count > 2 ? 2 : count;
dwVal = lpTime->wSecond;
szAdd = buff;
}
break;
case 't':
if (dwFlags & TIME_NOTIMEMARKER)
{
cchWritten = lastFormatPos; /* Skip */
bSkipping = TRUE;
}
else
{
if (count == 1)
szAdd = lpTime->wHour < 12 ? node->szShortAM : node->szShortPM;
else
szAdd = lpTime->wHour < 12 ? GetAM(node) : GetPM(node);
}
break;
}
if (szAdd == buff && buff[0] == '\0')
{
/* We have a numeric value to add */
sprintf(buffA, "%.*ld", count, dwVal);
MultiByteToWideChar(CP_ACP, 0, buffA, -1, buff, sizeof(buff)/sizeof(WCHAR));
}
dwLen = szAdd ? strlenW(szAdd) : 0;
if (cchOut && dwLen)
{
if (cchWritten + dwLen < cchOut)
memcpy(lpStr + cchWritten, szAdd, dwLen * sizeof(WCHAR));
else
{
memcpy(lpStr + cchWritten, szAdd, (cchOut - cchWritten) * sizeof(WCHAR));
goto NLS_GetDateTimeFormatW_Overrun;
}
}
cchWritten += dwLen;
lastFormatPos = cchWritten; /* Save position of last output format text */
}
else
{
/* Literal character */
if (!cchOut)
cchWritten++; /* Count size only */
else if (cchWritten >= cchOut)
goto NLS_GetDateTimeFormatW_Overrun;
else if (!bSkipping || *lpFormat == ' ')
{
lpStr[cchWritten] = *lpFormat;
cchWritten++;
}
lpFormat++;
}
}
/* Final string terminator and sanity check */
if (cchOut)
{
if (cchWritten >= cchOut)
goto NLS_GetDateTimeFormatW_Overrun;
else
lpStr[cchWritten] = '\0';
}
cchWritten++; /* Include terminating NUL */
TRACE("returning length=%d, ouput='%S'\n", cchWritten, lpStr);
return cchWritten;
NLS_GetDateTimeFormatW_Overrun:
TRACE("returning 0, (ERROR_INSUFFICIENT_BUFFER)\n");
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
/******************************************************************************
* NLS_GetDateTimeFormatA <internal>
*
* ASCII wrapper for GetDateFormatA/GetTimeFormatA.
*/
static INT NLS_GetDateTimeFormatA(LCID lcid, DWORD dwFlags,
const SYSTEMTIME* lpTime,
LPCSTR lpFormat, LPSTR lpStr, INT cchOut)
{
DWORD cp = CP_ACP;
WCHAR szFormat[128], szOut[128];
INT iRet;
TRACE("(0x%04lx,0x%08lx,%p,%s,%p,%d)\n", lcid, dwFlags, lpTime,
lpFormat, lpStr, cchOut);
if (NLS_IsUnicodeOnlyLcid(lcid))
{
GetDateTimeFormatA_InvalidParameter:
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!(dwFlags & LOCALE_USE_CP_ACP))
{
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
if (!node)
goto GetDateTimeFormatA_InvalidParameter;
cp = node->dwCodePage;
}
if (lpFormat)
MultiByteToWideChar(cp, 0, lpFormat, -1, szFormat, sizeof(szFormat)/sizeof(WCHAR));
if (cchOut > (int)(sizeof(szOut)/sizeof(WCHAR)))
cchOut = sizeof(szOut)/sizeof(WCHAR);
szOut[0] = '\0';
iRet = NLS_GetDateTimeFormatW(lcid, dwFlags, lpTime, lpFormat ? szFormat : NULL,
lpStr ? szOut : NULL, cchOut);
if (lpStr)
{
if (szOut[0])
WideCharToMultiByte(cp, 0, szOut, -1, lpStr, cchOut, 0, 0);
else if (cchOut && iRet)
*lpStr = '\0';
}
return iRet;
}
/******************************************************************************
* GetDateFormatA [KERNEL32.@]
*
* Format a date for a given locale.
*
* PARAMS
* lcid [I] Locale to format for
* dwFlags [I] LOCALE_ and DATE_ flags from "winnls.h"
* lpTime [I] Date to format
* lpFormat [I] Format string, or NULL to use the system defaults
* lpDateStr [O] Destination for formatted string
* cchOut [I] Size of lpDateStr, or 0 to calculate the resulting size
*
* NOTES
* - If lpFormat is NULL, lpDateStr will be formatted according to the format
* details returned by GetLocaleInfoA() and modified by dwFlags.
* - lpFormat is a string of characters and formatting tokens. Any characters
* in the string are copied verbatim to lpDateStr, with tokens being replaced
* by the date values they represent.
* - The following tokens have special meanings in a date format string:
*| Token Meaning
*| ----- -------
*| d Single digit day of the month (no leading 0)
*| dd Double digit day of the month
*| ddd Short name for the day of the week
*| dddd Long name for the day of the week
*| M Single digit month of the year (no leading 0)
*| MM Double digit month of the year
*| MMM Short name for the month of the year
*| MMMM Long name for the month of the year
*| y Double digit year number (no leading 0)
*| yy Double digit year number
*| yyyy Four digit year number
*| gg Era string, for example 'AD'.
* - To output any literal character that could be misidentified as a token,
* enclose it in single quotes.
* - The Ascii version of this function fails if lcid is Unicode only.
*
* RETURNS
* Success: The number of character written to lpDateStr, or that would
* have been written, if cchOut is 0.
* Failure: 0. Use GetLastError() to determine the cause.
*/
INT WINAPI GetDateFormatA( LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
LPCSTR lpFormat, LPSTR lpDateStr, INT cchOut)
{
TRACE("(0x%04lx,0x%08lx,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
lpFormat, lpDateStr, cchOut);
return NLS_GetDateTimeFormatA(lcid, dwFlags | DATE_DATEVARSONLY, lpTime,
lpFormat, lpDateStr, cchOut);
}
/******************************************************************************
* GetDateFormatW [KERNEL32.@]
*
* See GetDateFormatA.
*/
INT WINAPI GetDateFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
LPCWSTR lpFormat, LPWSTR lpDateStr, INT cchOut)
{
TRACE("(0x%04lx,0x%08lx,%p,%S,%p,%d)\n", lcid, dwFlags, lpTime,
lpFormat, lpDateStr, cchOut);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -