1 /* Copyright (C) 1991-1999, 2000, 2001, 2003, 2004, 2005, 2006 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. */
27 # define HAVE_MBRLEN 1
28 # define HAVE_STRUCT_ERA_ENTRY 1
29 # define HAVE_TM_GMTOFF 1
30 # define HAVE_TM_ZONE 1
31 # define HAVE_TZNAME 1
33 # define MULTIBYTE_IS_FORMAT_SAFE 1
34 # include "../locale/localeinfo.h"
38 #include <sys/types.h> /* Some systems define `time_t' here. */
40 #ifdef TIME_WITH_SYS_TIME
41 # include <sys/time.h>
44 # ifdef HAVE_SYS_TIME_H
45 # include <sys/time.h>
50 #if HAVE_TZNAME && ! defined tzname
51 extern char *tzname[];
54 /* Do multibyte processing if multibytes are supported, unless
55 multibyte sequences are safe in formats. Multibyte sequences are
56 safe if they cannot contain byte sequences that look like format
57 conversion specifications. The GNU C Library uses UTF8 multibyte
58 encoding, which is safe for formats, but strftime.c can be used
59 with other C libraries that use unsafe encodings. */
60 #define DO_MULTIBYTE (HAVE_MBLEN && HAVE_WCHAR_H && ! MULTIBYTE_IS_FORMAT_SAFE)
66 /* Simulate mbrlen with mblen as best we can. */
67 # define mbstate_t int
68 # define mbrlen(s, n, ps) mblen (s, n)
69 # define mbsinit(ps) (*(ps) == 0)
71 static const mbstate_t mbstate_zero;
82 # define CHAR_T wchar_t
83 # define UCHAR_T unsigned int
84 # define L_(Str) L##Str
85 # define NLW(Sym) _NL_W##Sym
87 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
88 # define STRLEN(s) __wcslen (s)
92 # define UCHAR_T unsigned char
96 # define MEMCPY(d, s, n) memcpy (d, s, n)
97 # define STRLEN(s) strlen (s)
100 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
102 # ifndef HAVE_MEMPCPY
103 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
108 /* Shift A right by B bits portably, by dividing A by 2**B and
109 truncating towards minus infinity. A and B should be free of side
110 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
111 INT_BITS is the number of useful bits in an int. GNU code can
112 assume that INT_BITS is at least 32.
114 ISO C99 says that A >> B is implementation-defined if A < 0. Some
115 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
116 right in the usual way when A < 0, so SHR falls back on division if
117 ordinary A >> B doesn't seem to be the usual signed shift. */
121 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
123 /* Bound on length of the string representing an integer type or expression T.
124 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
125 add 1 for integer division truncation; add 1 more for a minus sign
127 #define INT_STRLEN_BOUND(t) \
128 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
130 #define TM_YEAR_BASE 1900
133 /* Nonzero if YEAR is a leap year (every 4 years,
134 except every 100th isn't, and every 400th is). */
135 # define __isleap(year) \
136 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
141 # define tzname __tzname
142 # define tzset __tzset
146 /* Portable standalone applications should supply a "time_r.h" that
147 declares a POSIX-compliant localtime_r, for the benefit of older
148 implementations that lack localtime_r or have a nonstandard one.
149 See the gnulib time_r module for one way to implement this. */
152 # undef __localtime_r
153 # define __gmtime_r gmtime_r
154 # define __localtime_r localtime_r
159 # define FPRINTFTIME 0
163 # define STREAM_OR_CHAR_T FILE
164 # define STRFTIME_ARG(x) /* empty */
166 # define STREAM_OR_CHAR_T CHAR_T
167 # define STRFTIME_ARG(x) x,
171 # define memset_byte(P, Len, Byte) \
172 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
173 # define memset_space(P, Len) memset_byte (P, Len, ' ')
174 # define memset_zero(P, Len) memset_byte (P, Len, '0')
175 #elif defined COMPILE_WIDE
176 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
177 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
179 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
180 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
187 int _delta = width - _n; \
188 int _incr = _n + (_delta > 0 ? _delta : 0); \
189 if ((size_t) _incr >= maxsize - i) \
193 if (digits == 0 && _delta > 0) \
195 if (pad == L_('0')) \
196 memset_zero (p, _delta); \
198 memset_space (p, _delta); \
201 p += FPRINTFTIME ? 0 : _n; \
207 # define add1(C) add (1, fputc (C, p))
209 # define add1(C) add (1, *p = C)
216 fwrite_lowcase (p, (s), _n); \
217 else if (to_uppcase) \
218 fwrite_uppcase (p, (s), _n); \
220 fwrite ((s), _n, 1, p))
225 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
226 else if (to_uppcase) \
227 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
229 MEMCPY ((void *) p, (void const *) (s), _n))
233 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
234 # undef __mbsrtowcs_l
235 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
237 # define widen(os, ws, l) \
240 const char *__s = os; \
241 memset (&__st, '\0', sizeof (__st)); \
242 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
243 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
244 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
249 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
250 /* We use this code also for the extended locale handling where the
251 function gets as an additional argument the locale which has to be
252 used. To access the values we have to redefine the _NL_CURRENT
254 # define strftime __strftime_l
255 # define wcsftime __wcsftime_l
257 # define _NL_CURRENT(category, item) \
258 (current->values[_NL_ITEM_INDEX (item)].string)
259 # define LOCALE_ARG , loc
260 # define LOCALE_PARAM_PROTO , __locale_t loc
261 # define HELPER_LOCALE_ARG , current
263 # define LOCALE_PARAM_PROTO
266 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
268 # define HELPER_LOCALE_ARG
273 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
274 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
275 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
277 # define TOUPPER(Ch, L) towupper (Ch)
278 # define TOLOWER(Ch, L) towlower (Ch)
281 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
282 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
283 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
285 # define TOUPPER(Ch, L) toupper (Ch)
286 # define TOLOWER(Ch, L) tolower (Ch)
289 /* We don't use `isdigit' here since the locale dependent
290 interpretation is not what we want here. We only need to accept
291 the arabic digits in the ASCII range. One day there is perhaps a
292 more reliable way to accept other sets of digits. */
293 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
297 fwrite_lowcase (FILE *fp, const CHAR_T *src, size_t len)
301 fputc (TOLOWER ((UCHAR_T) *src, loc), fp);
307 fwrite_uppcase (FILE *fp, const CHAR_T *src, size_t len)
311 fputc (TOUPPER ((UCHAR_T) *src, loc), fp);
317 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
318 size_t len LOCALE_PARAM_PROTO)
321 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
326 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
327 size_t len LOCALE_PARAM_PROTO)
330 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
337 /* Yield the difference between *A and *B,
338 measured in seconds, ignoring leap seconds. */
339 # define tm_diff ftime_tm_diff
341 tm_diff (const struct tm *a, const struct tm *b)
343 /* Compute intervening leap days correctly even if year is negative.
344 Take care to avoid int overflow in leap day calculations,
345 but it's OK to assume that A and B are close to each other. */
346 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
347 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
348 int a100 = a4 / 25 - (a4 % 25 < 0);
349 int b100 = b4 / 25 - (b4 % 25 < 0);
350 int a400 = SHR (a100, 2);
351 int b400 = SHR (b100, 2);
352 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
353 int years = a->tm_year - b->tm_year;
354 int days = (365 * years + intervening_leap_days
355 + (a->tm_yday - b->tm_yday));
356 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
357 + (a->tm_min - b->tm_min))
358 + (a->tm_sec - b->tm_sec));
360 #endif /* ! HAVE_TM_GMTOFF */
364 /* The number of days from the first day of the first ISO week of this
365 year to the year day YDAY with week day WDAY. ISO weeks start on
366 Monday; the first ISO week has the year's first Thursday. YDAY may
367 be as small as YDAY_MINIMUM. */
368 #define ISO_WEEK_START_WDAY 1 /* Monday */
369 #define ISO_WEEK1_WDAY 4 /* Thursday */
370 #define YDAY_MINIMUM (-366)
375 iso_week_days (int yday, int wday)
377 /* Add enough to the first operand of % to make it nonnegative. */
378 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
380 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
381 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
385 /* When compiling this file, GNU applications can #define my_strftime
386 to a symbol (typically nstrftime) to get an extended strftime with
387 extra arguments UT and NS. Emacs is a special case for now, but
388 this Emacs-specific code can be removed once Emacs's config.h
389 defines my_strftime. */
390 #if defined emacs && !defined my_strftime
391 # define my_strftime nstrftime
396 # define my_strftime fprintftime
400 # define extra_args , ut, ns
401 # define extra_args_spec , int ut, int ns
403 # if defined COMPILE_WIDE
404 # define my_strftime wcsftime
405 # define nl_get_alt_digit _nl_get_walt_digit
407 # define my_strftime strftime
408 # define nl_get_alt_digit _nl_get_alt_digit
411 # define extra_args_spec
412 /* We don't have this information in general. */
418 /* Just like my_strftime, below, but with one more parameter, UPCASE,
419 to indicate that the result should be converted to upper case. */
421 strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
422 STRFTIME_ARG (size_t maxsize)
423 const CHAR_T *format,
424 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
426 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
427 struct locale_data *const current = loc->__locales[LC_TIME];
430 size_t maxsize = (size_t) -1;
433 int hour12 = tp->tm_hour;
435 /* We cannot make the following values variables since we must delay
436 the evaluation of these values until really needed since some
437 expressions might not be valid in every situation. The `struct tm'
438 might be generated by a strptime() call that initialized
439 only a few elements. Dereference the pointers only if the format
440 requires this. Then it is ok to fail if the pointers are invalid. */
442 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
444 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
446 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
448 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
450 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
451 ? NLW(PM_STR) : NLW(AM_STR)))
453 # define aw_len STRLEN (a_wkday)
454 # define am_len STRLEN (a_month)
455 # define ap_len STRLEN (ampm)
459 STREAM_OR_CHAR_T *p = s;
461 #if DO_MULTIBYTE && !defined COMPILE_WIDE
462 const char *format_end = NULL;
465 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
466 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
467 by localtime. On such systems, we must either use the tzset and
468 localtime wrappers to work around the bug (which sets
469 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
470 struct tm copy = *tp;
476 /* The POSIX test suite assumes that setting
477 the environment variable TZ to a new value before calling strftime()
478 will influence the result (the %Z format) even if the information in
479 TP is computed with a totally different time zone.
480 This is bogus: though POSIX allows bad behavior like this,
481 POSIX does not require it. Do the right thing instead. */
482 zone = (const char *) tp->tm_zone;
487 if (! (zone && *zone))
492 /* POSIX.1 requires that local time zone information be used as
493 though strftime called tzset. */
506 for (f = format; *f != '\0'; ++f)
508 int pad = 0; /* Padding for number ('-', '_', or 0). */
509 int modifier; /* Field modifier ('E', 'O', or 0). */
510 int digits = 0; /* Max digits for numeric format. */
511 int number_value; /* Numeric value to be printed. */
512 unsigned int u_number_value; /* (unsigned int) number_value. */
513 bool negative_number; /* The number is negative. */
514 bool always_output_a_sign; /* +/- should always be output. */
515 int tz_colon_mask; /* Bitmask of where ':' should appear. */
516 const CHAR_T *subfmt;
520 + 2 /* for the two colons in a %::z or %:::z time zone */
521 + (sizeof (int) < sizeof (time_t)
522 ? INT_STRLEN_BOUND (time_t)
523 : INT_STRLEN_BOUND (int))];
525 bool to_lowcase = false;
526 bool to_uppcase = upcase;
528 bool change_case = false;
531 #if DO_MULTIBYTE && !defined COMPILE_WIDE
537 case L_('\b'): case L_('\t'): case L_('\n'):
538 case L_('\v'): case L_('\f'): case L_('\r'):
539 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
540 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
541 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
542 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
543 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
544 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
545 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
546 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
547 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
548 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
549 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
550 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
551 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
552 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
553 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
554 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
555 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
556 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
558 /* The C Standard requires these 98 characters (plus '%') to
559 be in the basic execution character set. None of these
560 characters can start a multibyte sequence, so they need
561 not be analyzed further. */
566 /* Copy this multibyte sequence until we reach its end, find
567 an error, or come back to the initial shift state. */
569 mbstate_t mbstate = mbstate_zero;
574 format_end = f + strlen (f) + 1;
575 fsize = format_end - f;
579 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
584 if (bytes == (size_t) -2)
586 len += strlen (f + len);
590 if (bytes == (size_t) -1)
598 while (! mbsinit (&mbstate));
606 #else /* ! DO_MULTIBYTE */
608 /* Either multibyte encodings are not supported, they are
609 safe for formats, so any non-'%' byte can be copied through,
610 or this is the wide character version. */
617 #endif /* ! DO_MULTIBYTE */
619 /* Check for flags that can modify a format. */
624 /* This influences the number formats. */
631 /* This changes textual output. */
645 /* As a GNU extension we allow to specify the field width. */
651 if (width > INT_MAX / 10
652 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
653 /* Avoid overflow. */
658 width += *f - L_('0');
662 while (ISDIGIT (*f));
665 /* Check for modifiers. */
678 /* Now do the specified format. */
682 #define DO_NUMBER(d, v) \
684 number_value = v; goto do_number
685 #define DO_SIGNED_NUMBER(d, negative, v) \
687 negative_number = negative; \
688 u_number_value = v; goto do_signed_number
690 /* The mask is not what you might think.
691 When the ordinal i'th bit is set, insert a colon
692 before the i'th digit of the time zone representation. */
693 #define DO_TZ_OFFSET(d, negative, mask, v) \
695 negative_number = negative; \
696 tz_colon_mask = mask; \
697 u_number_value = v; goto do_tz_offset
698 #define DO_NUMBER_SPACEPAD(d, v) \
700 number_value = v; goto do_number_spacepad
717 cpy (aw_len, a_wkday);
720 goto underlying_strftime;
732 cpy (STRLEN (f_wkday), f_wkday);
735 goto underlying_strftime;
748 cpy (am_len, a_month);
751 goto underlying_strftime;
763 cpy (STRLEN (f_month), f_month);
766 goto underlying_strftime;
770 if (modifier == L_('O'))
773 if (! (modifier == 'E'
775 (const CHAR_T *) _NL_CURRENT (LC_TIME,
778 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
780 goto underlying_strftime;
785 size_t len = strftime_case_ (to_uppcase,
786 NULL, STRFTIME_ARG ((size_t) -1)
788 tp extra_args LOCALE_ARG);
789 add (len, strftime_case_ (to_uppcase, p,
790 STRFTIME_ARG (maxsize - i)
792 tp extra_args LOCALE_ARG));
796 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
799 /* The relevant information is available only via the
800 underlying strftime implementation, so use that. */
803 char ubuf[1024]; /* enough for any single format in practice */
805 /* Make sure we're calling the actual underlying strftime.
806 In some cases, config.h contains something like
807 "#define strftime rpl_strftime". */
813 /* The space helps distinguish strftime failure from empty
821 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
823 cpy (len - 1, ubuf + 1);
829 if (modifier == L_('O'))
831 if (modifier == L_('E'))
833 #if HAVE_STRUCT_ERA_ENTRY
834 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
838 size_t len = __wcslen (era->era_wname);
839 cpy (len, era->era_wname);
841 size_t len = strlen (era->era_name);
842 cpy (len, era->era_name);
847 goto underlying_strftime;
852 int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
853 century -= tp->tm_year % 100 < 0 && 0 < century;
854 DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
858 if (modifier == L_('O'))
861 if (! (modifier == L_('E')
863 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
865 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
868 goto underlying_strftime;
873 subfmt = L_("%m/%d/%y");
877 if (modifier == L_('E'))
880 DO_NUMBER (2, tp->tm_mday);
883 if (modifier == L_('E'))
886 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
888 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
889 and then jump to one of these labels. */
892 always_output_a_sign = true;
896 /* Force `_' flag unless overridden by `0' or `-' flag. */
897 if (pad != L_('0') && pad != L_('-'))
901 /* Format NUMBER_VALUE according to the MODIFIER flag. */
902 negative_number = number_value < 0;
903 u_number_value = number_value;
906 always_output_a_sign = false;
910 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
911 NEGATIVE_NUMBER is nonzero if the original number was
912 negative; in this case it was converted directly to
913 unsigned int (i.e., modulo (UINT_MAX + 1)) without
915 if (modifier == L_('O') && !negative_number)
918 /* Get the locale specific alternate representation of
919 the number. If none exist NULL is returned. */
920 const CHAR_T *cp = nl_get_alt_digit (u_number_value
925 size_t digitlen = STRLEN (cp);
933 goto underlying_strftime;
937 bufp = buf + sizeof (buf) / sizeof (buf[0]);
940 u_number_value = - u_number_value;
944 if (tz_colon_mask & 1)
947 *--bufp = u_number_value % 10 + L_('0');
948 u_number_value /= 10;
950 while (u_number_value != 0 || tz_colon_mask != 0);
952 do_number_sign_and_padding:
956 sign_char = (negative_number ? L_('-')
957 : always_output_a_sign ? L_('+')
967 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
968 - bufp) - !!sign_char;
974 if ((size_t) padding >= maxsize - i)
978 memset_space (p, padding);
980 width = width > padding ? width - padding : 0;
986 if ((size_t) digits >= maxsize - i)
993 memset_zero (p, padding);
1005 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1011 subfmt = L_("%Y-%m-%d");
1015 if (modifier == L_('E'))
1018 DO_NUMBER (2, tp->tm_hour);
1021 if (modifier == L_('E'))
1024 DO_NUMBER (2, hour12);
1026 case L_('k'): /* GNU extension. */
1027 if (modifier == L_('E'))
1030 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1032 case L_('l'): /* GNU extension. */
1033 if (modifier == L_('E'))
1036 DO_NUMBER_SPACEPAD (2, hour12);
1039 if (modifier == L_('E'))
1042 DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
1045 if (modifier == L_('E'))
1048 DO_NUMBER (2, tp->tm_min);
1051 if (modifier == L_('E'))
1054 DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
1057 case L_('N'): /* GNU extension. */
1058 if (modifier == L_('E'))
1066 /* Take an explicit width less than 9 as a precision. */
1068 for (j = width; j < 9; j++)
1072 DO_NUMBER (width, number_value);
1082 format_char = L_('p');
1096 goto underlying_strftime;
1100 subfmt = L_("%H:%M");
1105 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1108 subfmt = L_("%I:%M:%S %p");
1111 goto underlying_strftime;
1115 if (modifier == L_('E'))
1118 DO_NUMBER (2, tp->tm_sec);
1120 case L_('s'): /* GNU extension. */
1128 /* Generate string value for T using time_t arithmetic;
1129 this works even if sizeof (long) < sizeof (time_t). */
1131 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1132 negative_number = t < 0;
1138 *--bufp = (negative_number ? -d : d) + L_('0');
1143 always_output_a_sign = false;
1144 goto do_number_sign_and_padding;
1148 if (modifier == L_('O'))
1151 if (! (modifier == L_('E')
1153 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1155 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1158 goto underlying_strftime;
1161 subfmt = L_("%H:%M:%S");
1169 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1172 if (modifier == L_('E'))
1175 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1180 if (modifier == L_('E'))
1183 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1184 is a leap year, except that YEAR and YEAR - 1 both work
1185 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1187 int year = (tp->tm_year
1189 ? TM_YEAR_BASE % 400
1190 : TM_YEAR_BASE % 400 - 400));
1191 int year_adjust = 0;
1192 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1196 /* This ISO week belongs to the previous year. */
1198 days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
1203 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1207 /* This ISO week belongs to the next year. */
1217 int yy = (tp->tm_year % 100 + year_adjust) % 100;
1218 DO_NUMBER (2, (0 <= yy
1220 : tp->tm_year < -TM_YEAR_BASE - year_adjust
1226 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
1227 (tp->tm_year + (unsigned int) TM_YEAR_BASE
1231 DO_NUMBER (2, days / 7 + 1);
1236 if (modifier == L_('E'))
1239 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1242 if (modifier == L_('E'))
1245 DO_NUMBER (1, tp->tm_wday);
1248 if (modifier == 'E')
1250 #if HAVE_STRUCT_ERA_ENTRY
1251 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1254 # ifdef COMPILE_WIDE
1255 subfmt = era->era_wformat;
1257 subfmt = era->era_format;
1262 goto underlying_strftime;
1265 if (modifier == L_('O'))
1268 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1269 tp->tm_year + (unsigned int) TM_YEAR_BASE);
1272 if (modifier == L_('E'))
1274 #if HAVE_STRUCT_ERA_ENTRY
1275 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1278 int delta = tp->tm_year - era->start_date[0];
1279 DO_NUMBER (1, (era->offset
1280 + delta * era->absolute_direction));
1283 goto underlying_strftime;
1288 int yy = tp->tm_year % 100;
1290 yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
1302 /* The tzset() call might have changed the value. */
1303 if (!(zone && *zone) && tp->tm_isdst >= 0)
1304 zone = tzname[tp->tm_isdst != 0];
1311 /* The zone string is always given in multibyte form. We have
1312 to transform it first. */
1315 widen (zone, wczone, len);
1319 cpy (strlen (zone), zone);
1324 /* :, ::, and ::: are valid only just before 'z'.
1325 :::: etc. are rejected later. */
1326 for (colons = 1; f[colons] == L_(':'); colons++)
1328 if (f[colons] != L_('z'))
1331 goto do_z_conversion;
1337 if (tp->tm_isdst < 0)
1346 diff = tp->tm_gmtoff;
1359 if (lt == (time_t) -1)
1361 /* mktime returns -1 for errors, but -1 is also a
1362 valid time_t value. Check whether an error really
1366 if (! __localtime_r (<, &tm)
1367 || ((ltm.tm_sec ^ tm.tm_sec)
1368 | (ltm.tm_min ^ tm.tm_min)
1369 | (ltm.tm_hour ^ tm.tm_hour)
1370 | (ltm.tm_mday ^ tm.tm_mday)
1371 | (ltm.tm_mon ^ tm.tm_mon)
1372 | (ltm.tm_year ^ tm.tm_year)))
1376 if (! __gmtime_r (<, >m))
1379 diff = tm_diff (<m, >m);
1383 hour_diff = diff / 60 / 60;
1384 min_diff = diff / 60 % 60;
1385 sec_diff = diff % 60;
1390 DO_TZ_OFFSET (5, diff < 0, 0, hour_diff * 100 + min_diff);
1392 case 1: tz_hh_mm: /* +hh:mm */
1393 DO_TZ_OFFSET (6, diff < 0, 04, hour_diff * 100 + min_diff);
1395 case 2: tz_hh_mm_ss: /* +hh:mm:ss */
1396 DO_TZ_OFFSET (9, diff < 0, 024,
1397 hour_diff * 10000 + min_diff * 100 + sec_diff);
1399 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1404 DO_TZ_OFFSET (3, diff < 0, 0, hour_diff);
1411 case L_('\0'): /* GNU extension: % at end of format. */
1415 /* Unknown format; output the format, including the '%',
1416 since this is most likely the right thing to do if a
1417 multibyte string has been misparsed. */
1421 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1423 cpy (flen, &f[1 - flen]);
1430 if (p && maxsize != 0)
1437 /* Write information from TP into S according to the format
1438 string FORMAT, writing no more that MAXSIZE characters
1439 (including the terminating '\0') and returning number of
1440 characters written. If S is NULL, nothing will be written
1441 anywhere, so to determine how many characters would be
1442 written, use NULL for S and (size_t) -1 for MAXSIZE. */
1444 my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
1445 const CHAR_T *format,
1446 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
1448 return strftime_case_ (false, s, STRFTIME_ARG (maxsize)
1449 format, tp extra_args LOCALE_ARG);
1452 #if defined _LIBC && ! FPRINTFTIME
1453 libc_hidden_def (my_strftime)
1457 #if defined emacs && ! FPRINTFTIME
1458 /* For Emacs we have a separate interface which corresponds to the normal
1459 strftime function plus the ut argument, but without the ns argument. */
1461 emacs_strftimeu (char *s, size_t maxsize, const char *format,
1462 const struct tm *tp, int ut)
1464 return my_strftime (s, maxsize, format, tp, ut, 0);