1 /* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2009 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)
54 static const mbstate_t mbstate_zero;
65 # define CHAR_T wchar_t
66 # define UCHAR_T unsigned int
67 # define L_(Str) L##Str
68 # define NLW(Sym) _NL_W##Sym
70 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
71 # define STRLEN(s) __wcslen (s)
75 # define UCHAR_T unsigned char
79 # define MEMCPY(d, s, n) memcpy (d, s, n)
80 # define STRLEN(s) strlen (s)
84 /* Shift A right by B bits portably, by dividing A by 2**B and
85 truncating towards minus infinity. A and B should be free of side
86 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
87 INT_BITS is the number of useful bits in an int. GNU code can
88 assume that INT_BITS is at least 32.
90 ISO C99 says that A >> B is implementation-defined if A < 0. Some
91 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
92 right in the usual way when A < 0, so SHR falls back on division if
93 ordinary A >> B doesn't seem to be the usual signed shift. */
97 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
99 /* Bound on length of the string representing an integer type or expression T.
100 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
101 add 1 for integer division truncation; add 1 more for a minus sign
103 #define INT_STRLEN_BOUND(t) \
104 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
106 #define TM_YEAR_BASE 1900
109 /* Nonzero if YEAR is a leap year (every 4 years,
110 except every 100th isn't, and every 400th is). */
111 # define __isleap(year) \
112 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
117 # define tzname __tzname
118 # define tzset __tzset
122 /* Portable standalone applications should supply a "time.h" that
123 declares a POSIX-compliant localtime_r, for the benefit of older
124 implementations that lack localtime_r or have a nonstandard one.
125 See the gnulib time_r module for one way to implement this. */
127 # undef __localtime_r
128 # define __gmtime_r gmtime_r
129 # define __localtime_r localtime_r
134 # define FPRINTFTIME 0
138 # define STREAM_OR_CHAR_T FILE
139 # define STRFTIME_ARG(x) /* empty */
141 # define STREAM_OR_CHAR_T CHAR_T
142 # define STRFTIME_ARG(x) x,
146 # define memset_byte(P, Len, Byte) \
147 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
148 # define memset_space(P, Len) memset_byte (P, Len, ' ')
149 # define memset_zero(P, Len) memset_byte (P, Len, '0')
150 #elif defined COMPILE_WIDE
151 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
152 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
154 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
155 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
159 # define advance(P, N)
161 # define advance(P, N) ((P) += (N))
168 int _delta = width - _n; \
169 int _incr = _n + (_delta > 0 ? _delta : 0); \
170 if ((size_t) _incr >= maxsize - i) \
174 if (digits == 0 && _delta > 0) \
176 if (pad == L_('0')) \
177 memset_zero (p, _delta); \
179 memset_space (p, _delta); \
188 # define add1(C) add (1, fputc (C, p))
190 # define add1(C) add (1, *p = C)
197 fwrite_lowcase (p, (s), _n); \
198 else if (to_uppcase) \
199 fwrite_uppcase (p, (s), _n); \
201 fwrite ((s), _n, 1, p))
206 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
207 else if (to_uppcase) \
208 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
210 MEMCPY ((void *) p, (void const *) (s), _n))
214 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
215 # undef __mbsrtowcs_l
216 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
218 # define widen(os, ws, l) \
221 const char *__s = os; \
222 memset (&__st, '\0', sizeof (__st)); \
223 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
224 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
225 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
230 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
231 /* We use this code also for the extended locale handling where the
232 function gets as an additional argument the locale which has to be
233 used. To access the values we have to redefine the _NL_CURRENT
235 # define strftime __strftime_l
236 # define wcsftime __wcsftime_l
238 # define _NL_CURRENT(category, item) \
239 (current->values[_NL_ITEM_INDEX (item)].string)
240 # define LOCALE_ARG , loc
241 # define LOCALE_PARAM_PROTO , __locale_t loc
242 # define HELPER_LOCALE_ARG , current
244 # define LOCALE_PARAM_PROTO
247 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
249 # define HELPER_LOCALE_ARG
254 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
255 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
256 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
258 # define TOUPPER(Ch, L) towupper (Ch)
259 # define TOLOWER(Ch, L) towlower (Ch)
262 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
263 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
264 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
266 # define TOUPPER(Ch, L) toupper (Ch)
267 # define TOLOWER(Ch, L) tolower (Ch)
270 /* We don't use `isdigit' here since the locale dependent
271 interpretation is not what we want here. We only need to accept
272 the arabic digits in the ASCII range. One day there is perhaps a
273 more reliable way to accept other sets of digits. */
274 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
278 fwrite_lowcase (FILE *fp, const CHAR_T *src, size_t len)
282 fputc (TOLOWER ((UCHAR_T) *src, loc), fp);
288 fwrite_uppcase (FILE *fp, const CHAR_T *src, size_t len)
292 fputc (TOUPPER ((UCHAR_T) *src, loc), fp);
298 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
299 size_t len LOCALE_PARAM_PROTO)
302 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
307 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
308 size_t len LOCALE_PARAM_PROTO)
311 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
318 /* Yield the difference between *A and *B,
319 measured in seconds, ignoring leap seconds. */
320 # define tm_diff ftime_tm_diff
322 tm_diff (const struct tm *a, const struct tm *b)
324 /* Compute intervening leap days correctly even if year is negative.
325 Take care to avoid int overflow in leap day calculations,
326 but it's OK to assume that A and B are close to each other. */
327 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
328 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
329 int a100 = a4 / 25 - (a4 % 25 < 0);
330 int b100 = b4 / 25 - (b4 % 25 < 0);
331 int a400 = SHR (a100, 2);
332 int b400 = SHR (b100, 2);
333 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
334 int years = a->tm_year - b->tm_year;
335 int days = (365 * years + intervening_leap_days
336 + (a->tm_yday - b->tm_yday));
337 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
338 + (a->tm_min - b->tm_min))
339 + (a->tm_sec - b->tm_sec));
341 #endif /* ! HAVE_TM_GMTOFF */
345 /* The number of days from the first day of the first ISO week of this
346 year to the year day YDAY with week day WDAY. ISO weeks start on
347 Monday; the first ISO week has the year's first Thursday. YDAY may
348 be as small as YDAY_MINIMUM. */
349 #define ISO_WEEK_START_WDAY 1 /* Monday */
350 #define ISO_WEEK1_WDAY 4 /* Thursday */
351 #define YDAY_MINIMUM (-366)
356 iso_week_days (int yday, int wday)
358 /* Add enough to the first operand of % to make it nonnegative. */
359 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
361 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
362 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
366 /* When compiling this file, GNU applications can #define my_strftime
367 to a symbol (typically nstrftime) to get an extended strftime with
368 extra arguments UT and NS. Emacs is a special case for now, but
369 this Emacs-specific code can be removed once Emacs's config.h
370 defines my_strftime. */
371 #if defined emacs && !defined my_strftime
372 # define my_strftime nstrftime
377 # define my_strftime fprintftime
381 # define extra_args , ut, ns
382 # define extra_args_spec , int ut, int ns
384 # if defined COMPILE_WIDE
385 # define my_strftime wcsftime
386 # define nl_get_alt_digit _nl_get_walt_digit
388 # define my_strftime strftime
389 # define nl_get_alt_digit _nl_get_alt_digit
392 # define extra_args_spec
393 /* We don't have this information in general. */
399 /* Just like my_strftime, below, but with one more parameter, UPCASE,
400 to indicate that the result should be converted to upper case. */
402 strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
403 STRFTIME_ARG (size_t maxsize)
404 const CHAR_T *format,
405 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
407 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
408 struct locale_data *const current = loc->__locales[LC_TIME];
411 size_t maxsize = (size_t) -1;
414 int hour12 = tp->tm_hour;
416 /* We cannot make the following values variables since we must delay
417 the evaluation of these values until really needed since some
418 expressions might not be valid in every situation. The `struct tm'
419 might be generated by a strptime() call that initialized
420 only a few elements. Dereference the pointers only if the format
421 requires this. Then it is ok to fail if the pointers are invalid. */
423 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
425 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
427 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
429 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
431 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
432 ? NLW(PM_STR) : NLW(AM_STR)))
434 # define aw_len STRLEN (a_wkday)
435 # define am_len STRLEN (a_month)
436 # define ap_len STRLEN (ampm)
440 STREAM_OR_CHAR_T *p = s;
442 #if DO_MULTIBYTE && !defined COMPILE_WIDE
443 const char *format_end = NULL;
446 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
447 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
448 by localtime. On such systems, we must either use the tzset and
449 localtime wrappers to work around the bug (which sets
450 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
451 struct tm copy = *tp;
457 /* The POSIX test suite assumes that setting
458 the environment variable TZ to a new value before calling strftime()
459 will influence the result (the %Z format) even if the information in
460 TP is computed with a totally different time zone.
461 This is bogus: though POSIX allows bad behavior like this,
462 POSIX does not require it. Do the right thing instead. */
463 zone = (const char *) tp->tm_zone;
468 if (! (zone && *zone))
473 /* POSIX.1 requires that local time zone information be used as
474 though strftime called tzset. */
487 for (f = format; *f != '\0'; ++f)
489 int pad = 0; /* Padding for number ('-', '_', or 0). */
490 int modifier; /* Field modifier ('E', 'O', or 0). */
491 int digits = 0; /* Max digits for numeric format. */
492 int number_value; /* Numeric value to be printed. */
493 unsigned int u_number_value; /* (unsigned int) number_value. */
494 bool negative_number; /* The number is negative. */
495 bool always_output_a_sign; /* +/- should always be output. */
496 int tz_colon_mask; /* Bitmask of where ':' should appear. */
497 const CHAR_T *subfmt;
501 + 2 /* for the two colons in a %::z or %:::z time zone */
502 + (sizeof (int) < sizeof (time_t)
503 ? INT_STRLEN_BOUND (time_t)
504 : INT_STRLEN_BOUND (int))];
506 bool to_lowcase = false;
507 bool to_uppcase = upcase;
509 bool change_case = false;
512 #if DO_MULTIBYTE && !defined COMPILE_WIDE
518 case L_('\b'): case L_('\t'): case L_('\n'):
519 case L_('\v'): case L_('\f'): case L_('\r'):
520 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
521 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
522 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
523 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
524 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
525 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
526 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
527 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
528 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
529 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
530 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
531 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
532 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
533 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
534 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
535 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
536 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
537 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
539 /* The C Standard requires these 98 characters (plus '%') to
540 be in the basic execution character set. None of these
541 characters can start a multibyte sequence, so they need
542 not be analyzed further. */
547 /* Copy this multibyte sequence until we reach its end, find
548 an error, or come back to the initial shift state. */
550 mbstate_t mbstate = mbstate_zero;
555 format_end = f + strlen (f) + 1;
556 fsize = format_end - f;
560 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
565 if (bytes == (size_t) -2)
567 len += strlen (f + len);
571 if (bytes == (size_t) -1)
579 while (! mbsinit (&mbstate));
587 #else /* ! DO_MULTIBYTE */
589 /* Either multibyte encodings are not supported, they are
590 safe for formats, so any non-'%' byte can be copied through,
591 or this is the wide character version. */
598 #endif /* ! DO_MULTIBYTE */
600 /* Check for flags that can modify a format. */
605 /* This influences the number formats. */
612 /* This changes textual output. */
626 /* As a GNU extension we allow to specify the field width. */
632 if (width > INT_MAX / 10
633 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
634 /* Avoid overflow. */
639 width += *f - L_('0');
643 while (ISDIGIT (*f));
646 /* Check for modifiers. */
659 /* Now do the specified format. */
663 #define DO_NUMBER(d, v) \
665 number_value = v; goto do_number
666 #define DO_SIGNED_NUMBER(d, negative, v) \
668 negative_number = negative; \
669 u_number_value = v; goto do_signed_number
671 /* The mask is not what you might think.
672 When the ordinal i'th bit is set, insert a colon
673 before the i'th digit of the time zone representation. */
674 #define DO_TZ_OFFSET(d, negative, mask, v) \
676 negative_number = negative; \
677 tz_colon_mask = mask; \
678 u_number_value = v; goto do_tz_offset
679 #define DO_NUMBER_SPACEPAD(d, v) \
681 number_value = v; goto do_number_spacepad
698 cpy (aw_len, a_wkday);
701 goto underlying_strftime;
713 cpy (STRLEN (f_wkday), f_wkday);
716 goto underlying_strftime;
729 cpy (am_len, a_month);
732 goto underlying_strftime;
744 cpy (STRLEN (f_month), f_month);
747 goto underlying_strftime;
751 if (modifier == L_('O'))
754 if (! (modifier == 'E'
756 (const CHAR_T *) _NL_CURRENT (LC_TIME,
759 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
761 goto underlying_strftime;
766 size_t len = strftime_case_ (to_uppcase,
767 NULL, STRFTIME_ARG ((size_t) -1)
769 tp extra_args LOCALE_ARG);
770 add (len, strftime_case_ (to_uppcase, p,
771 STRFTIME_ARG (maxsize - i)
773 tp extra_args LOCALE_ARG));
777 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
780 /* The relevant information is available only via the
781 underlying strftime implementation, so use that. */
784 char ubuf[1024]; /* enough for any single format in practice */
786 /* Make sure we're calling the actual underlying strftime.
787 In some cases, config.h contains something like
788 "#define strftime rpl_strftime". */
794 /* The space helps distinguish strftime failure from empty
802 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
804 cpy (len - 1, ubuf + 1);
810 if (modifier == L_('O'))
812 if (modifier == L_('E'))
814 #if HAVE_STRUCT_ERA_ENTRY
815 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
819 size_t len = __wcslen (era->era_wname);
820 cpy (len, era->era_wname);
822 size_t len = strlen (era->era_name);
823 cpy (len, era->era_name);
828 goto underlying_strftime;
833 int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
834 century -= tp->tm_year % 100 < 0 && 0 < century;
835 DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
839 if (modifier == L_('O'))
842 if (! (modifier == L_('E')
844 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
846 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
849 goto underlying_strftime;
854 subfmt = L_("%m/%d/%y");
858 if (modifier == L_('E'))
861 DO_NUMBER (2, tp->tm_mday);
864 if (modifier == L_('E'))
867 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
869 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
870 and then jump to one of these labels. */
873 always_output_a_sign = true;
877 /* Force `_' flag unless overridden by `0' or `-' flag. */
878 if (pad != L_('0') && pad != L_('-'))
882 /* Format NUMBER_VALUE according to the MODIFIER flag. */
883 negative_number = number_value < 0;
884 u_number_value = number_value;
887 always_output_a_sign = false;
891 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
892 NEGATIVE_NUMBER is nonzero if the original number was
893 negative; in this case it was converted directly to
894 unsigned int (i.e., modulo (UINT_MAX + 1)) without
896 if (modifier == L_('O') && !negative_number)
899 /* Get the locale specific alternate representation of
900 the number. If none exist NULL is returned. */
901 const CHAR_T *cp = nl_get_alt_digit (u_number_value
906 size_t digitlen = STRLEN (cp);
914 goto underlying_strftime;
918 bufp = buf + sizeof (buf) / sizeof (buf[0]);
921 u_number_value = - u_number_value;
925 if (tz_colon_mask & 1)
928 *--bufp = u_number_value % 10 + L_('0');
929 u_number_value /= 10;
931 while (u_number_value != 0 || tz_colon_mask != 0);
933 do_number_sign_and_padding:
937 sign_char = (negative_number ? L_('-')
938 : always_output_a_sign ? L_('+')
948 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
949 - bufp) - !!sign_char;
955 if ((size_t) padding >= maxsize - i)
959 memset_space (p, padding);
961 width = width > padding ? width - padding : 0;
967 if ((size_t) digits >= maxsize - i)
974 memset_zero (p, padding);
986 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
992 subfmt = L_("%Y-%m-%d");
996 if (modifier == L_('E'))
999 DO_NUMBER (2, tp->tm_hour);
1002 if (modifier == L_('E'))
1005 DO_NUMBER (2, hour12);
1007 case L_('k'): /* GNU extension. */
1008 if (modifier == L_('E'))
1011 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1013 case L_('l'): /* GNU extension. */
1014 if (modifier == L_('E'))
1017 DO_NUMBER_SPACEPAD (2, hour12);
1020 if (modifier == L_('E'))
1023 DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
1026 if (modifier == L_('E'))
1029 DO_NUMBER (2, tp->tm_min);
1032 if (modifier == L_('E'))
1035 DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
1038 case L_('N'): /* GNU extension. */
1039 if (modifier == L_('E'))
1047 /* Take an explicit width less than 9 as a precision. */
1049 for (j = width; j < 9; j++)
1053 DO_NUMBER (width, number_value);
1063 format_char = L_('p');
1077 goto underlying_strftime;
1081 subfmt = L_("%H:%M");
1086 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1089 subfmt = L_("%I:%M:%S %p");
1092 goto underlying_strftime;
1096 if (modifier == L_('E'))
1099 DO_NUMBER (2, tp->tm_sec);
1101 case L_('s'): /* GNU extension. */
1109 /* Generate string value for T using time_t arithmetic;
1110 this works even if sizeof (long) < sizeof (time_t). */
1112 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1113 negative_number = t < 0;
1119 *--bufp = (negative_number ? -d : d) + L_('0');
1124 always_output_a_sign = false;
1125 goto do_number_sign_and_padding;
1129 if (modifier == L_('O'))
1132 if (! (modifier == L_('E')
1134 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1136 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1139 goto underlying_strftime;
1142 subfmt = L_("%H:%M:%S");
1150 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1153 if (modifier == L_('E'))
1156 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1161 if (modifier == L_('E'))
1164 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1165 is a leap year, except that YEAR and YEAR - 1 both work
1166 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1168 int year = (tp->tm_year
1170 ? TM_YEAR_BASE % 400
1171 : TM_YEAR_BASE % 400 - 400));
1172 int year_adjust = 0;
1173 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1177 /* This ISO week belongs to the previous year. */
1179 days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
1184 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1188 /* This ISO week belongs to the next year. */
1198 int yy = (tp->tm_year % 100 + year_adjust) % 100;
1199 DO_NUMBER (2, (0 <= yy
1201 : tp->tm_year < -TM_YEAR_BASE - year_adjust
1207 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
1208 (tp->tm_year + (unsigned int) TM_YEAR_BASE
1212 DO_NUMBER (2, days / 7 + 1);
1217 if (modifier == L_('E'))
1220 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1223 if (modifier == L_('E'))
1226 DO_NUMBER (1, tp->tm_wday);
1229 if (modifier == 'E')
1231 #if HAVE_STRUCT_ERA_ENTRY
1232 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1235 # ifdef COMPILE_WIDE
1236 subfmt = era->era_wformat;
1238 subfmt = era->era_format;
1243 goto underlying_strftime;
1246 if (modifier == L_('O'))
1249 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1250 tp->tm_year + (unsigned int) TM_YEAR_BASE);
1253 if (modifier == L_('E'))
1255 #if HAVE_STRUCT_ERA_ENTRY
1256 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1259 int delta = tp->tm_year - era->start_date[0];
1260 DO_NUMBER (1, (era->offset
1261 + delta * era->absolute_direction));
1264 goto underlying_strftime;
1269 int yy = tp->tm_year % 100;
1271 yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
1283 /* The tzset() call might have changed the value. */
1284 if (!(zone && *zone) && tp->tm_isdst >= 0)
1285 zone = tzname[tp->tm_isdst != 0];
1292 /* The zone string is always given in multibyte form. We have
1293 to transform it first. */
1296 widen (zone, wczone, len);
1300 cpy (strlen (zone), zone);
1305 /* :, ::, and ::: are valid only just before 'z'.
1306 :::: etc. are rejected later. */
1307 for (colons = 1; f[colons] == L_(':'); colons++)
1309 if (f[colons] != L_('z'))
1312 goto do_z_conversion;
1318 if (tp->tm_isdst < 0)
1327 diff = tp->tm_gmtoff;
1340 if (lt == (time_t) -1)
1342 /* mktime returns -1 for errors, but -1 is also a
1343 valid time_t value. Check whether an error really
1347 if (! __localtime_r (<, &tm)
1348 || ((ltm.tm_sec ^ tm.tm_sec)
1349 | (ltm.tm_min ^ tm.tm_min)
1350 | (ltm.tm_hour ^ tm.tm_hour)
1351 | (ltm.tm_mday ^ tm.tm_mday)
1352 | (ltm.tm_mon ^ tm.tm_mon)
1353 | (ltm.tm_year ^ tm.tm_year)))
1357 if (! __gmtime_r (<, >m))
1360 diff = tm_diff (<m, >m);
1364 hour_diff = diff / 60 / 60;
1365 min_diff = diff / 60 % 60;
1366 sec_diff = diff % 60;
1371 DO_TZ_OFFSET (5, diff < 0, 0, hour_diff * 100 + min_diff);
1373 case 1: tz_hh_mm: /* +hh:mm */
1374 DO_TZ_OFFSET (6, diff < 0, 04, hour_diff * 100 + min_diff);
1376 case 2: tz_hh_mm_ss: /* +hh:mm:ss */
1377 DO_TZ_OFFSET (9, diff < 0, 024,
1378 hour_diff * 10000 + min_diff * 100 + sec_diff);
1380 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1385 DO_TZ_OFFSET (3, diff < 0, 0, hour_diff);
1392 case L_('\0'): /* GNU extension: % at end of format. */
1396 /* Unknown format; output the format, including the '%',
1397 since this is most likely the right thing to do if a
1398 multibyte string has been misparsed. */
1402 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1404 cpy (flen, &f[1 - flen]);
1411 if (p && maxsize != 0)
1418 /* Write information from TP into S according to the format
1419 string FORMAT, writing no more that MAXSIZE characters
1420 (including the terminating '\0') and returning number of
1421 characters written. If S is NULL, nothing will be written
1422 anywhere, so to determine how many characters would be
1423 written, use NULL for S and (size_t) -1 for MAXSIZE. */
1425 my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
1426 const CHAR_T *format,
1427 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
1429 return strftime_case_ (false, s, STRFTIME_ARG (maxsize)
1430 format, tp extra_args LOCALE_ARG);
1433 #if defined _LIBC && ! FPRINTFTIME
1434 libc_hidden_def (my_strftime)
1438 #if defined emacs && ! FPRINTFTIME
1439 /* For Emacs we have a separate interface which corresponds to the normal
1440 strftime function plus the ut argument, but without the ns argument. */
1442 emacs_strftimeu (char *s, size_t maxsize, const char *format,
1443 const struct tm *tp, int ut)
1445 return my_strftime (s, maxsize, format, tp, ut, 0);