📄 lcformat.c
字号:
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);
return NLS_GetDateTimeFormatW(lcid, dwFlags|DATE_DATEVARSONLY, lpTime,
lpFormat, lpDateStr, cchOut);
}
/******************************************************************************
* GetTimeFormatA [KERNEL32.@]
*
* Format a time for a given locale.
*
* PARAMS
* lcid [I] Locale to format for
* dwFlags [I] LOCALE_ and TIME_ flags from "winnls.h"
* lpTime [I] Time to format
* lpFormat [I] Formatting overrides
* lpTimeStr [O] Destination for formatted string
* cchOut [I] Size of lpTimeStr, or 0 to calculate the resulting size
*
* NOTES
* - If lpFormat is NULL, lpszValue 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 lpTimeStr, with tokens being replaced
* by the time values they represent.
* - The following tokens have special meanings in a time format string:
*| Token Meaning
*| ----- -------
*| h Hours with no leading zero (12-hour clock)
*| hh Hours with full two digits (12-hour clock)
*| H Hours with no leading zero (24-hour clock)
*| HH Hours with full two digits (24-hour clock)
*| m Minutes with no leading zero
*| mm Minutes with full two digits
*| s Seconds with no leading zero
*| ss Seconds with full two digits
*| t Short time marker (e.g. "A" or "P")
*| tt Long time marker (e.g. "AM", "PM")
* - 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 lpTimeStr, or that would
* have been written, if cchOut is 0.
* Failure: 0. Use GetLastError() to determine the cause.
*/
INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
LPCSTR lpFormat, LPSTR lpTimeStr, INT cchOut)
{
TRACE("(0x%04lx,0x%08lx,%p,%s,%p,%d)\n",lcid, dwFlags, lpTime,
lpFormat, lpTimeStr, cchOut);
return NLS_GetDateTimeFormatA(lcid, dwFlags|TIME_TIMEVARSONLY, lpTime,
lpFormat, lpTimeStr, cchOut);
}
/******************************************************************************
* 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,
lpFormat, lpTimeStr, cchOut);
return NLS_GetDateTimeFormatW(lcid, dwFlags|TIME_TIMEVARSONLY, lpTime,
lpFormat, lpTimeStr, cchOut);
}
/**************************************************************************
* GetNumberFormatA (KERNEL32.@)
*
* Format a number string for a given locale.
*
* PARAMS
* lcid [I] Locale to format for
* dwFlags [I] LOCALE_ flags from "winnls.h"
* lpszValue [I] String to format
* lpFormat [I] Formatting overrides
* lpNumberStr [O] Destination for formatted string
* cchOut [I] Size of lpNumberStr, or 0 to calculate the resulting size
*
* NOTES
* - lpszValue can contain only '0' - '9', '-' and '.'.
* - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
* be formatted according to the format details returned by GetLocaleInfoA().
* - This function rounds the number string if the number of decimals exceeds the
* locales normal number of decimal places.
* - If cchOut is 0, this function does not write to lpNumberStr.
* - The Ascii version of this function fails if lcid is Unicode only.
*
* RETURNS
* Success: The number of character written to lpNumberStr, or that would
* have been written, if cchOut is 0.
* Failure: 0. Use GetLastError() to determine the cause.
*/
INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags,
LPCSTR lpszValue, const NUMBERFMTA *lpFormat,
LPSTR lpNumberStr, int cchOut)
{
DWORD cp = CP_ACP;
WCHAR szDec[8], szGrp[8], szIn[128], szOut[128];
NUMBERFMTW fmt;
const NUMBERFMTW *pfmt = NULL;
INT iRet;
TRACE("(0x%04lx,0x%08lx,%s,%p,%p,%d)\n", lcid, dwFlags, lpszValue,
lpFormat, lpNumberStr, cchOut);
if (NLS_IsUnicodeOnlyLcid(lcid))
{
GetNumberFormatA_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 GetNumberFormatA_InvalidParameter;
cp = node->dwCodePage;
}
if (lpFormat)
{
memcpy(&fmt, lpFormat, sizeof(fmt));
pfmt = &fmt;
if (lpFormat->lpDecimalSep)
{
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, sizeof(szDec)/sizeof(WCHAR));
fmt.lpDecimalSep = szDec;
}
if (lpFormat->lpThousandSep)
{
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, sizeof(szGrp)/sizeof(WCHAR));
fmt.lpThousandSep = szGrp;
}
}
if (lpszValue)
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, sizeof(szIn)/sizeof(WCHAR));
if (cchOut > (int)(sizeof(szOut)/sizeof(WCHAR)))
cchOut = sizeof(szOut)/sizeof(WCHAR);
szOut[0] = '\0';
iRet = GetNumberFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
lpNumberStr ? szOut : NULL, cchOut);
if (szOut[0] && lpNumberStr)
WideCharToMultiByte(cp, 0, szOut, -1, lpNumberStr, cchOut, 0, 0);
return iRet;
}
/* Number parsing state flags */
#define NF_ISNEGATIVE 0x1 /* '-' found */
#define NF_ISREAL 0x2 /* '.' found */
#define NF_DIGITS 0x4 /* '0'-'9' found */
#define NF_DIGITS_OUT 0x8 /* Digits before the '.' found */
#define NF_ROUND 0x10 /* Number needs to be rounded */
/* Formatting options for Numbers */
#define NLS_NEG_PARENS 0 /* "(1.1)" */
#define NLS_NEG_LEFT 1 /* "-1.1" */
#define NLS_NEG_LEFT_SPACE 2 /* "- 1.1" */
#define NLS_NEG_RIGHT 3 /* "1.1-" */
#define NLS_NEG_RIGHT_SPACE 4 /* "1.1 -" */
/**************************************************************************
* GetNumberFormatW (KERNEL32.@)
*
* See GetNumberFormatA.
*/
INT WINAPI GetNumberFormatW(LCID lcid, DWORD dwFlags,
LPCWSTR lpszValue, const NUMBERFMTW *lpFormat,
LPWSTR lpNumberStr, int cchOut)
{
WCHAR szBuff[128], *szOut = szBuff + sizeof(szBuff) / sizeof(WCHAR) - 1;
WCHAR szNegBuff[8];
const WCHAR *lpszNeg = NULL, *lpszNegStart, *szSrc;
DWORD dwState = 0, dwDecimals = 0, dwGroupCount = 0, dwCurrentGroupCount = 0;
INT iRet;
TRACE("(0x%04lx,0x%08lx,%S,%p,%p,%d)\n", lcid, dwFlags, lpszValue,
lpFormat, lpNumberStr, cchOut);
if(NLS_isSystemLocale(lcid))
{
lcid = NLS_getDefaultLocale(lcid);
}
else if(!IsValidLocale(lcid, 0))
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!lpszValue || cchOut < 0 || (cchOut > 0 && !lpNumberStr) ||
(lpFormat && (dwFlags || !lpFormat->lpDecimalSep || !lpFormat->lpThousandSep)))
{
GetNumberFormatW_Error:
SetLastError(lpFormat && dwFlags ? ERROR_INVALID_FLAGS : ERROR_INVALID_PARAMETER);
return 0;
}
if (!lpFormat)
{
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
if (!node)
goto GetNumberFormatW_Error;
lpFormat = &node->fmt;
lpszNegStart = lpszNeg = GetNegative(node);
}
else
{
GetLocaleInfoW(lcid, LOCALE_SNEGATIVESIGN|(dwFlags & LOCALE_NOUSEROVERRIDE),
szNegBuff, sizeof(szNegBuff)/sizeof(WCHAR));
lpszNegStart = lpszNeg = szNegBuff;
}
lpszNeg = lpszNeg + strlenW(lpszNeg) - 1;
dwFlags &= (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP);
/* Format the number backwards into a temporary buffer */
szSrc = lpszValue;
*szOut-- = '\0';
/* Check the number for validity */
while (*szSrc)
{
if (*szSrc >= '0' && *szSrc <= '9')
{
dwState |= NF_DIGITS;
if (dwState & NF_ISREAL)
dwDecimals++;
}
else if (*szSrc == '-')
{
if (dwState)
goto GetNumberFormatW_Error; /* '-' not first character */
dwState |= NF_ISNEGATIVE;
}
else if (*szSrc == '.')
{
if (dwState & NF_ISREAL)
goto GetNumberFormatW_Error; /* More than one '.' */
dwState |= NF_ISREAL;
}
else
goto GetNumberFormatW_Error; /* Invalid char */
szSrc++;
}
szSrc--; /* Point to last character */
if (!(dwState & NF_DIGITS))
goto GetNumberFormatW_Error; /* No digits */
/* Add any trailing negative sign */
if (dwState & NF_ISNEGATIVE)
{
switch (lpFormat->NegativeOrder)
{
case NLS_NEG_PARENS:
*szOut-- = ')';
break;
case NLS_NEG_RIGHT:
case NLS_NEG_RIGHT_SPACE:
while (lpszNeg >= lpszNegStart)
*szOut-- = *lpszNeg--;
if (lpFormat->NegativeOrder == NLS_NEG_RIGHT_SPACE)
*szOut-- = ' ';
break;
}
}
/* Copy all digits up to the decimal point */
if (!lpFormat->NumDigits)
{
if (dwState & NF_ISREAL)
{
while (*szSrc != '.') /* Don't write any decimals or a separator */
{
if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
dwState |= NF_ROUND;
else
dwState &= ~NF_ROUND;
szSrc--;
}
szSrc--;
}
}
else
{
LPWSTR lpszDec = lpFormat->lpDecimalSep + strlenW(lpFormat->lpDecimalSep) - 1;
if (dwDecimals <= lpFormat->NumDigits)
{
dwDecimals = lpFormat->NumDigits - dwDecimals;
while (dwDecimals--)
*szOut-- = '0'; /* Pad to correct number of dp */
}
else
{
dwDecimals -= lpFormat->NumDigits;
/* Skip excess decimals, and determine if we have to round the number */
while (dwDecimals--)
{
if (*szSrc >= '5' || (*szSrc == '4' && (dwState & NF_ROUND)))
dwState |= NF_ROUND;
else
dwState &= ~NF_ROUND;
szSrc--;
}
}
if (dwState & NF_ISREAL)
{
while (*szSrc != '.')
{
if (dwState & NF_ROUND)
{
if (*szSrc == '9')
*szOut-- = '0'; /* continue rounding */
else
{
dwState &= ~NF_ROUND;
*szOut-- = (*szSrc)+1;
}
szSrc--;
}
else
*szOut-- = *szSrc--; /* Write existing decimals */
}
szSrc--; /* Skip '.' */
}
while (lpszDec >= lpFormat->lpDecimalSep)
*szOut-- = *lpszDec--; /* Write decimal separator */
}
dwGroupCount = lpFormat->Grouping == 32 ? 3 : lpFormat->Grouping;
/* Write the remaining whole number digits, including grouping chars */
while (szSrc >= lpszValue && *szSrc >= '0' && *szSrc <= '9')
{
if (dwState & NF_ROUND)
{
if (*szSrc == '9')
*szOut-- = '0'; /* continue rounding */
else
{
dwState &= ~NF_ROUND;
*szOut-- = (*szSrc)+1;
}
szSrc--;
}
else
*szOut-- = *szSrc--;
dwState |= NF_DIGITS_OUT;
dwCurrentGroupCount++;
if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount && *szSrc != '-')
{
LPWSTR lpszGrp = lpFormat->lpThousandSep + strlenW(lpFormat->lpThousandSep) - 1;
while (lpszGrp >= lpFormat->lpThousandSep)
*szOut-- = *lpszGrp--; /* Write grouping char */
dwCurrentGroupCount = 0;
if (lpFormat->Grouping == 32)
dwGroupCount = 2; /* Indic grouping: 3 then 2 */
}
}
if (dwState & NF_ROUND)
{
*szOut-- = '1'; /* e.g. .6 > 1.0 */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -