📄 wcsftime.c
字号:
static void __cdecl _W_store_num (
int num,
int digits,
wchar_t **out,
size_t *count,
unsigned no_lead_zeros
)
{
int temp = 0;
if (no_lead_zeros) {
_W_store_number (num, out, count);
return;
}
if ((size_t)digits < *count) {
for (digits--; (digits+1); digits--) {
(*out)[digits] = (wchar_t)(L'0' + num % 10);
num /= 10;
temp++;
}
*out += temp;
*count -= temp;
}
else
*count = 0;
}
/***
*_W_store_number() - Convert positive integer to string
*
*Purpose:
* Convert positive integer to a string and store it in the output
* buffer with no null terminator. Update both the count and
* buffer pointers.
*
* Differs from _W_store_num in that the precision is not specified,
* and no leading zeros are added.
*
* *** For internal use with wcsftime() only ***
*
* Created from xtoi.c
*
*Entry:
* int num = pointer to integer value
* wchar_t **out = address of pointer to output string
* size_t *count = address of char count (space in output area)
*
*Exit:
* none
*
*Exceptions:
* The buffer is filled until it is out of space. There is no
* way to tell beforehand (as in _W_store_num) if the buffer will
* run out of space.
*
*******************************************************************************/
static void __cdecl _W_store_number (
int num,
wchar_t **out,
size_t *count
)
{
wchar_t *p; /* pointer to traverse string */
wchar_t *firstdig; /* pointer to first digit */
wchar_t temp; /* temp char */
p = *out;
/* put the digits in the buffer in reverse order */
if (*count > 1)
{
do {
*p++ = (wchar_t) (num % 10 + L'0');
(*count)--;
} while ((num/=10) > 0 && *count > 1);
}
firstdig = *out; /* firstdig points to first digit */
*out = p; /* return pointer to next space */
p--; /* p points to last digit */
/* reverse the buffer */
do {
temp = *p;
*p-- = *firstdig;
*firstdig++ = temp; /* swap *p and *firstdig */
} while (firstdig < p); /* repeat until halfway */
}
/***
*_W_store_winword() - Store date/time in WinWord format
*
*Purpose:
* Format the date/time in the supplied WinWord format
* and store it in the supplied buffer.
*
* *** For internal use with wcsftime() only ***
*
* For simple localized Gregorian calendars (calendar type 1), the WinWord
* format is converted token by token to wcsftime conversion specifiers.
* _W_expandtime is then called to do the work. The WinWord format is
* expected to be a wide character string.
*
* For other calendar types, the Win32 APIs GetDateFormatW/GetTimeFormatW
* are instead used to do all formatting, so that this routine doesn't
* have to know about era/period strings, year offsets, etc.
*
*
*Entry:
* int field_code = code for ww_* field with format
* const struct tm *tmptr = pointer to time/date structure
* wchar_t **out = address of pointer to output string
* size_t *count = address of char count (space in output area)
* struct __lc_time_data *lc_time = pointer to locale-specific info
*
*Exit:
* BOOL true for success, false for failure
*
*Exceptions:
*
*******************************************************************************/
static BOOL __cdecl _W_store_winword (
_locale_t plocinfo,
int field_code,
const struct tm *tmptr,
wchar_t **out,
size_t *count,
struct __lc_time_data *lc_time
)
{
const wchar_t *format;
wchar_t specifier;
const wchar_t *p;
int repeat;
wchar_t *ampmstr;
unsigned no_lead_zeros;
switch (field_code)
{
case WW_SDATEFMT:
format = lc_time->_W_ww_sdatefmt;
break;
case WW_LDATEFMT:
format = lc_time->_W_ww_ldatefmt;
break;
case WW_TIMEFMT:
default:
format = lc_time->_W_ww_timefmt;
break;
}
if (lc_time->ww_caltype != 1)
{
/* We have something other than the basic Gregorian calendar */
SYSTEMTIME SystemTime;
int cch;
int (WINAPI * FormatFuncW)(LCID, DWORD, const SYSTEMTIME *,
LPCWSTR, LPWSTR, int);
if (field_code != WW_TIMEFMT)
FormatFuncW = GetDateFormatW;
else
FormatFuncW = GetTimeFormatW;
/* We leave the verification of SystemTime up to GetDateFormatW or GetTimeFormatW;
if one of those function returns 0 to indicate error, we will fall through and
call _W_expandtime() again.
*/
SystemTime.wYear = (WORD)(tmptr->tm_year + 1900);
SystemTime.wMonth = (WORD)(tmptr->tm_mon + 1);
SystemTime.wDay = (WORD)(tmptr->tm_mday);
SystemTime.wHour = (WORD)(tmptr->tm_hour);
SystemTime.wMinute = (WORD)(tmptr->tm_min);
SystemTime.wSecond = (WORD)(tmptr->tm_sec);
SystemTime.wMilliseconds = 0;
/* Find buffer size required */
cch = FormatFuncW(lc_time->ww_lcid, 0, &SystemTime,
format, NULL, 0);
if (cch != 0)
{
wchar_t *buffer;
/* Allocate buffer, first try stack, then heap */
buffer = (wchar_t *)_malloca(cch * sizeof(wchar_t));
if (buffer != NULL)
{
/* Do actual date/time formatting */
cch = FormatFuncW(lc_time->ww_lcid, 0, &SystemTime,
format, buffer, cch);
/* Copy to output buffer */
p = buffer;
while (--cch > 0 && *count > 0) {
*(*out)++ = *p++;
(*count)--;
}
_freea(buffer);
return TRUE;
}
}
/* In case of error, just fall through to localized Gregorian */
}
while (*format && *count != 0)
{
specifier = 0; /* indicate no match */
no_lead_zeros = 0; /* default is print leading zeros */
/* count the number of repetitions of this character */
for (repeat=0, p=format; *p++ == *format; repeat++);
/* leave p pointing to the beginning of the next token */
p--;
/* switch on ascii format character and determine specifier */
switch (*format)
{
case L'M':
switch (repeat)
{
case 1: no_lead_zeros = 1; /* fall thru */
case 2: specifier = L'm'; break;
case 3: specifier = L'b'; break;
case 4: specifier = L'B'; break;
} break;
case L'd':
switch (repeat)
{
case 1: no_lead_zeros = 1; /* fall thru */
case 2: specifier = L'd'; break;
case 3: specifier = L'a'; break;
case 4: specifier = L'A'; break;
} break;
case L'y':
switch (repeat)
{
case 2: specifier = L'y'; break;
case 4: specifier = L'Y'; break;
} break;
case L'h':
switch (repeat)
{
case 1: no_lead_zeros = 1; /* fall thru */
case 2: specifier = L'I'; break;
} break;
case L'H':
switch (repeat)
{
case 1: no_lead_zeros = 1; /* fall thru */
case 2: specifier = L'H'; break;
} break;
case L'm':
switch (repeat)
{
case 1: no_lead_zeros = 1; /* fall thru */
case 2: specifier = L'M'; break;
} break;
case L's': /* for compatibility; not strictly WinWord */
switch (repeat)
{
case 1: no_lead_zeros = 1; /* fall thru */
case 2: specifier = L'S'; break;
} break;
case L'A':
case L'a':
if (!_wcsicmp(format, L"am/pm"))
p = format + 5;
else if (!_wcsicmp(format, L"a/p"))
p = format + 3;
specifier = L'p';
break;
case L't': /* t or tt time marker suffix */
if ( tmptr->tm_hour <= 11 )
ampmstr = lc_time->_W_ampm[0];
else
ampmstr = lc_time->_W_ampm[1];
if ( (repeat == 1) && (*count > 0) ) {
*(*out)++ = *ampmstr++;
(*count)--;
} else {
while (*ampmstr != 0 && *count > 0) {
*(*out)++ = *ampmstr++;
(*count)--;
}
}
format = p;
continue;
case L'\'': /* literal string */
if (repeat & 1) /* odd number */
{
format += repeat;
while (*format && *count != 0)
{
if (*format == L'\'')
{
format++;
break;
}
*(*out)++ = *format++;
(*count)--;
}
}
else { /* even number */
format += repeat;
}
continue;
default: /* non-control char, print it */
break;
} /* switch */
/* expand specifier, or copy literal if specifier not found */
if (specifier)
{
if (!_W_expandtime( plocinfo,
specifier,
tmptr,
out,
count,
lc_time,
no_lead_zeros))
{
return FALSE;
}
format = p; /* bump format up to the next token */
} else {
*(*out)++ = *format++;
(*count)--;
}
} /* while */
return TRUE;
}
/***
*size_t wcsftime(wstring, maxsize, wformat, timeptr) - Format a time string
*
*Purpose:
* The wcsftime function is equivalent to the strftime function, except
* that the argument 'wstring' specifies an array of a wide string into
* which the generated output is to be placed.
* [ISO]
*
*Entry:
* wchar_t *wstring = pointer to output string
* size_t maxsize = max length of string
* const wchar_t *wformat = format control string
* const struct tm *timeptr = pointer to tb data structure
*
*Exit:
* !0 = If the total number of resulting characters including the
* terminating null is not more than 'maxsize', then return the
* number of wide chars placed in the 'wstring' array (not including the
* null terminator).
*
* 0 = Otherwise, return 0 and the contents of the string are
* indeterminate.
*
*Exceptions:
*
*******************************************************************************/
extern "C" size_t __cdecl _wcsftime_l (
wchar_t *wstring,
size_t maxsize,
const wchar_t *wformat,
const struct tm *timeptr,
_locale_t plocinfo
)
{
return (_Wcsftime_l(wstring, maxsize, wformat, timeptr, 0, plocinfo));
}
extern "C" size_t __cdecl wcsftime (
wchar_t *wstring,
size_t maxsize,
const wchar_t *wformat,
const struct tm *timeptr
)
{
return (_Wcsftime_l(wstring, maxsize, wformat, timeptr, 0, NULL));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -