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_r.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. */
143 # undef __localtime_r
144 # define __gmtime_r gmtime_r
145 # define __localtime_r localtime_r
150 # define FPRINTFTIME 0
154 # define STREAM_OR_CHAR_T FILE
155 # define STRFTIME_ARG(x) /* empty */
157 # define STREAM_OR_CHAR_T CHAR_T
158 # define STRFTIME_ARG(x) x,
162 # define memset_byte(P, Len, Byte) \
163 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
164 # define memset_space(P, Len) memset_byte (P, Len, ' ')
165 # define memset_zero(P, Len) memset_byte (P, Len, '0')
166 #elif defined COMPILE_WIDE
167 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
168 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
170 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
171 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
175 # define advance(P, N)
177 # define advance(P, N) ((P) += (N))
184 int _delta = width - _n; \
185 int _incr = _n + (_delta > 0 ? _delta : 0); \
186 if ((size_t) _incr >= maxsize - i) \
190 if (digits == 0 && _delta > 0) \
192 if (pad == L_('0')) \
193 memset_zero (p, _delta); \
195 memset_space (p, _delta); \
204 # define add1(C) add (1, fputc (C, p))
206 # define add1(C) add (1, *p = C)
213 fwrite_lowcase (p, (s), _n); \
214 else if (to_uppcase) \
215 fwrite_uppcase (p, (s), _n); \
217 fwrite ((s), _n, 1, p))
222 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
223 else if (to_uppcase) \
224 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
226 MEMCPY ((void *) p, (void const *) (s), _n))
230 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
231 # undef __mbsrtowcs_l
232 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
234 # define widen(os, ws, l) \
237 const char *__s = os; \
238 memset (&__st, '\0', sizeof (__st)); \
239 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
240 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
241 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
246 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
247 /* We use this code also for the extended locale handling where the
248 function gets as an additional argument the locale which has to be
249 used. To access the values we have to redefine the _NL_CURRENT
251 # define strftime __strftime_l
252 # define wcsftime __wcsftime_l
254 # define _NL_CURRENT(category, item) \
255 (current->values[_NL_ITEM_INDEX (item)].string)
256 # define LOCALE_ARG , loc
257 # define LOCALE_PARAM_PROTO , __locale_t loc
258 # define HELPER_LOCALE_ARG , current
260 # define LOCALE_PARAM_PROTO
263 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
265 # define HELPER_LOCALE_ARG
270 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
271 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
272 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
274 # define TOUPPER(Ch, L) towupper (Ch)
275 # define TOLOWER(Ch, L) towlower (Ch)
278 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
279 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
280 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
282 # define TOUPPER(Ch, L) toupper (Ch)
283 # define TOLOWER(Ch, L) tolower (Ch)
286 /* We don't use `isdigit' here since the locale dependent
287 interpretation is not what we want here. We only need to accept
288 the arabic digits in the ASCII range. One day there is perhaps a
289 more reliable way to accept other sets of digits. */
290 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
294 fwrite_lowcase (FILE *fp, const CHAR_T *src, size_t len)
298 fputc (TOLOWER ((UCHAR_T) *src, loc), fp);
304 fwrite_uppcase (FILE *fp, const CHAR_T *src, size_t len)
308 fputc (TOUPPER ((UCHAR_T) *src, loc), fp);
314 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
315 size_t len LOCALE_PARAM_PROTO)
318 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
323 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
324 size_t len LOCALE_PARAM_PROTO)
327 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
334 /* Yield the difference between *A and *B,
335 measured in seconds, ignoring leap seconds. */
336 # define tm_diff ftime_tm_diff
338 tm_diff (const struct tm *a, const struct tm *b)
340 /* Compute intervening leap days correctly even if year is negative.
341 Take care to avoid int overflow in leap day calculations,
342 but it's OK to assume that A and B are close to each other. */
343 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
344 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
345 int a100 = a4 / 25 - (a4 % 25 < 0);
346 int b100 = b4 / 25 - (b4 % 25 < 0);
347 int a400 = SHR (a100, 2);
348 int b400 = SHR (b100, 2);
349 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
350 int years = a->tm_year - b->tm_year;
351 int days = (365 * years + intervening_leap_days
352 + (a->tm_yday - b->tm_yday));
353 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
354 + (a->tm_min - b->tm_min))
355 + (a->tm_sec - b->tm_sec));
357 #endif /* ! HAVE_TM_GMTOFF */
361 /* The number of days from the first day of the first ISO week of this
362 year to the year day YDAY with week day WDAY. ISO weeks start on
363 Monday; the first ISO week has the year's first Thursday. YDAY may
364 be as small as YDAY_MINIMUM. */
365 #define ISO_WEEK_START_WDAY 1 /* Monday */
366 #define ISO_WEEK1_WDAY 4 /* Thursday */
367 #define YDAY_MINIMUM (-366)
372 iso_week_days (int yday, int wday)
374 /* Add enough to the first operand of % to make it nonnegative. */
375 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
377 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
378 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
382 /* When compiling this file, GNU applications can #define my_strftime
383 to a symbol (typically nstrftime) to get an extended strftime with
384 extra arguments UT and NS. Emacs is a special case for now, but
385 this Emacs-specific code can be removed once Emacs's config.h
386 defines my_strftime. */
387 #if defined emacs && !defined my_strftime
388 # define my_strftime nstrftime
393 # define my_strftime fprintftime
397 # define extra_args , ut, ns
398 # define extra_args_spec , int ut, int ns
400 # if defined COMPILE_WIDE
401 # define my_strftime wcsftime
402 # define nl_get_alt_digit _nl_get_walt_digit
404 # define my_strftime strftime
405 # define nl_get_alt_digit _nl_get_alt_digit
408 # define extra_args_spec
409 /* We don't have this information in general. */
415 /* Just like my_strftime, below, but with one more parameter, UPCASE,
416 to indicate that the result should be converted to upper case. */
418 strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
419 STRFTIME_ARG (size_t maxsize)
420 const CHAR_T *format,
421 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
423 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
424 struct locale_data *const current = loc->__locales[LC_TIME];
427 size_t maxsize = (size_t) -1;
430 int hour12 = tp->tm_hour;
432 /* We cannot make the following values variables since we must delay
433 the evaluation of these values until really needed since some
434 expressions might not be valid in every situation. The `struct tm'
435 might be generated by a strptime() call that initialized
436 only a few elements. Dereference the pointers only if the format
437 requires this. Then it is ok to fail if the pointers are invalid. */
439 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
441 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
443 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
445 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
447 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
448 ? NLW(PM_STR) : NLW(AM_STR)))
450 # define aw_len STRLEN (a_wkday)
451 # define am_len STRLEN (a_month)
452 # define ap_len STRLEN (ampm)
456 STREAM_OR_CHAR_T *p = s;
458 #if DO_MULTIBYTE && !defined COMPILE_WIDE
459 const char *format_end = NULL;
462 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
463 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
464 by localtime. On such systems, we must either use the tzset and
465 localtime wrappers to work around the bug (which sets
466 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
467 struct tm copy = *tp;
473 /* The POSIX test suite assumes that setting
474 the environment variable TZ to a new value before calling strftime()
475 will influence the result (the %Z format) even if the information in
476 TP is computed with a totally different time zone.
477 This is bogus: though POSIX allows bad behavior like this,
478 POSIX does not require it. Do the right thing instead. */
479 zone = (const char *) tp->tm_zone;
484 if (! (zone && *zone))
489 /* POSIX.1 requires that local time zone information be used as
490 though strftime called tzset. */
503 for (f = format; *f != '\0'; ++f)
505 int pad = 0; /* Padding for number ('-', '_', or 0). */
506 int modifier; /* Field modifier ('E', 'O', or 0). */
507 int digits = 0; /* Max digits for numeric format. */
508 int number_value; /* Numeric value to be printed. */
509 unsigned int u_number_value; /* (unsigned int) number_value. */
510 bool negative_number; /* The number is negative. */
511 bool always_output_a_sign; /* +/- should always be output. */
512 int tz_colon_mask; /* Bitmask of where ':' should appear. */
513 const CHAR_T *subfmt;
517 + 2 /* for the two colons in a %::z or %:::z time zone */
518 + (sizeof (int) < sizeof (time_t)
519 ? INT_STRLEN_BOUND (time_t)
520 : INT_STRLEN_BOUND (int))];
522 bool to_lowcase = false;
523 bool to_uppcase = upcase;
525 bool change_case = false;
528 #if DO_MULTIBYTE && !defined COMPILE_WIDE
534 case L_('\b'): case L_('\t'): case L_('\n'):
535 case L_('\v'): case L_('\f'): case L_('\r'):
536 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
537 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
538 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
539 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
540 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
541 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
542 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
543 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
544 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
545 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
546 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
547 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
548 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
549 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
550 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
551 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
552 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
553 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
555 /* The C Standard requires these 98 characters (plus '%') to
556 be in the basic execution character set. None of these
557 characters can start a multibyte sequence, so they need
558 not be analyzed further. */
563 /* Copy this multibyte sequence until we reach its end, find
564 an error, or come back to the initial shift state. */
566 mbstate_t mbstate = mbstate_zero;
571 format_end = f + strlen (f) + 1;
572 fsize = format_end - f;
576 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
581 if (bytes == (size_t) -2)
583 len += strlen (f + len);
587 if (bytes == (size_t) -1)
595 while (! mbsinit (&mbstate));
603 #else /* ! DO_MULTIBYTE */
605 /* Either multibyte encodings are not supported, they are
606 safe for formats, so any non-'%' byte can be copied through,
607 or this is the wide character version. */
614 #endif /* ! DO_MULTIBYTE */
616 /* Check for flags that can modify a format. */
621 /* This influences the number formats. */
628 /* This changes textual output. */
642 /* As a GNU extension we allow to specify the field width. */
648 if (width > INT_MAX / 10
649 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
650 /* Avoid overflow. */
655 width += *f - L_('0');
659 while (ISDIGIT (*f));
662 /* Check for modifiers. */
675 /* Now do the specified format. */
679 #define DO_NUMBER(d, v) \
681 number_value = v; goto do_number
682 #define DO_SIGNED_NUMBER(d, negative, v) \
684 negative_number = negative; \
685 u_number_value = v; goto do_signed_number
687 /* The mask is not what you might think.
688 When the ordinal i'th bit is set, insert a colon
689 before the i'th digit of the time zone representation. */
690 #define DO_TZ_OFFSET(d, negative, mask, v) \
692 negative_number = negative; \
693 tz_colon_mask = mask; \
694 u_number_value = v; goto do_tz_offset
695 #define DO_NUMBER_SPACEPAD(d, v) \
697 number_value = v; goto do_number_spacepad
714 cpy (aw_len, a_wkday);
717 goto underlying_strftime;
729 cpy (STRLEN (f_wkday), f_wkday);
732 goto underlying_strftime;
745 cpy (am_len, a_month);
748 goto underlying_strftime;
760 cpy (STRLEN (f_month), f_month);
763 goto underlying_strftime;
767 if (modifier == L_('O'))
770 if (! (modifier == 'E'
772 (const CHAR_T *) _NL_CURRENT (LC_TIME,
775 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
777 goto underlying_strftime;
782 size_t len = strftime_case_ (to_uppcase,
783 NULL, STRFTIME_ARG ((size_t) -1)
785 tp extra_args LOCALE_ARG);
786 add (len, strftime_case_ (to_uppcase, p,
787 STRFTIME_ARG (maxsize - i)
789 tp extra_args LOCALE_ARG));
793 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
796 /* The relevant information is available only via the
797 underlying strftime implementation, so use that. */
800 char ubuf[1024]; /* enough for any single format in practice */
802 /* Make sure we're calling the actual underlying strftime.
803 In some cases, config.h contains something like
804 "#define strftime rpl_strftime". */
810 /* The space helps distinguish strftime failure from empty
818 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
820 cpy (len - 1, ubuf + 1);
826 if (modifier == L_('O'))
828 if (modifier == L_('E'))
830 #if HAVE_STRUCT_ERA_ENTRY
831 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
835 size_t len = __wcslen (era->era_wname);
836 cpy (len, era->era_wname);
838 size_t len = strlen (era->era_name);
839 cpy (len, era->era_name);
844 goto underlying_strftime;
849 int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
850 century -= tp->tm_year % 100 < 0 && 0 < century;
851 DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
855 if (modifier == L_('O'))
858 if (! (modifier == L_('E')
860 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
862 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
865 goto underlying_strftime;
870 subfmt = L_("%m/%d/%y");
874 if (modifier == L_('E'))
877 DO_NUMBER (2, tp->tm_mday);
880 if (modifier == L_('E'))
883 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
885 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
886 and then jump to one of these labels. */
889 always_output_a_sign = true;
893 /* Force `_' flag unless overridden by `0' or `-' flag. */
894 if (pad != L_('0') && pad != L_('-'))
898 /* Format NUMBER_VALUE according to the MODIFIER flag. */
899 negative_number = number_value < 0;
900 u_number_value = number_value;
903 always_output_a_sign = false;
907 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
908 NEGATIVE_NUMBER is nonzero if the original number was
909 negative; in this case it was converted directly to
910 unsigned int (i.e., modulo (UINT_MAX + 1)) without
912 if (modifier == L_('O') && !negative_number)
915 /* Get the locale specific alternate representation of
916 the number. If none exist NULL is returned. */
917 const CHAR_T *cp = nl_get_alt_digit (u_number_value
922 size_t digitlen = STRLEN (cp);
930 goto underlying_strftime;
934 bufp = buf + sizeof (buf) / sizeof (buf[0]);
937 u_number_value = - u_number_value;
941 if (tz_colon_mask & 1)
944 *--bufp = u_number_value % 10 + L_('0');
945 u_number_value /= 10;
947 while (u_number_value != 0 || tz_colon_mask != 0);
949 do_number_sign_and_padding:
953 sign_char = (negative_number ? L_('-')
954 : always_output_a_sign ? L_('+')
964 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
965 - bufp) - !!sign_char;
971 if ((size_t) padding >= maxsize - i)
975 memset_space (p, padding);
977 width = width > padding ? width - padding : 0;
983 if ((size_t) digits >= maxsize - i)
990 memset_zero (p, padding);
1002 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
1008 subfmt = L_("%Y-%m-%d");
1012 if (modifier == L_('E'))
1015 DO_NUMBER (2, tp->tm_hour);
1018 if (modifier == L_('E'))
1021 DO_NUMBER (2, hour12);
1023 case L_('k'): /* GNU extension. */
1024 if (modifier == L_('E'))
1027 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1029 case L_('l'): /* GNU extension. */
1030 if (modifier == L_('E'))
1033 DO_NUMBER_SPACEPAD (2, hour12);
1036 if (modifier == L_('E'))
1039 DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
1042 if (modifier == L_('E'))
1045 DO_NUMBER (2, tp->tm_min);
1048 if (modifier == L_('E'))
1051 DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
1054 case L_('N'): /* GNU extension. */
1055 if (modifier == L_('E'))
1063 /* Take an explicit width less than 9 as a precision. */
1065 for (j = width; j < 9; j++)
1069 DO_NUMBER (width, number_value);
1079 format_char = L_('p');
1093 goto underlying_strftime;
1097 subfmt = L_("%H:%M");
1102 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1105 subfmt = L_("%I:%M:%S %p");
1108 goto underlying_strftime;
1112 if (modifier == L_('E'))
1115 DO_NUMBER (2, tp->tm_sec);
1117 case L_('s'): /* GNU extension. */
1125 /* Generate string value for T using time_t arithmetic;
1126 this works even if sizeof (long) < sizeof (time_t). */
1128 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1129 negative_number = t < 0;
1135 *--bufp = (negative_number ? -d : d) + L_('0');
1140 always_output_a_sign = false;
1141 goto do_number_sign_and_padding;
1145 if (modifier == L_('O'))
1148 if (! (modifier == L_('E')
1150 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1152 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1155 goto underlying_strftime;
1158 subfmt = L_("%H:%M:%S");
1166 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1169 if (modifier == L_('E'))
1172 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1177 if (modifier == L_('E'))
1180 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1181 is a leap year, except that YEAR and YEAR - 1 both work
1182 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1184 int year = (tp->tm_year
1186 ? TM_YEAR_BASE % 400
1187 : TM_YEAR_BASE % 400 - 400));
1188 int year_adjust = 0;
1189 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1193 /* This ISO week belongs to the previous year. */
1195 days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
1200 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1204 /* This ISO week belongs to the next year. */
1214 int yy = (tp->tm_year % 100 + year_adjust) % 100;
1215 DO_NUMBER (2, (0 <= yy
1217 : tp->tm_year < -TM_YEAR_BASE - year_adjust
1223 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
1224 (tp->tm_year + (unsigned int) TM_YEAR_BASE
1228 DO_NUMBER (2, days / 7 + 1);
1233 if (modifier == L_('E'))
1236 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1239 if (modifier == L_('E'))
1242 DO_NUMBER (1, tp->tm_wday);
1245 if (modifier == 'E')
1247 #if HAVE_STRUCT_ERA_ENTRY
1248 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1251 # ifdef COMPILE_WIDE
1252 subfmt = era->era_wformat;
1254 subfmt = era->era_format;
1259 goto underlying_strftime;
1262 if (modifier == L_('O'))
1265 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1266 tp->tm_year + (unsigned int) TM_YEAR_BASE);
1269 if (modifier == L_('E'))
1271 #if HAVE_STRUCT_ERA_ENTRY
1272 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1275 int delta = tp->tm_year - era->start_date[0];
1276 DO_NUMBER (1, (era->offset
1277 + delta * era->absolute_direction));
1280 goto underlying_strftime;
1285 int yy = tp->tm_year % 100;
1287 yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
1299 /* The tzset() call might have changed the value. */
1300 if (!(zone && *zone) && tp->tm_isdst >= 0)
1301 zone = tzname[tp->tm_isdst != 0];
1308 /* The zone string is always given in multibyte form. We have
1309 to transform it first. */
1312 widen (zone, wczone, len);
1316 cpy (strlen (zone), zone);
1321 /* :, ::, and ::: are valid only just before 'z'.
1322 :::: etc. are rejected later. */
1323 for (colons = 1; f[colons] == L_(':'); colons++)
1325 if (f[colons] != L_('z'))
1328 goto do_z_conversion;
1334 if (tp->tm_isdst < 0)
1343 diff = tp->tm_gmtoff;
1356 if (lt == (time_t) -1)
1358 /* mktime returns -1 for errors, but -1 is also a
1359 valid time_t value. Check whether an error really
1363 if (! __localtime_r (<, &tm)
1364 || ((ltm.tm_sec ^ tm.tm_sec)
1365 | (ltm.tm_min ^ tm.tm_min)
1366 | (ltm.tm_hour ^ tm.tm_hour)
1367 | (ltm.tm_mday ^ tm.tm_mday)
1368 | (ltm.tm_mon ^ tm.tm_mon)
1369 | (ltm.tm_year ^ tm.tm_year)))
1373 if (! __gmtime_r (<, >m))
1376 diff = tm_diff (<m, >m);
1380 hour_diff = diff / 60 / 60;
1381 min_diff = diff / 60 % 60;
1382 sec_diff = diff % 60;
1387 DO_TZ_OFFSET (5, diff < 0, 0, hour_diff * 100 + min_diff);
1389 case 1: tz_hh_mm: /* +hh:mm */
1390 DO_TZ_OFFSET (6, diff < 0, 04, hour_diff * 100 + min_diff);
1392 case 2: tz_hh_mm_ss: /* +hh:mm:ss */
1393 DO_TZ_OFFSET (9, diff < 0, 024,
1394 hour_diff * 10000 + min_diff * 100 + sec_diff);
1396 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1401 DO_TZ_OFFSET (3, diff < 0, 0, hour_diff);
1408 case L_('\0'): /* GNU extension: % at end of format. */
1412 /* Unknown format; output the format, including the '%',
1413 since this is most likely the right thing to do if a
1414 multibyte string has been misparsed. */
1418 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1420 cpy (flen, &f[1 - flen]);
1427 if (p && maxsize != 0)
1434 /* Write information from TP into S according to the format
1435 string FORMAT, writing no more that MAXSIZE characters
1436 (including the terminating '\0') and returning number of
1437 characters written. If S is NULL, nothing will be written
1438 anywhere, so to determine how many characters would be
1439 written, use NULL for S and (size_t) -1 for MAXSIZE. */
1441 my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
1442 const CHAR_T *format,
1443 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
1445 return strftime_case_ (false, s, STRFTIME_ARG (maxsize)
1446 format, tp extra_args LOCALE_ARG);
1449 #if defined _LIBC && ! FPRINTFTIME
1450 libc_hidden_def (my_strftime)
1454 #if defined emacs && ! FPRINTFTIME
1455 /* For Emacs we have a separate interface which corresponds to the normal
1456 strftime function plus the ut argument, but without the ns argument. */
1458 emacs_strftimeu (char *s, size_t maxsize, const char *format,
1459 const struct tm *tp, int ut)
1461 return my_strftime (s, maxsize, format, tp, ut, 0);