1 /* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 Free Software
4 NOTE: The canonical source of this file is maintained with the GNU C Library.
5 Bugs can be reported to bug-glibc@prep.ai.mit.edu.
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 # define HAVE_MBRLEN 1
23 # define HAVE_STRUCT_ERA_ENTRY 1
24 # define HAVE_TM_GMTOFF 1
25 # define HAVE_TM_ZONE 1
26 # define HAVE_TZNAME 1
28 # define MULTIBYTE_IS_FORMAT_SAFE 1
29 # include "../locale/localeinfo.h"
33 # include "fprintftime.h"
40 #if HAVE_TZNAME && !HAVE_DECL_TZNAME
41 extern char *tzname[];
44 /* Do multibyte processing if multibytes are supported, unless
45 multibyte sequences are safe in formats. Multibyte sequences are
46 safe if they cannot contain byte sequences that look like format
47 conversion specifications. The GNU C Library uses UTF8 multibyte
48 encoding, which is safe for formats, but strftime.c can be used
49 with other C libraries that use unsafe encodings. */
50 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
56 /* Simulate mbrlen with mblen as best we can. */
57 # define mbstate_t int
58 # define mbrlen(s, n, ps) mblen (s, n)
59 # define mbsinit(ps) (*(ps) == 0)
61 static const mbstate_t mbstate_zero;
72 # define CHAR_T wchar_t
73 # define UCHAR_T unsigned int
74 # define L_(Str) L##Str
75 # define NLW(Sym) _NL_W##Sym
77 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
78 # define STRLEN(s) __wcslen (s)
82 # define UCHAR_T unsigned char
86 # define MEMCPY(d, s, n) memcpy (d, s, n)
87 # define STRLEN(s) strlen (s)
90 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
93 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
98 /* Shift A right by B bits portably, by dividing A by 2**B and
99 truncating towards minus infinity. A and B should be free of side
100 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
101 INT_BITS is the number of useful bits in an int. GNU code can
102 assume that INT_BITS is at least 32.
104 ISO C99 says that A >> B is implementation-defined if A < 0. Some
105 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
106 right in the usual way when A < 0, so SHR falls back on division if
107 ordinary A >> B doesn't seem to be the usual signed shift. */
111 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
113 /* Bound on length of the string representing an integer type or expression T.
114 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
115 add 1 for integer division truncation; add 1 more for a minus sign
117 #define INT_STRLEN_BOUND(t) \
118 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
120 #define TM_YEAR_BASE 1900
123 /* Nonzero if YEAR is a leap year (every 4 years,
124 except every 100th isn't, and every 400th is). */
125 # define __isleap(year) \
126 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
131 # define tzname __tzname
132 # define tzset __tzset
136 /* Portable standalone applications should supply a "time.h" that
137 declares a POSIX-compliant localtime_r, for the benefit of older
138 implementations that lack localtime_r or have a nonstandard one.
139 See the gnulib time_r module for one way to implement this. */
141 # undef __localtime_r
142 # define __gmtime_r gmtime_r
143 # define __localtime_r localtime_r
148 # define FPRINTFTIME 0
152 # define STREAM_OR_CHAR_T FILE
153 # define STRFTIME_ARG(x) /* empty */
155 # define STREAM_OR_CHAR_T CHAR_T
156 # define STRFTIME_ARG(x) x,
160 # define memset_byte(P, Len, Byte) \
161 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
162 # define memset_space(P, Len) memset_byte (P, Len, ' ')
163 # define memset_zero(P, Len) memset_byte (P, Len, '0')
164 #elif defined COMPILE_WIDE
165 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
166 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
168 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
169 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
173 # define advance(P, N)
175 # define advance(P, N) ((P) += (N))
182 int _delta = width - _n; \
183 int _incr = _n + (_delta > 0 ? _delta : 0); \
184 if ((size_t) _incr >= maxsize - i) \
188 if (digits == 0 && _delta > 0) \
190 if (pad == L_('0')) \
191 memset_zero (p, _delta); \
193 memset_space (p, _delta); \
202 # define add1(C) add (1, fputc (C, p))
204 # define add1(C) add (1, *p = C)
211 fwrite_lowcase (p, (s), _n); \
212 else if (to_uppcase) \
213 fwrite_uppcase (p, (s), _n); \
215 fwrite ((s), _n, 1, p))
220 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
221 else if (to_uppcase) \
222 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
224 MEMCPY ((void *) p, (void const *) (s), _n))
228 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
229 # undef __mbsrtowcs_l
230 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
232 # define widen(os, ws, l) \
235 const char *__s = os; \
236 memset (&__st, '\0', sizeof (__st)); \
237 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
238 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
239 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
244 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
245 /* We use this code also for the extended locale handling where the
246 function gets as an additional argument the locale which has to be
247 used. To access the values we have to redefine the _NL_CURRENT
249 # define strftime __strftime_l
250 # define wcsftime __wcsftime_l
252 # define _NL_CURRENT(category, item) \
253 (current->values[_NL_ITEM_INDEX (item)].string)
254 # define LOCALE_ARG , loc
255 # define LOCALE_PARAM_PROTO , __locale_t loc
256 # define HELPER_LOCALE_ARG , current
258 # define LOCALE_PARAM_PROTO
261 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
263 # define HELPER_LOCALE_ARG
268 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
269 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
270 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
272 # define TOUPPER(Ch, L) towupper (Ch)
273 # define TOLOWER(Ch, L) towlower (Ch)
276 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
277 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
278 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
280 # define TOUPPER(Ch, L) toupper (Ch)
281 # define TOLOWER(Ch, L) tolower (Ch)
284 /* We don't use `isdigit' here since the locale dependent
285 interpretation is not what we want here. We only need to accept
286 the arabic digits in the ASCII range. One day there is perhaps a
287 more reliable way to accept other sets of digits. */
288 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
292 fwrite_lowcase (FILE *fp, const CHAR_T *src, size_t len)
296 fputc (TOLOWER ((UCHAR_T) *src, loc), fp);
302 fwrite_uppcase (FILE *fp, const CHAR_T *src, size_t len)
306 fputc (TOUPPER ((UCHAR_T) *src, loc), fp);
312 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
313 size_t len LOCALE_PARAM_PROTO)
316 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
321 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
322 size_t len LOCALE_PARAM_PROTO)
325 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
332 /* Yield the difference between *A and *B,
333 measured in seconds, ignoring leap seconds. */
334 # define tm_diff ftime_tm_diff
336 tm_diff (const struct tm *a, const struct tm *b)
338 /* Compute intervening leap days correctly even if year is negative.
339 Take care to avoid int overflow in leap day calculations,
340 but it's OK to assume that A and B are close to each other. */
341 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
342 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
343 int a100 = a4 / 25 - (a4 % 25 < 0);
344 int b100 = b4 / 25 - (b4 % 25 < 0);
345 int a400 = SHR (a100, 2);
346 int b400 = SHR (b100, 2);
347 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
348 int years = a->tm_year - b->tm_year;
349 int days = (365 * years + intervening_leap_days
350 + (a->tm_yday - b->tm_yday));
351 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
352 + (a->tm_min - b->tm_min))
353 + (a->tm_sec - b->tm_sec));
355 #endif /* ! HAVE_TM_GMTOFF */
359 /* The number of days from the first day of the first ISO week of this
360 year to the year day YDAY with week day WDAY. ISO weeks start on
361 Monday; the first ISO week has the year's first Thursday. YDAY may
362 be as small as YDAY_MINIMUM. */
363 #define ISO_WEEK_START_WDAY 1 /* Monday */
364 #define ISO_WEEK1_WDAY 4 /* Thursday */
365 #define YDAY_MINIMUM (-366)
370 iso_week_days (int yday, int wday)
372 /* Add enough to the first operand of % to make it nonnegative. */
373 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
375 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
376 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
380 /* When compiling this file, GNU applications can #define my_strftime
381 to a symbol (typically nstrftime) to get an extended strftime with
382 extra arguments UT and NS. Emacs is a special case for now, but
383 this Emacs-specific code can be removed once Emacs's config.h
384 defines my_strftime. */
385 #if defined emacs && !defined my_strftime
386 # define my_strftime nstrftime
391 # define my_strftime fprintftime
395 # define extra_args , ut, ns
396 # define extra_args_spec , int ut, int ns
398 # if defined COMPILE_WIDE
399 # define my_strftime wcsftime
400 # define nl_get_alt_digit _nl_get_walt_digit
402 # define my_strftime strftime
403 # define nl_get_alt_digit _nl_get_alt_digit
406 # define extra_args_spec
407 /* We don't have this information in general. */
413 /* Just like my_strftime, below, but with one more parameter, UPCASE,
414 to indicate that the result should be converted to upper case. */
416 strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
417 STRFTIME_ARG (size_t maxsize)
418 const CHAR_T *format,
419 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
421 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
422 struct locale_data *const current = loc->__locales[LC_TIME];
425 size_t maxsize = (size_t) -1;
428 int hour12 = tp->tm_hour;
430 /* We cannot make the following values variables since we must delay
431 the evaluation of these values until really needed since some
432 expressions might not be valid in every situation. The `struct tm'
433 might be generated by a strptime() call that initialized
434 only a few elements. Dereference the pointers only if the format
435 requires this. Then it is ok to fail if the pointers are invalid. */
437 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
439 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
441 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
443 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
445 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
446 ? NLW(PM_STR) : NLW(AM_STR)))
448 # define aw_len STRLEN (a_wkday)
449 # define am_len STRLEN (a_month)
450 # define ap_len STRLEN (ampm)
454 STREAM_OR_CHAR_T *p = s;
456 #if DO_MULTIBYTE && !defined COMPILE_WIDE
457 const char *format_end = NULL;
460 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
461 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
462 by localtime. On such systems, we must either use the tzset and
463 localtime wrappers to work around the bug (which sets
464 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
465 struct tm copy = *tp;
471 /* The POSIX test suite assumes that setting
472 the environment variable TZ to a new value before calling strftime()
473 will influence the result (the %Z format) even if the information in
474 TP is computed with a totally different time zone.
475 This is bogus: though POSIX allows bad behavior like this,
476 POSIX does not require it. Do the right thing instead. */
477 zone = (const char *) tp->tm_zone;
482 if (! (zone && *zone))
487 /* POSIX.1 requires that local time zone information be used as
488 though strftime called tzset. */
501 for (f = format; *f != '\0'; ++f)
503 int pad = 0; /* Padding for number ('-', '_', or 0). */
504 int modifier; /* Field modifier ('E', 'O', or 0). */
505 int digits = 0; /* Max digits for numeric format. */
506 int number_value; /* Numeric value to be printed. */
507 unsigned int u_number_value; /* (unsigned int) number_value. */
508 bool negative_number; /* The number is negative. */
509 bool always_output_a_sign; /* +/- should always be output. */
510 int tz_colon_mask; /* Bitmask of where ':' should appear. */
511 const CHAR_T *subfmt;
515 + 2 /* for the two colons in a %::z or %:::z time zone */
516 + (sizeof (int) < sizeof (time_t)
517 ? INT_STRLEN_BOUND (time_t)
518 : INT_STRLEN_BOUND (int))];
520 bool to_lowcase = false;
521 bool to_uppcase = upcase;
523 bool change_case = false;
526 #if DO_MULTIBYTE && !defined COMPILE_WIDE
532 case L_('\b'): case L_('\t'): case L_('\n'):
533 case L_('\v'): case L_('\f'): case L_('\r'):
534 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
535 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
536 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
537 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
538 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
539 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
540 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
541 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
542 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
543 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
544 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
545 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
546 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
547 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
548 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
549 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
550 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
551 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
553 /* The C Standard requires these 98 characters (plus '%') to
554 be in the basic execution character set. None of these
555 characters can start a multibyte sequence, so they need
556 not be analyzed further. */
561 /* Copy this multibyte sequence until we reach its end, find
562 an error, or come back to the initial shift state. */
564 mbstate_t mbstate = mbstate_zero;
569 format_end = f + strlen (f) + 1;
570 fsize = format_end - f;
574 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
579 if (bytes == (size_t) -2)
581 len += strlen (f + len);
585 if (bytes == (size_t) -1)
593 while (! mbsinit (&mbstate));
601 #else /* ! DO_MULTIBYTE */
603 /* Either multibyte encodings are not supported, they are
604 safe for formats, so any non-'%' byte can be copied through,
605 or this is the wide character version. */
612 #endif /* ! DO_MULTIBYTE */
614 /* Check for flags that can modify a format. */
619 /* This influences the number formats. */
626 /* This changes textual output. */
640 /* As a GNU extension we allow to specify the field width. */
646 if (width > INT_MAX / 10
647 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
648 /* Avoid overflow. */
653 width += *f - L_('0');
657 while (ISDIGIT (*f));
660 /* Check for modifiers. */
673 /* Now do the specified format. */
677 #define DO_NUMBER(d, v) \
679 number_value = v; goto do_number
680 #define DO_SIGNED_NUMBER(d, negative, v) \
682 negative_number = negative; \
683 u_number_value = v; goto do_signed_number
685 /* The mask is not what you might think.
686 When the ordinal i'th bit is set, insert a colon
687 before the i'th digit of the time zone representation. */
688 #define DO_TZ_OFFSET(d, negative, mask, v) \
690 negative_number = negative; \
691 tz_colon_mask = mask; \
692 u_number_value = v; goto do_tz_offset
693 #define DO_NUMBER_SPACEPAD(d, v) \
695 number_value = v; goto do_number_spacepad
712 cpy (aw_len, a_wkday);
715 goto underlying_strftime;
727 cpy (STRLEN (f_wkday), f_wkday);
730 goto underlying_strftime;
743 cpy (am_len, a_month);
746 goto underlying_strftime;
758 cpy (STRLEN (f_month), f_month);
761 goto underlying_strftime;
765 if (modifier == L_('O'))
768 if (! (modifier == 'E'
770 (const CHAR_T *) _NL_CURRENT (LC_TIME,
773 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
775 goto underlying_strftime;
780 size_t len = strftime_case_ (to_uppcase,
781 NULL, STRFTIME_ARG ((size_t) -1)
783 tp extra_args LOCALE_ARG);
784 add (len, strftime_case_ (to_uppcase, p,
785 STRFTIME_ARG (maxsize - i)
787 tp extra_args LOCALE_ARG));
791 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
794 /* The relevant information is available only via the
795 underlying strftime implementation, so use that. */
798 char ubuf[1024]; /* enough for any single format in practice */
800 /* Make sure we're calling the actual underlying strftime.
801 In some cases, config.h contains something like
802 "#define strftime rpl_strftime". */
808 /* The space helps distinguish strftime failure from empty
816 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
818 cpy (len - 1, ubuf + 1);
824 if (modifier == L_('O'))
826 if (modifier == L_('E'))
828 #if HAVE_STRUCT_ERA_ENTRY
829 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
833 size_t len = __wcslen (era->era_wname);
834 cpy (len, era->era_wname);
836 size_t len = strlen (era->era_name);
837 cpy (len, era->era_name);
842 goto underlying_strftime;
847 int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
848 century -= tp->tm_year % 100 < 0 && 0 < century;
849 DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
853 if (modifier == L_('O'))
856 if (! (modifier == L_('E')
858 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
860 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
863 goto underlying_strftime;
868 subfmt = L_("%m/%d/%y");
872 if (modifier == L_('E'))
875 DO_NUMBER (2, tp->tm_mday);
878 if (modifier == L_('E'))
881 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
883 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
884 and then jump to one of these labels. */
887 always_output_a_sign = true;
891 /* Force `_' flag unless overridden by `0' or `-' flag. */
892 if (pad != L_('0') && pad != L_('-'))
896 /* Format NUMBER_VALUE according to the MODIFIER flag. */
897 negative_number = number_value < 0;
898 u_number_value = number_value;
901 always_output_a_sign = false;
905 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
906 NEGATIVE_NUMBER is nonzero if the original number was
907 negative; in this case it was converted directly to
908 unsigned int (i.e., modulo (UINT_MAX + 1)) without
910 if (modifier == L_('O') && !negative_number)
913 /* Get the locale specific alternate representation of
914 the number. If none exist NULL is returned. */
915 const CHAR_T *cp = nl_get_alt_digit (u_number_value
920 size_t digitlen = STRLEN (cp);
928 goto underlying_strftime;
932 bufp = buf + sizeof (buf) / sizeof (buf[0]);
935 u_number_value = - u_number_value;
939 if (tz_colon_mask & 1)
942 *--bufp = u_number_value % 10 + L_('0');
943 u_number_value /= 10;
945 while (u_number_value != 0 || tz_colon_mask != 0);
947 do_number_sign_and_padding:
951 sign_char = (negative_number ? L_('-')
952 : always_output_a_sign ? L_('+')
962 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
963 - bufp) - !!sign_char;
969 if ((size_t) padding >= maxsize - i)
973 memset_space (p, padding);
975 width = width > padding ? width - padding : 0;
981 if ((size_t) digits >= maxsize - i)
988 memset_zero (p, padding);
1000 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1006 subfmt = L_("%Y-%m-%d");
1010 if (modifier == L_('E'))
1013 DO_NUMBER (2, tp->tm_hour);
1016 if (modifier == L_('E'))
1019 DO_NUMBER (2, hour12);
1021 case L_('k'): /* GNU extension. */
1022 if (modifier == L_('E'))
1025 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1027 case L_('l'): /* GNU extension. */
1028 if (modifier == L_('E'))
1031 DO_NUMBER_SPACEPAD (2, hour12);
1034 if (modifier == L_('E'))
1037 DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
1040 if (modifier == L_('E'))
1043 DO_NUMBER (2, tp->tm_min);
1046 if (modifier == L_('E'))
1049 DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
1052 case L_('N'): /* GNU extension. */
1053 if (modifier == L_('E'))
1061 /* Take an explicit width less than 9 as a precision. */
1063 for (j = width; j < 9; j++)
1067 DO_NUMBER (width, number_value);
1077 format_char = L_('p');
1091 goto underlying_strftime;
1095 subfmt = L_("%H:%M");
1100 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1103 subfmt = L_("%I:%M:%S %p");
1106 goto underlying_strftime;
1110 if (modifier == L_('E'))
1113 DO_NUMBER (2, tp->tm_sec);
1115 case L_('s'): /* GNU extension. */
1123 /* Generate string value for T using time_t arithmetic;
1124 this works even if sizeof (long) < sizeof (time_t). */
1126 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1127 negative_number = t < 0;
1133 *--bufp = (negative_number ? -d : d) + L_('0');
1138 always_output_a_sign = false;
1139 goto do_number_sign_and_padding;
1143 if (modifier == L_('O'))
1146 if (! (modifier == L_('E')
1148 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1150 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1153 goto underlying_strftime;
1156 subfmt = L_("%H:%M:%S");
1164 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1167 if (modifier == L_('E'))
1170 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1175 if (modifier == L_('E'))
1178 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1179 is a leap year, except that YEAR and YEAR - 1 both work
1180 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1182 int year = (tp->tm_year
1184 ? TM_YEAR_BASE % 400
1185 : TM_YEAR_BASE % 400 - 400));
1186 int year_adjust = 0;
1187 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1191 /* This ISO week belongs to the previous year. */
1193 days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
1198 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1202 /* This ISO week belongs to the next year. */
1212 int yy = (tp->tm_year % 100 + year_adjust) % 100;
1213 DO_NUMBER (2, (0 <= yy
1215 : tp->tm_year < -TM_YEAR_BASE - year_adjust
1221 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
1222 (tp->tm_year + (unsigned int) TM_YEAR_BASE
1226 DO_NUMBER (2, days / 7 + 1);
1231 if (modifier == L_('E'))
1234 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1237 if (modifier == L_('E'))
1240 DO_NUMBER (1, tp->tm_wday);
1243 if (modifier == 'E')
1245 #if HAVE_STRUCT_ERA_ENTRY
1246 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1249 # ifdef COMPILE_WIDE
1250 subfmt = era->era_wformat;
1252 subfmt = era->era_format;
1257 goto underlying_strftime;
1260 if (modifier == L_('O'))
1263 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1264 tp->tm_year + (unsigned int) TM_YEAR_BASE);
1267 if (modifier == L_('E'))
1269 #if HAVE_STRUCT_ERA_ENTRY
1270 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1273 int delta = tp->tm_year - era->start_date[0];
1274 DO_NUMBER (1, (era->offset
1275 + delta * era->absolute_direction));
1278 goto underlying_strftime;
1283 int yy = tp->tm_year % 100;
1285 yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
1297 /* The tzset() call might have changed the value. */
1298 if (!(zone && *zone) && tp->tm_isdst >= 0)
1299 zone = tzname[tp->tm_isdst != 0];
1306 /* The zone string is always given in multibyte form. We have
1307 to transform it first. */
1310 widen (zone, wczone, len);
1314 cpy (strlen (zone), zone);
1319 /* :, ::, and ::: are valid only just before 'z'.
1320 :::: etc. are rejected later. */
1321 for (colons = 1; f[colons] == L_(':'); colons++)
1323 if (f[colons] != L_('z'))
1326 goto do_z_conversion;
1332 if (tp->tm_isdst < 0)
1341 diff = tp->tm_gmtoff;
1354 if (lt == (time_t) -1)
1356 /* mktime returns -1 for errors, but -1 is also a
1357 valid time_t value. Check whether an error really
1361 if (! __localtime_r (<, &tm)
1362 || ((ltm.tm_sec ^ tm.tm_sec)
1363 | (ltm.tm_min ^ tm.tm_min)
1364 | (ltm.tm_hour ^ tm.tm_hour)
1365 | (ltm.tm_mday ^ tm.tm_mday)
1366 | (ltm.tm_mon ^ tm.tm_mon)
1367 | (ltm.tm_year ^ tm.tm_year)))
1371 if (! __gmtime_r (<, >m))
1374 diff = tm_diff (<m, >m);
1378 hour_diff = diff / 60 / 60;
1379 min_diff = diff / 60 % 60;
1380 sec_diff = diff % 60;
1385 DO_TZ_OFFSET (5, diff < 0, 0, hour_diff * 100 + min_diff);
1387 case 1: tz_hh_mm: /* +hh:mm */
1388 DO_TZ_OFFSET (6, diff < 0, 04, hour_diff * 100 + min_diff);
1390 case 2: tz_hh_mm_ss: /* +hh:mm:ss */
1391 DO_TZ_OFFSET (9, diff < 0, 024,
1392 hour_diff * 10000 + min_diff * 100 + sec_diff);
1394 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1399 DO_TZ_OFFSET (3, diff < 0, 0, hour_diff);
1406 case L_('\0'): /* GNU extension: % at end of format. */
1410 /* Unknown format; output the format, including the '%',
1411 since this is most likely the right thing to do if a
1412 multibyte string has been misparsed. */
1416 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1418 cpy (flen, &f[1 - flen]);
1425 if (p && maxsize != 0)
1432 /* Write information from TP into S according to the format
1433 string FORMAT, writing no more that MAXSIZE characters
1434 (including the terminating '\0') and returning number of
1435 characters written. If S is NULL, nothing will be written
1436 anywhere, so to determine how many characters would be
1437 written, use NULL for S and (size_t) -1 for MAXSIZE. */
1439 my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
1440 const CHAR_T *format,
1441 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
1443 return strftime_case_ (false, s, STRFTIME_ARG (maxsize)
1444 format, tp extra_args LOCALE_ARG);
1447 #if defined _LIBC && ! FPRINTFTIME
1448 libc_hidden_def (my_strftime)
1452 #if defined emacs && ! FPRINTFTIME
1453 /* For Emacs we have a separate interface which corresponds to the normal
1454 strftime function plus the ut argument, but without the ns argument. */
1456 emacs_strftimeu (char *s, size_t maxsize, const char *format,
1457 const struct tm *tp, int ut)
1459 return my_strftime (s, maxsize, format, tp, ut, 0);