📄 strftime_l.c
字号:
pad = L_('_'); do_number: /* Format the number according to the MODIFIER flag. */ if (modifier == L_('O') && 0 <= number_value) {#ifdef _NL_CURRENT /* Get the locale specific alternate representation of the number NUMBER_VALUE. If none exist NULL is returned. */ const CHAR_T *cp = nl_get_alt_digit (number_value HELPER_LOCALE_ARG); if (cp != NULL) { size_t digitlen = STRLEN (cp); if (digitlen != 0) { cpy (digitlen, cp); break; } }#else# if HAVE_STRFTIME goto underlying_strftime;# endif#endif } { unsigned int u = number_value; bufp = buf + sizeof (buf) / sizeof (buf[0]); negative_number = number_value < 0; if (negative_number) u = -u; do *--bufp = u % 10 + L_('0'); while ((u /= 10) != 0); } do_number_sign_and_padding: if (negative_number) *--bufp = L_('-'); if (pad != L_('-')) { int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0])) - bufp); if (padding > 0) { if (pad == L_('_')) { if ((size_t) padding >= maxsize - i) return 0; if (p) memset_space (p, padding); i += padding; width = width > padding ? width - padding : 0; } else { if ((size_t) digits >= maxsize - i) return 0; if (negative_number) { ++bufp; if (p) *p++ = L_('-'); ++i; } if (p) memset_zero (p, padding); i += padding; width = 0; } } } cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp); break; case L_('F'): if (modifier != 0) goto bad_format; subfmt = L_("%Y-%m-%d"); goto subformat; case L_('H'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_hour); case L_('I'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, hour12); case L_('k'): /* GNU extension. */ if (modifier == L_('E')) goto bad_format; DO_NUMBER_SPACEPAD (2, tp->tm_hour); case L_('l'): /* GNU extension. */ if (modifier == L_('E')) goto bad_format; DO_NUMBER_SPACEPAD (2, hour12); case L_('j'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (3, 1 + tp->tm_yday); case L_('M'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_min); case L_('m'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_mon + 1); case L_('n'): add (1, *p = L_('\n')); break; case L_('P'): to_lowcase = 1;#if !defined _NL_CURRENT && HAVE_STRFTIME format_char = L_('p');#endif /* FALLTHROUGH */ case L_('p'): if (change_case) { to_uppcase = 0; to_lowcase = 1; }#if defined _NL_CURRENT || !HAVE_STRFTIME cpy (ap_len, ampm); break;#else goto underlying_strftime;#endif case L_('R'): subfmt = L_("%H:%M"); goto subformat; case L_('r'):#if !defined _NL_CURRENT && HAVE_STRFTIME goto underlying_strftime;#else# ifdef _NL_CURRENT if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT_AMPM))) == L_('\0'))# endif subfmt = L_("%I:%M:%S %p"); goto subformat;#endif case L_('S'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, tp->tm_sec); case L_('s'): /* GNU extension. */ { struct tm ltm; time_t t; ltm = *tp; t = mktime (<m); /* Generate string value for T using time_t arithmetic; this works even if sizeof (long) < sizeof (time_t). */ bufp = buf + sizeof (buf) / sizeof (buf[0]); negative_number = t < 0; do { int d = t % 10; t /= 10; if (negative_number) { d = -d; /* Adjust if division truncates to minus infinity. */ if (0 < -1 % 10 && d < 0) { t++; d += 10; } } *--bufp = d + L_('0'); } while (t != 0); digits = 1; goto do_number_sign_and_padding; } case L_('X'): if (modifier == L_('O')) goto bad_format;#ifdef _NL_CURRENT if (! (modifier == L_('E') && (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT))) != L_('\0')))) subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT)); goto subformat;#else# if HAVE_STRFTIME goto underlying_strftime;# else /* Fall through. */# endif#endif case L_('T'): subfmt = L_("%H:%M:%S"); goto subformat; case L_('t'): add (1, *p = L_('\t')); break; case L_('u'): DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1); case L_('U'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7); case L_('V'): case L_('g'): case L_('G'): if (modifier == L_('E')) goto bad_format; { int year = tp->tm_year + TM_YEAR_BASE; int days = iso_week_days (tp->tm_yday, tp->tm_wday); if (days < 0) { /* This ISO week belongs to the previous year. */ year--; days = iso_week_days (tp->tm_yday + (365 + __isleap (year)), tp->tm_wday); } else { int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)), tp->tm_wday); if (0 <= d) { /* This ISO week belongs to the next year. */ year++; days = d; } } switch (*f) { case L_('g'): DO_NUMBER (2, (year % 100 + 100) % 100); case L_('G'): DO_NUMBER (1, year); default: DO_NUMBER (2, days / 7 + 1); } } case L_('W'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7); case L_('w'): if (modifier == L_('E')) goto bad_format; DO_NUMBER (1, tp->tm_wday); case L_('Y'): if (modifier == 'E') {#if HAVE_STRUCT_ERA_ENTRY struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); if (era) {# ifdef COMPILE_WIDE subfmt = era->era_wformat;# else subfmt = era->era_format;# endif goto subformat; }#else# if HAVE_STRFTIME goto underlying_strftime;# endif#endif } if (modifier == L_('O')) goto bad_format; else DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE); case L_('y'): if (modifier == L_('E')) {#if HAVE_STRUCT_ERA_ENTRY struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); if (era) { int delta = tp->tm_year - era->start_date[0]; DO_NUMBER (1, (era->offset + delta * era->absolute_direction)); }#else# if HAVE_STRFTIME goto underlying_strftime;# endif#endif } DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100); case L_('Z'): if (change_case) { to_uppcase = 0; to_lowcase = 1; }#if HAVE_TZNAME /* The tzset() call might have changed the value. */ if (!(zone && *zone) && tp->tm_isdst >= 0) zone = tzname[tp->tm_isdst];#endif if (! zone) zone = "";#ifdef COMPILE_WIDE { /* The zone string is always given in multibyte form. We have to transform it first. */ wchar_t *wczone; size_t len; widen (zone, wczone, len); cpy (len, wczone); }#else cpy (strlen (zone), zone);#endif break; case L_('z'): if (tp->tm_isdst < 0) break; { int diff;#if HAVE_TM_GMTOFF diff = tp->tm_gmtoff;#else if (ut) diff = 0; else { struct tm gtm; struct tm ltm; time_t lt; ltm = *tp; lt = mktime (<m); if (lt == (time_t) -1) { /* mktime returns -1 for errors, but -1 is also a valid time_t value. Check whether an error really occurred. */ struct tm tm; if (! __localtime_r (<, &tm) || ((ltm.tm_sec ^ tm.tm_sec) | (ltm.tm_min ^ tm.tm_min) | (ltm.tm_hour ^ tm.tm_hour) | (ltm.tm_mday ^ tm.tm_mday) | (ltm.tm_mon ^ tm.tm_mon) | (ltm.tm_year ^ tm.tm_year))) break; } if (! __gmtime_r (<, >m)) break; diff = tm_diff (<m, >m); }#endif if (diff < 0) { add (1, *p = L_('-')); diff = -diff; } else add (1, *p = L_('+')); diff /= 60; DO_NUMBER (4, (diff / 60) * 100 + diff % 60); } case L_('\0'): /* GNU extension: % at end of format. */ --f; /* Fall through. */ default: /* Unknown format; output the format, including the '%', since this is most likely the right thing to do if a multibyte string has been misparsed. */ bad_format: { int flen; for (flen = 1; f[1 - flen] != L_('%'); flen++) continue; cpy (flen, &f[1 - flen]); } break; } } if (p && maxsize != 0) *p = L_('\0'); return i;}#ifdef emacs/* For Emacs we have a separate interface which corresponds to the normal strftime function and does not have the extra information whether the TP arguments comes from a `gmtime' call or not. */size_temacs_strftime (s, maxsize, format, tp) char *s; size_t maxsize; const char *format; const struct tm *tp;{ return my_strftime (s, maxsize, format, tp, 0);}#endif#if defined _LIBC && !defined COMPILE_WIDEweak_alias (__strftime_l, strftime_l)#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -