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 2, or (at your option)
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 along
18 with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
23 # define HAVE_MBRLEN 1
24 # define HAVE_STRUCT_ERA_ENTRY 1
25 # define HAVE_TM_GMTOFF 1
26 # define HAVE_TM_ZONE 1
27 # define HAVE_TZNAME 1
29 # define MULTIBYTE_IS_FORMAT_SAFE 1
30 # include "../locale/localeinfo.h"
34 # include "fprintftime.h"
41 #if HAVE_TZNAME && ! defined tzname
42 extern char *tzname[];
45 /* Do multibyte processing if multibytes are supported, unless
46 multibyte sequences are safe in formats. Multibyte sequences are
47 safe if they cannot contain byte sequences that look like format
48 conversion specifications. The GNU C Library uses UTF8 multibyte
49 encoding, which is safe for formats, but strftime.c can be used
50 with other C libraries that use unsafe encodings. */
51 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
57 /* Simulate mbrlen with mblen as best we can. */
58 # define mbstate_t int
59 # define mbrlen(s, n, ps) mblen (s, n)
60 # define mbsinit(ps) (*(ps) == 0)
62 static const mbstate_t mbstate_zero;
73 # define CHAR_T wchar_t
74 # define UCHAR_T unsigned int
75 # define L_(Str) L##Str
76 # define NLW(Sym) _NL_W##Sym
78 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
79 # define STRLEN(s) __wcslen (s)
83 # define UCHAR_T unsigned char
87 # define MEMCPY(d, s, n) memcpy (d, s, n)
88 # define STRLEN(s) strlen (s)
91 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
94 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
99 /* Shift A right by B bits portably, by dividing A by 2**B and
100 truncating towards minus infinity. A and B should be free of side
101 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
102 INT_BITS is the number of useful bits in an int. GNU code can
103 assume that INT_BITS is at least 32.
105 ISO C99 says that A >> B is implementation-defined if A < 0. Some
106 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
107 right in the usual way when A < 0, so SHR falls back on division if
108 ordinary A >> B doesn't seem to be the usual signed shift. */
112 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
114 /* Bound on length of the string representing an integer type or expression T.
115 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
116 add 1 for integer division truncation; add 1 more for a minus sign
118 #define INT_STRLEN_BOUND(t) \
119 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
121 #define TM_YEAR_BASE 1900
124 /* Nonzero if YEAR is a leap year (every 4 years,
125 except every 100th isn't, and every 400th is). */
126 # define __isleap(year) \
127 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
132 # define tzname __tzname
133 # define tzset __tzset
137 /* Portable standalone applications should supply a "time.h" that
138 declares a POSIX-compliant localtime_r, for the benefit of older
139 implementations that lack localtime_r or have a nonstandard one.
140 See the gnulib time_r module for one way to implement this. */
142 # undef __localtime_r
143 # define __gmtime_r gmtime_r
144 # define __localtime_r localtime_r
149 # define FPRINTFTIME 0
153 # define STREAM_OR_CHAR_T FILE
154 # define STRFTIME_ARG(x) /* empty */
156 # define STREAM_OR_CHAR_T CHAR_T
157 # define STRFTIME_ARG(x) x,
161 # define memset_byte(P, Len, Byte) \
162 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
163 # define memset_space(P, Len) memset_byte (P, Len, ' ')
164 # define memset_zero(P, Len) memset_byte (P, Len, '0')
165 #elif defined COMPILE_WIDE
166 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
167 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
169 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
170 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
174 # define advance(P, N)
176 # define advance(P, N) ((P) += (N))
183 int _delta = width - _n; \
184 int _incr = _n + (_delta > 0 ? _delta : 0); \
185 if ((size_t) _incr >= maxsize - i) \
189 if (digits == 0 && _delta > 0) \
191 if (pad == L_('0')) \
192 memset_zero (p, _delta); \
194 memset_space (p, _delta); \
203 # define add1(C) add (1, fputc (C, p))
205 # define add1(C) add (1, *p = C)
212 fwrite_lowcase (p, (s), _n); \
213 else if (to_uppcase) \
214 fwrite_uppcase (p, (s), _n); \
216 fwrite ((s), _n, 1, p))
221 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
222 else if (to_uppcase) \
223 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
225 MEMCPY ((void *) p, (void const *) (s), _n))
229 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
230 # undef __mbsrtowcs_l
231 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
233 # define widen(os, ws, l) \
236 const char *__s = os; \
237 memset (&__st, '\0', sizeof (__st)); \
238 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
239 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
240 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
245 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
246 /* We use this code also for the extended locale handling where the
247 function gets as an additional argument the locale which has to be
248 used. To access the values we have to redefine the _NL_CURRENT
250 # define strftime __strftime_l
251 # define wcsftime __wcsftime_l
253 # define _NL_CURRENT(category, item) \
254 (current->values[_NL_ITEM_INDEX (item)].string)
255 # define LOCALE_ARG , loc
256 # define LOCALE_PARAM_PROTO , __locale_t loc
257 # define HELPER_LOCALE_ARG , current
259 # define LOCALE_PARAM_PROTO
262 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
264 # define HELPER_LOCALE_ARG
269 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
270 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
271 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
273 # define TOUPPER(Ch, L) towupper (Ch)
274 # define TOLOWER(Ch, L) towlower (Ch)
277 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
278 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
279 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
281 # define TOUPPER(Ch, L) toupper (Ch)
282 # define TOLOWER(Ch, L) tolower (Ch)
285 /* We don't use `isdigit' here since the locale dependent
286 interpretation is not what we want here. We only need to accept
287 the arabic digits in the ASCII range. One day there is perhaps a
288 more reliable way to accept other sets of digits. */
289 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
293 fwrite_lowcase (FILE *fp, const CHAR_T *src, size_t len)
297 fputc (TOLOWER ((UCHAR_T) *src, loc), fp);
303 fwrite_uppcase (FILE *fp, const CHAR_T *src, size_t len)
307 fputc (TOUPPER ((UCHAR_T) *src, loc), fp);
313 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
314 size_t len LOCALE_PARAM_PROTO)
317 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
322 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
323 size_t len LOCALE_PARAM_PROTO)
326 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
333 /* Yield the difference between *A and *B,
334 measured in seconds, ignoring leap seconds. */
335 # define tm_diff ftime_tm_diff
337 tm_diff (const struct tm *a, const struct tm *b)
339 /* Compute intervening leap days correctly even if year is negative.
340 Take care to avoid int overflow in leap day calculations,
341 but it's OK to assume that A and B are close to each other. */
342 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
343 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
344 int a100 = a4 / 25 - (a4 % 25 < 0);
345 int b100 = b4 / 25 - (b4 % 25 < 0);
346 int a400 = SHR (a100, 2);
347 int b400 = SHR (b100, 2);
348 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
349 int years = a->tm_year - b->tm_year;
350 int days = (365 * years + intervening_leap_days
351 + (a->tm_yday - b->tm_yday));
352 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
353 + (a->tm_min - b->tm_min))
354 + (a->tm_sec - b->tm_sec));
356 #endif /* ! HAVE_TM_GMTOFF */
360 /* The number of days from the first day of the first ISO week of this
361 year to the year day YDAY with week day WDAY. ISO weeks start on
362 Monday; the first ISO week has the year's first Thursday. YDAY may
363 be as small as YDAY_MINIMUM. */
364 #define ISO_WEEK_START_WDAY 1 /* Monday */
365 #define ISO_WEEK1_WDAY 4 /* Thursday */
366 #define YDAY_MINIMUM (-366)
371 iso_week_days (int yday, int wday)
373 /* Add enough to the first operand of % to make it nonnegative. */
374 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
376 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
377 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
381 /* When compiling this file, GNU applications can #define my_strftime
382 to a symbol (typically nstrftime) to get an extended strftime with
383 extra arguments UT and NS. Emacs is a special case for now, but
384 this Emacs-specific code can be removed once Emacs's config.h
385 defines my_strftime. */
386 #if defined emacs && !defined my_strftime
387 # define my_strftime nstrftime
392 # define my_strftime fprintftime
396 # define extra_args , ut, ns
397 # define extra_args_spec , int ut, int ns
399 # if defined COMPILE_WIDE
400 # define my_strftime wcsftime
401 # define nl_get_alt_digit _nl_get_walt_digit
403 # define my_strftime strftime
404 # define nl_get_alt_digit _nl_get_alt_digit
407 # define extra_args_spec
408 /* We don't have this information in general. */
414 /* Just like my_strftime, below, but with one more parameter, UPCASE,
415 to indicate that the result should be converted to upper case. */
417 strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
418 STRFTIME_ARG (size_t maxsize)
419 const CHAR_T *format,
420 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
422 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
423 struct locale_data *const current = loc->__locales[LC_TIME];
426 size_t maxsize = (size_t) -1;
429 int hour12 = tp->tm_hour;
431 /* We cannot make the following values variables since we must delay
432 the evaluation of these values until really needed since some
433 expressions might not be valid in every situation. The `struct tm'
434 might be generated by a strptime() call that initialized
435 only a few elements. Dereference the pointers only if the format
436 requires this. Then it is ok to fail if the pointers are invalid. */
438 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
440 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
442 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
444 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
446 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
447 ? NLW(PM_STR) : NLW(AM_STR)))
449 # define aw_len STRLEN (a_wkday)
450 # define am_len STRLEN (a_month)
451 # define ap_len STRLEN (ampm)
455 STREAM_OR_CHAR_T *p = s;
457 #if DO_MULTIBYTE && !defined COMPILE_WIDE
458 const char *format_end = NULL;
461 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
462 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
463 by localtime. On such systems, we must either use the tzset and
464 localtime wrappers to work around the bug (which sets
465 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
466 struct tm copy = *tp;
472 /* The POSIX test suite assumes that setting
473 the environment variable TZ to a new value before calling strftime()
474 will influence the result (the %Z format) even if the information in
475 TP is computed with a totally different time zone.
476 This is bogus: though POSIX allows bad behavior like this,
477 POSIX does not require it. Do the right thing instead. */
478 zone = (const char *) tp->tm_zone;
483 if (! (zone && *zone))
488 /* POSIX.1 requires that local time zone information be used as
489 though strftime called tzset. */
502 for (f = format; *f != '\0'; ++f)
504 int pad = 0; /* Padding for number ('-', '_', or 0). */
505 int modifier; /* Field modifier ('E', 'O', or 0). */
506 int digits = 0; /* Max digits for numeric format. */
507 int number_value; /* Numeric value to be printed. */
508 unsigned int u_number_value; /* (unsigned int) number_value. */
509 bool negative_number; /* The number is negative. */
510 bool always_output_a_sign; /* +/- should always be output. */
511 int tz_colon_mask; /* Bitmask of where ':' should appear. */
512 const CHAR_T *subfmt;
516 + 2 /* for the two colons in a %::z or %:::z time zone */
517 + (sizeof (int) < sizeof (time_t)
518 ? INT_STRLEN_BOUND (time_t)
519 : INT_STRLEN_BOUND (int))];
521 bool to_lowcase = false;
522 bool to_uppcase = upcase;
524 bool change_case = false;
527 #if DO_MULTIBYTE && !defined COMPILE_WIDE
533 case L_('\b'): case L_('\t'): case L_('\n'):
534 case L_('\v'): case L_('\f'): case L_('\r'):
535 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
536 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
537 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
538 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
539 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
540 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
541 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
542 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
543 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
544 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
545 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
546 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
547 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
548 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
549 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
550 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
551 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
552 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
554 /* The C Standard requires these 98 characters (plus '%') to
555 be in the basic execution character set. None of these
556 characters can start a multibyte sequence, so they need
557 not be analyzed further. */
562 /* Copy this multibyte sequence until we reach its end, find
563 an error, or come back to the initial shift state. */
565 mbstate_t mbstate = mbstate_zero;
570 format_end = f + strlen (f) + 1;
571 fsize = format_end - f;
575 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
580 if (bytes == (size_t) -2)
582 len += strlen (f + len);
586 if (bytes == (size_t) -1)
594 while (! mbsinit (&mbstate));
602 #else /* ! DO_MULTIBYTE */
604 /* Either multibyte encodings are not supported, they are
605 safe for formats, so any non-'%' byte can be copied through,
606 or this is the wide character version. */
613 #endif /* ! DO_MULTIBYTE */
615 /* Check for flags that can modify a format. */
620 /* This influences the number formats. */
627 /* This changes textual output. */
641 /* As a GNU extension we allow to specify the field width. */
647 if (width > INT_MAX / 10
648 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
649 /* Avoid overflow. */
654 width += *f - L_('0');
658 while (ISDIGIT (*f));
661 /* Check for modifiers. */
674 /* Now do the specified format. */
678 #define DO_NUMBER(d, v) \
680 number_value = v; goto do_number
681 #define DO_SIGNED_NUMBER(d, negative, v) \
683 negative_number = negative; \
684 u_number_value = v; goto do_signed_number
686 /* The mask is not what you might think.
687 When the ordinal i'th bit is set, insert a colon
688 before the i'th digit of the time zone representation. */
689 #define DO_TZ_OFFSET(d, negative, mask, v) \
691 negative_number = negative; \
692 tz_colon_mask = mask; \
693 u_number_value = v; goto do_tz_offset
694 #define DO_NUMBER_SPACEPAD(d, v) \
696 number_value = v; goto do_number_spacepad
713 cpy (aw_len, a_wkday);
716 goto underlying_strftime;
728 cpy (STRLEN (f_wkday), f_wkday);
731 goto underlying_strftime;
744 cpy (am_len, a_month);
747 goto underlying_strftime;
759 cpy (STRLEN (f_month), f_month);
762 goto underlying_strftime;
766 if (modifier == L_('O'))
769 if (! (modifier == 'E'
771 (const CHAR_T *) _NL_CURRENT (LC_TIME,
774 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
776 goto underlying_strftime;
781 size_t len = strftime_case_ (to_uppcase,
782 NULL, STRFTIME_ARG ((size_t) -1)
784 tp extra_args LOCALE_ARG);
785 add (len, strftime_case_ (to_uppcase, p,
786 STRFTIME_ARG (maxsize - i)
788 tp extra_args LOCALE_ARG));
792 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
795 /* The relevant information is available only via the
796 underlying strftime implementation, so use that. */
799 char ubuf[1024]; /* enough for any single format in practice */
801 /* Make sure we're calling the actual underlying strftime.
802 In some cases, config.h contains something like
803 "#define strftime rpl_strftime". */
809 /* The space helps distinguish strftime failure from empty
817 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
819 cpy (len - 1, ubuf + 1);
825 if (modifier == L_('O'))
827 if (modifier == L_('E'))
829 #if HAVE_STRUCT_ERA_ENTRY
830 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
834 size_t len = __wcslen (era->era_wname);
835 cpy (len, era->era_wname);
837 size_t len = strlen (era->era_name);
838 cpy (len, era->era_name);
843 goto underlying_strftime;
848 int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
849 century -= tp->tm_year % 100 < 0 && 0 < century;
850 DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
854 if (modifier == L_('O'))
857 if (! (modifier == L_('E')
859 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
861 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
864 goto underlying_strftime;
869 subfmt = L_("%m/%d/%y");
873 if (modifier == L_('E'))
876 DO_NUMBER (2, tp->tm_mday);
879 if (modifier == L_('E'))
882 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
884 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
885 and then jump to one of these labels. */
888 always_output_a_sign = true;
892 /* Force `_' flag unless overridden by `0' or `-' flag. */
893 if (pad != L_('0') && pad != L_('-'))
897 /* Format NUMBER_VALUE according to the MODIFIER flag. */
898 negative_number = number_value < 0;
899 u_number_value = number_value;
902 always_output_a_sign = false;
906 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
907 NEGATIVE_NUMBER is nonzero if the original number was
908 negative; in this case it was converted directly to
909 unsigned int (i.e., modulo (UINT_MAX + 1)) without
911 if (modifier == L_('O') && !negative_number)
914 /* Get the locale specific alternate representation of
915 the number. If none exist NULL is returned. */
916 const CHAR_T *cp = nl_get_alt_digit (u_number_value
921 size_t digitlen = STRLEN (cp);
929 goto underlying_strftime;
933 bufp = buf + sizeof (buf) / sizeof (buf[0]);
936 u_number_value = - u_number_value;
940 if (tz_colon_mask & 1)
943 *--bufp = u_number_value % 10 + L_('0');
944 u_number_value /= 10;
946 while (u_number_value != 0 || tz_colon_mask != 0);
948 do_number_sign_and_padding:
952 sign_char = (negative_number ? L_('-')
953 : always_output_a_sign ? L_('+')
963 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
964 - bufp) - !!sign_char;
970 if ((size_t) padding >= maxsize - i)
974 memset_space (p, padding);
976 width = width > padding ? width - padding : 0;
982 if ((size_t) digits >= maxsize - i)
989 memset_zero (p, padding);
1001 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1007 subfmt = L_("%Y-%m-%d");
1011 if (modifier == L_('E'))
1014 DO_NUMBER (2, tp->tm_hour);
1017 if (modifier == L_('E'))
1020 DO_NUMBER (2, hour12);
1022 case L_('k'): /* GNU extension. */
1023 if (modifier == L_('E'))
1026 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1028 case L_('l'): /* GNU extension. */
1029 if (modifier == L_('E'))
1032 DO_NUMBER_SPACEPAD (2, hour12);
1035 if (modifier == L_('E'))
1038 DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
1041 if (modifier == L_('E'))
1044 DO_NUMBER (2, tp->tm_min);
1047 if (modifier == L_('E'))
1050 DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
1053 case L_('N'): /* GNU extension. */
1054 if (modifier == L_('E'))
1062 /* Take an explicit width less than 9 as a precision. */
1064 for (j = width; j < 9; j++)
1068 DO_NUMBER (width, number_value);
1078 format_char = L_('p');
1092 goto underlying_strftime;
1096 subfmt = L_("%H:%M");
1101 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1104 subfmt = L_("%I:%M:%S %p");
1107 goto underlying_strftime;
1111 if (modifier == L_('E'))
1114 DO_NUMBER (2, tp->tm_sec);
1116 case L_('s'): /* GNU extension. */
1124 /* Generate string value for T using time_t arithmetic;
1125 this works even if sizeof (long) < sizeof (time_t). */
1127 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1128 negative_number = t < 0;
1134 *--bufp = (negative_number ? -d : d) + L_('0');
1139 always_output_a_sign = false;
1140 goto do_number_sign_and_padding;
1144 if (modifier == L_('O'))
1147 if (! (modifier == L_('E')
1149 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1151 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1154 goto underlying_strftime;
1157 subfmt = L_("%H:%M:%S");
1165 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1168 if (modifier == L_('E'))
1171 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1176 if (modifier == L_('E'))
1179 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1180 is a leap year, except that YEAR and YEAR - 1 both work
1181 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1183 int year = (tp->tm_year
1185 ? TM_YEAR_BASE % 400
1186 : TM_YEAR_BASE % 400 - 400));
1187 int year_adjust = 0;
1188 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1192 /* This ISO week belongs to the previous year. */
1194 days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
1199 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1203 /* This ISO week belongs to the next year. */
1213 int yy = (tp->tm_year % 100 + year_adjust) % 100;
1214 DO_NUMBER (2, (0 <= yy
1216 : tp->tm_year < -TM_YEAR_BASE - year_adjust
1222 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
1223 (tp->tm_year + (unsigned int) TM_YEAR_BASE
1227 DO_NUMBER (2, days / 7 + 1);
1232 if (modifier == L_('E'))
1235 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1238 if (modifier == L_('E'))
1241 DO_NUMBER (1, tp->tm_wday);
1244 if (modifier == 'E')
1246 #if HAVE_STRUCT_ERA_ENTRY
1247 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1250 # ifdef COMPILE_WIDE
1251 subfmt = era->era_wformat;
1253 subfmt = era->era_format;
1258 goto underlying_strftime;
1261 if (modifier == L_('O'))
1264 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1265 tp->tm_year + (unsigned int) TM_YEAR_BASE);
1268 if (modifier == L_('E'))
1270 #if HAVE_STRUCT_ERA_ENTRY
1271 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1274 int delta = tp->tm_year - era->start_date[0];
1275 DO_NUMBER (1, (era->offset
1276 + delta * era->absolute_direction));
1279 goto underlying_strftime;
1284 int yy = tp->tm_year % 100;
1286 yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
1298 /* The tzset() call might have changed the value. */
1299 if (!(zone && *zone) && tp->tm_isdst >= 0)
1300 zone = tzname[tp->tm_isdst != 0];
1307 /* The zone string is always given in multibyte form. We have
1308 to transform it first. */
1311 widen (zone, wczone, len);
1315 cpy (strlen (zone), zone);
1320 /* :, ::, and ::: are valid only just before 'z'.
1321 :::: etc. are rejected later. */
1322 for (colons = 1; f[colons] == L_(':'); colons++)
1324 if (f[colons] != L_('z'))
1327 goto do_z_conversion;
1333 if (tp->tm_isdst < 0)
1342 diff = tp->tm_gmtoff;
1355 if (lt == (time_t) -1)
1357 /* mktime returns -1 for errors, but -1 is also a
1358 valid time_t value. Check whether an error really
1362 if (! __localtime_r (<, &tm)
1363 || ((ltm.tm_sec ^ tm.tm_sec)
1364 | (ltm.tm_min ^ tm.tm_min)
1365 | (ltm.tm_hour ^ tm.tm_hour)
1366 | (ltm.tm_mday ^ tm.tm_mday)
1367 | (ltm.tm_mon ^ tm.tm_mon)
1368 | (ltm.tm_year ^ tm.tm_year)))
1372 if (! __gmtime_r (<, >m))
1375 diff = tm_diff (<m, >m);
1379 hour_diff = diff / 60 / 60;
1380 min_diff = diff / 60 % 60;
1381 sec_diff = diff % 60;
1386 DO_TZ_OFFSET (5, diff < 0, 0, hour_diff * 100 + min_diff);
1388 case 1: tz_hh_mm: /* +hh:mm */
1389 DO_TZ_OFFSET (6, diff < 0, 04, hour_diff * 100 + min_diff);
1391 case 2: tz_hh_mm_ss: /* +hh:mm:ss */
1392 DO_TZ_OFFSET (9, diff < 0, 024,
1393 hour_diff * 10000 + min_diff * 100 + sec_diff);
1395 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1400 DO_TZ_OFFSET (3, diff < 0, 0, hour_diff);
1407 case L_('\0'): /* GNU extension: % at end of format. */
1411 /* Unknown format; output the format, including the '%',
1412 since this is most likely the right thing to do if a
1413 multibyte string has been misparsed. */
1417 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1419 cpy (flen, &f[1 - flen]);
1426 if (p && maxsize != 0)
1433 /* Write information from TP into S according to the format
1434 string FORMAT, writing no more that MAXSIZE characters
1435 (including the terminating '\0') and returning number of
1436 characters written. If S is NULL, nothing will be written
1437 anywhere, so to determine how many characters would be
1438 written, use NULL for S and (size_t) -1 for MAXSIZE. */
1440 my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
1441 const CHAR_T *format,
1442 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
1444 return strftime_case_ (false, s, STRFTIME_ARG (maxsize)
1445 format, tp extra_args LOCALE_ARG);
1448 #if defined _LIBC && ! FPRINTFTIME
1449 libc_hidden_def (my_strftime)
1453 #if defined emacs && ! FPRINTFTIME
1454 /* For Emacs we have a separate interface which corresponds to the normal
1455 strftime function plus the ut argument, but without the ns argument. */
1457 emacs_strftimeu (char *s, size_t maxsize, const char *format,
1458 const struct tm *tp, int ut)
1460 return my_strftime (s, maxsize, format, tp, ut, 0);