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/>. */
21 # define HAVE_STRUCT_ERA_ENTRY 1
22 # define HAVE_TM_GMTOFF 1
23 # define HAVE_TM_ZONE 1
24 # define HAVE_TZNAME 1
26 # include "../locale/localeinfo.h"
30 # include "fprintftime.h"
37 #if HAVE_TZNAME && !HAVE_DECL_TZNAME
38 extern char *tzname[];
41 /* Do multibyte processing if multibytes are supported, unless
42 multibyte sequences are safe in formats. Multibyte sequences are
43 safe if they cannot contain byte sequences that look like format
44 conversion specifications. The multibyte encodings used by the
45 C library on the various platforms (UTF-8, GB2312, GBK, CP936,
46 GB18030, EUC-TW, BIG5, BIG5-HKSCS, CP950, EUC-JP, EUC-KR, CP949,
47 SHIFT_JIS, CP932, JOHAB) are safe for formats, because the byte '%'
48 cannot occur in a multibyte character except in the first byte.
49 But this does not hold for the DEC-HANYU encoding used on OSF/1. */
51 # define MULTIBYTE_IS_FORMAT_SAFE 1
53 #define DO_MULTIBYTE (! MULTIBYTE_IS_FORMAT_SAFE)
57 static const mbstate_t mbstate_zero;
68 # define CHAR_T wchar_t
69 # define UCHAR_T unsigned int
70 # define L_(Str) L##Str
71 # define NLW(Sym) _NL_W##Sym
73 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
74 # define STRLEN(s) __wcslen (s)
78 # define UCHAR_T unsigned char
82 # define MEMCPY(d, s, n) memcpy (d, s, n)
83 # define STRLEN(s) strlen (s)
87 /* Shift A right by B bits portably, by dividing A by 2**B and
88 truncating towards minus infinity. A and B should be free of side
89 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
90 INT_BITS is the number of useful bits in an int. GNU code can
91 assume that INT_BITS is at least 32.
93 ISO C99 says that A >> B is implementation-defined if A < 0. Some
94 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
95 right in the usual way when A < 0, so SHR falls back on division if
96 ordinary A >> B doesn't seem to be the usual signed shift. */
100 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
102 /* Bound on length of the string representing an integer type or expression T.
103 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
104 add 1 for integer division truncation; add 1 more for a minus sign
106 #define INT_STRLEN_BOUND(t) \
107 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
109 #define TM_YEAR_BASE 1900
112 /* Nonzero if YEAR is a leap year (every 4 years,
113 except every 100th isn't, and every 400th is). */
114 # define __isleap(year) \
115 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
120 # define tzname __tzname
121 # define tzset __tzset
125 /* Portable standalone applications should supply a "time.h" that
126 declares a POSIX-compliant localtime_r, for the benefit of older
127 implementations that lack localtime_r or have a nonstandard one.
128 See the gnulib time_r module for one way to implement this. */
130 # undef __localtime_r
131 # define __gmtime_r gmtime_r
132 # define __localtime_r localtime_r
137 # define FPRINTFTIME 0
141 # define STREAM_OR_CHAR_T FILE
142 # define STRFTIME_ARG(x) /* empty */
144 # define STREAM_OR_CHAR_T CHAR_T
145 # define STRFTIME_ARG(x) x,
149 # define memset_byte(P, Len, Byte) \
150 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
151 # define memset_space(P, Len) memset_byte (P, Len, ' ')
152 # define memset_zero(P, Len) memset_byte (P, Len, '0')
153 #elif defined COMPILE_WIDE
154 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
155 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
157 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
158 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
162 # define advance(P, N)
164 # define advance(P, N) ((P) += (N))
171 int _delta = width - _n; \
172 int _incr = _n + (_delta > 0 ? _delta : 0); \
173 if ((size_t) _incr >= maxsize - i) \
177 if (digits == 0 && _delta > 0) \
179 if (pad == L_('0')) \
180 memset_zero (p, _delta); \
182 memset_space (p, _delta); \
191 # define add1(C) add (1, fputc (C, p))
193 # define add1(C) add (1, *p = C)
200 fwrite_lowcase (p, (s), _n); \
201 else if (to_uppcase) \
202 fwrite_uppcase (p, (s), _n); \
204 fwrite ((s), _n, 1, p))
209 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
210 else if (to_uppcase) \
211 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
213 MEMCPY ((void *) p, (void const *) (s), _n))
217 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
218 # undef __mbsrtowcs_l
219 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
221 # define widen(os, ws, l) \
224 const char *__s = os; \
225 memset (&__st, '\0', sizeof (__st)); \
226 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
227 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
228 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
233 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
234 /* We use this code also for the extended locale handling where the
235 function gets as an additional argument the locale which has to be
236 used. To access the values we have to redefine the _NL_CURRENT
238 # define strftime __strftime_l
239 # define wcsftime __wcsftime_l
241 # define _NL_CURRENT(category, item) \
242 (current->values[_NL_ITEM_INDEX (item)].string)
243 # define LOCALE_ARG , loc
244 # define LOCALE_PARAM_PROTO , __locale_t loc
245 # define HELPER_LOCALE_ARG , current
247 # define LOCALE_PARAM_PROTO
250 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
252 # define HELPER_LOCALE_ARG
257 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
258 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
259 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
261 # define TOUPPER(Ch, L) towupper (Ch)
262 # define TOLOWER(Ch, L) towlower (Ch)
265 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
266 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
267 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
269 # define TOUPPER(Ch, L) toupper (Ch)
270 # define TOLOWER(Ch, L) tolower (Ch)
273 /* We don't use `isdigit' here since the locale dependent
274 interpretation is not what we want here. We only need to accept
275 the arabic digits in the ASCII range. One day there is perhaps a
276 more reliable way to accept other sets of digits. */
277 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
281 fwrite_lowcase (FILE *fp, const CHAR_T *src, size_t len)
285 fputc (TOLOWER ((UCHAR_T) *src, loc), fp);
291 fwrite_uppcase (FILE *fp, const CHAR_T *src, size_t len)
295 fputc (TOUPPER ((UCHAR_T) *src, loc), fp);
301 memcpy_lowcase (CHAR_T *dest, const CHAR_T *src,
302 size_t len LOCALE_PARAM_PROTO)
305 dest[len] = TOLOWER ((UCHAR_T) src[len], loc);
310 memcpy_uppcase (CHAR_T *dest, const CHAR_T *src,
311 size_t len LOCALE_PARAM_PROTO)
314 dest[len] = TOUPPER ((UCHAR_T) src[len], loc);
321 /* Yield the difference between *A and *B,
322 measured in seconds, ignoring leap seconds. */
323 # define tm_diff ftime_tm_diff
325 tm_diff (const struct tm *a, const struct tm *b)
327 /* Compute intervening leap days correctly even if year is negative.
328 Take care to avoid int overflow in leap day calculations,
329 but it's OK to assume that A and B are close to each other. */
330 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
331 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
332 int a100 = a4 / 25 - (a4 % 25 < 0);
333 int b100 = b4 / 25 - (b4 % 25 < 0);
334 int a400 = SHR (a100, 2);
335 int b400 = SHR (b100, 2);
336 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
337 int years = a->tm_year - b->tm_year;
338 int days = (365 * years + intervening_leap_days
339 + (a->tm_yday - b->tm_yday));
340 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
341 + (a->tm_min - b->tm_min))
342 + (a->tm_sec - b->tm_sec));
344 #endif /* ! HAVE_TM_GMTOFF */
348 /* The number of days from the first day of the first ISO week of this
349 year to the year day YDAY with week day WDAY. ISO weeks start on
350 Monday; the first ISO week has the year's first Thursday. YDAY may
351 be as small as YDAY_MINIMUM. */
352 #define ISO_WEEK_START_WDAY 1 /* Monday */
353 #define ISO_WEEK1_WDAY 4 /* Thursday */
354 #define YDAY_MINIMUM (-366)
359 iso_week_days (int yday, int wday)
361 /* Add enough to the first operand of % to make it nonnegative. */
362 int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
364 - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
365 + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
369 /* When compiling this file, GNU applications can #define my_strftime
370 to a symbol (typically nstrftime) to get an extended strftime with
371 extra arguments UT and NS. Emacs is a special case for now, but
372 this Emacs-specific code can be removed once Emacs's config.h
373 defines my_strftime. */
374 #if defined emacs && !defined my_strftime
375 # define my_strftime nstrftime
380 # define my_strftime fprintftime
384 # define extra_args , ut, ns
385 # define extra_args_spec , int ut, int ns
387 # if defined COMPILE_WIDE
388 # define my_strftime wcsftime
389 # define nl_get_alt_digit _nl_get_walt_digit
391 # define my_strftime strftime
392 # define nl_get_alt_digit _nl_get_alt_digit
395 # define extra_args_spec
396 /* We don't have this information in general. */
402 /* Just like my_strftime, below, but with one more parameter, UPCASE,
403 to indicate that the result should be converted to upper case. */
405 strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
406 STRFTIME_ARG (size_t maxsize)
407 const CHAR_T *format,
408 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
410 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
411 struct locale_data *const current = loc->__locales[LC_TIME];
414 size_t maxsize = (size_t) -1;
417 int hour12 = tp->tm_hour;
419 /* We cannot make the following values variables since we must delay
420 the evaluation of these values until really needed since some
421 expressions might not be valid in every situation. The `struct tm'
422 might be generated by a strptime() call that initialized
423 only a few elements. Dereference the pointers only if the format
424 requires this. Then it is ok to fail if the pointers are invalid. */
426 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
428 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
430 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
432 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
434 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
435 ? NLW(PM_STR) : NLW(AM_STR)))
437 # define aw_len STRLEN (a_wkday)
438 # define am_len STRLEN (a_month)
439 # define ap_len STRLEN (ampm)
443 STREAM_OR_CHAR_T *p = s;
445 #if DO_MULTIBYTE && !defined COMPILE_WIDE
446 const char *format_end = NULL;
449 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
450 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
451 by localtime. On such systems, we must either use the tzset and
452 localtime wrappers to work around the bug (which sets
453 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
454 struct tm copy = *tp;
460 /* The POSIX test suite assumes that setting
461 the environment variable TZ to a new value before calling strftime()
462 will influence the result (the %Z format) even if the information in
463 TP is computed with a totally different time zone.
464 This is bogus: though POSIX allows bad behavior like this,
465 POSIX does not require it. Do the right thing instead. */
466 zone = (const char *) tp->tm_zone;
471 if (! (zone && *zone))
476 /* POSIX.1 requires that local time zone information be used as
477 though strftime called tzset. */
490 for (f = format; *f != '\0'; ++f)
492 int pad = 0; /* Padding for number ('-', '_', or 0). */
493 int modifier; /* Field modifier ('E', 'O', or 0). */
494 int digits = 0; /* Max digits for numeric format. */
495 int number_value; /* Numeric value to be printed. */
496 unsigned int u_number_value; /* (unsigned int) number_value. */
497 bool negative_number; /* The number is negative. */
498 bool always_output_a_sign; /* +/- should always be output. */
499 int tz_colon_mask; /* Bitmask of where ':' should appear. */
500 const CHAR_T *subfmt;
504 + 2 /* for the two colons in a %::z or %:::z time zone */
505 + (sizeof (int) < sizeof (time_t)
506 ? INT_STRLEN_BOUND (time_t)
507 : INT_STRLEN_BOUND (int))];
509 bool to_lowcase = false;
510 bool to_uppcase = upcase;
512 bool change_case = false;
515 #if DO_MULTIBYTE && !defined COMPILE_WIDE
521 case L_('\b'): case L_('\t'): case L_('\n'):
522 case L_('\v'): case L_('\f'): case L_('\r'):
523 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
524 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
525 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
526 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
527 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
528 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
529 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
530 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
531 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
532 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
533 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
534 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
535 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
536 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
537 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
538 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
539 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
540 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
542 /* The C Standard requires these 98 characters (plus '%') to
543 be in the basic execution character set. None of these
544 characters can start a multibyte sequence, so they need
545 not be analyzed further. */
550 /* Copy this multibyte sequence until we reach its end, find
551 an error, or come back to the initial shift state. */
553 mbstate_t mbstate = mbstate_zero;
558 format_end = f + strlen (f) + 1;
559 fsize = format_end - f;
563 size_t bytes = mbrlen (f + len, fsize - len, &mbstate);
568 if (bytes == (size_t) -2)
570 len += strlen (f + len);
574 if (bytes == (size_t) -1)
582 while (! mbsinit (&mbstate));
590 #else /* ! DO_MULTIBYTE */
592 /* Either multibyte encodings are not supported, they are
593 safe for formats, so any non-'%' byte can be copied through,
594 or this is the wide character version. */
601 #endif /* ! DO_MULTIBYTE */
603 /* Check for flags that can modify a format. */
608 /* This influences the number formats. */
615 /* This changes textual output. */
629 /* As a GNU extension we allow to specify the field width. */
635 if (width > INT_MAX / 10
636 || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10))
637 /* Avoid overflow. */
642 width += *f - L_('0');
646 while (ISDIGIT (*f));
649 /* Check for modifiers. */
662 /* Now do the specified format. */
666 #define DO_NUMBER(d, v) \
668 number_value = v; goto do_number
669 #define DO_SIGNED_NUMBER(d, negative, v) \
671 negative_number = negative; \
672 u_number_value = v; goto do_signed_number
674 /* The mask is not what you might think.
675 When the ordinal i'th bit is set, insert a colon
676 before the i'th digit of the time zone representation. */
677 #define DO_TZ_OFFSET(d, negative, mask, v) \
679 negative_number = negative; \
680 tz_colon_mask = mask; \
681 u_number_value = v; goto do_tz_offset
682 #define DO_NUMBER_SPACEPAD(d, v) \
684 number_value = v; goto do_number_spacepad
701 cpy (aw_len, a_wkday);
704 goto underlying_strftime;
716 cpy (STRLEN (f_wkday), f_wkday);
719 goto underlying_strftime;
732 cpy (am_len, a_month);
735 goto underlying_strftime;
747 cpy (STRLEN (f_month), f_month);
750 goto underlying_strftime;
754 if (modifier == L_('O'))
757 if (! (modifier == 'E'
759 (const CHAR_T *) _NL_CURRENT (LC_TIME,
762 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT));
764 goto underlying_strftime;
769 size_t len = strftime_case_ (to_uppcase,
770 NULL, STRFTIME_ARG ((size_t) -1)
772 tp extra_args LOCALE_ARG);
773 add (len, strftime_case_ (to_uppcase, p,
774 STRFTIME_ARG (maxsize - i)
776 tp extra_args LOCALE_ARG));
780 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
783 /* The relevant information is available only via the
784 underlying strftime implementation, so use that. */
787 char ubuf[1024]; /* enough for any single format in practice */
789 /* Make sure we're calling the actual underlying strftime.
790 In some cases, config.h contains something like
791 "#define strftime rpl_strftime". */
797 /* The space helps distinguish strftime failure from empty
805 len = strftime (ubuf, sizeof ubuf, ufmt, tp);
807 cpy (len - 1, ubuf + 1);
813 if (modifier == L_('O'))
815 if (modifier == L_('E'))
817 #if HAVE_STRUCT_ERA_ENTRY
818 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
822 size_t len = __wcslen (era->era_wname);
823 cpy (len, era->era_wname);
825 size_t len = strlen (era->era_name);
826 cpy (len, era->era_name);
831 goto underlying_strftime;
836 int century = tp->tm_year / 100 + TM_YEAR_BASE / 100;
837 century -= tp->tm_year % 100 < 0 && 0 < century;
838 DO_SIGNED_NUMBER (2, tp->tm_year < - TM_YEAR_BASE, century);
842 if (modifier == L_('O'))
845 if (! (modifier == L_('E')
847 (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT)))
849 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT));
852 goto underlying_strftime;
857 subfmt = L_("%m/%d/%y");
861 if (modifier == L_('E'))
864 DO_NUMBER (2, tp->tm_mday);
867 if (modifier == L_('E'))
870 DO_NUMBER_SPACEPAD (2, tp->tm_mday);
872 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
873 and then jump to one of these labels. */
876 always_output_a_sign = true;
880 /* Force `_' flag unless overridden by `0' or `-' flag. */
881 if (pad != L_('0') && pad != L_('-'))
885 /* Format NUMBER_VALUE according to the MODIFIER flag. */
886 negative_number = number_value < 0;
887 u_number_value = number_value;
890 always_output_a_sign = false;
894 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
895 NEGATIVE_NUMBER is nonzero if the original number was
896 negative; in this case it was converted directly to
897 unsigned int (i.e., modulo (UINT_MAX + 1)) without
899 if (modifier == L_('O') && !negative_number)
902 /* Get the locale specific alternate representation of
903 the number. If none exist NULL is returned. */
904 const CHAR_T *cp = nl_get_alt_digit (u_number_value
909 size_t digitlen = STRLEN (cp);
917 goto underlying_strftime;
921 bufp = buf + sizeof (buf) / sizeof (buf[0]);
924 u_number_value = - u_number_value;
928 if (tz_colon_mask & 1)
931 *--bufp = u_number_value % 10 + L_('0');
932 u_number_value /= 10;
934 while (u_number_value != 0 || tz_colon_mask != 0);
936 do_number_sign_and_padding:
940 sign_char = (negative_number ? L_('-')
941 : always_output_a_sign ? L_('+')
951 int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0]))
952 - bufp) - !!sign_char;
958 if ((size_t) padding >= maxsize - i)
962 memset_space (p, padding);
964 width = width > padding ? width - padding : 0;
970 if ((size_t) digits >= maxsize - i)
977 memset_zero (p, padding);
989 cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp);
995 subfmt = L_("%Y-%m-%d");
999 if (modifier == L_('E'))
1002 DO_NUMBER (2, tp->tm_hour);
1005 if (modifier == L_('E'))
1008 DO_NUMBER (2, hour12);
1010 case L_('k'): /* GNU extension. */
1011 if (modifier == L_('E'))
1014 DO_NUMBER_SPACEPAD (2, tp->tm_hour);
1016 case L_('l'): /* GNU extension. */
1017 if (modifier == L_('E'))
1020 DO_NUMBER_SPACEPAD (2, hour12);
1023 if (modifier == L_('E'))
1026 DO_SIGNED_NUMBER (3, tp->tm_yday < -1, tp->tm_yday + 1U);
1029 if (modifier == L_('E'))
1032 DO_NUMBER (2, tp->tm_min);
1035 if (modifier == L_('E'))
1038 DO_SIGNED_NUMBER (2, tp->tm_mon < -1, tp->tm_mon + 1U);
1041 case L_('N'): /* GNU extension. */
1042 if (modifier == L_('E'))
1050 /* Take an explicit width less than 9 as a precision. */
1052 for (j = width; j < 9; j++)
1056 DO_NUMBER (width, number_value);
1066 format_char = L_('p');
1080 goto underlying_strftime;
1084 subfmt = L_("%H:%M");
1089 if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME,
1092 subfmt = L_("%I:%M:%S %p");
1095 goto underlying_strftime;
1099 if (modifier == L_('E'))
1102 DO_NUMBER (2, tp->tm_sec);
1104 case L_('s'): /* GNU extension. */
1112 /* Generate string value for T using time_t arithmetic;
1113 this works even if sizeof (long) < sizeof (time_t). */
1115 bufp = buf + sizeof (buf) / sizeof (buf[0]);
1116 negative_number = t < 0;
1122 *--bufp = (negative_number ? -d : d) + L_('0');
1127 always_output_a_sign = false;
1128 goto do_number_sign_and_padding;
1132 if (modifier == L_('O'))
1135 if (! (modifier == L_('E')
1137 (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT)))
1139 subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT));
1142 goto underlying_strftime;
1145 subfmt = L_("%H:%M:%S");
1153 DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1);
1156 if (modifier == L_('E'))
1159 DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7);
1164 if (modifier == L_('E'))
1167 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1168 is a leap year, except that YEAR and YEAR - 1 both work
1169 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1171 int year = (tp->tm_year
1173 ? TM_YEAR_BASE % 400
1174 : TM_YEAR_BASE % 400 - 400));
1175 int year_adjust = 0;
1176 int days = iso_week_days (tp->tm_yday, tp->tm_wday);
1180 /* This ISO week belongs to the previous year. */
1182 days = iso_week_days (tp->tm_yday + (365 + __isleap (year - 1)),
1187 int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)),
1191 /* This ISO week belongs to the next year. */
1201 int yy = (tp->tm_year % 100 + year_adjust) % 100;
1202 DO_NUMBER (2, (0 <= yy
1204 : tp->tm_year < -TM_YEAR_BASE - year_adjust
1210 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE - year_adjust,
1211 (tp->tm_year + (unsigned int) TM_YEAR_BASE
1215 DO_NUMBER (2, days / 7 + 1);
1220 if (modifier == L_('E'))
1223 DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7);
1226 if (modifier == L_('E'))
1229 DO_NUMBER (1, tp->tm_wday);
1232 if (modifier == 'E')
1234 #if HAVE_STRUCT_ERA_ENTRY
1235 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1238 # ifdef COMPILE_WIDE
1239 subfmt = era->era_wformat;
1241 subfmt = era->era_format;
1246 goto underlying_strftime;
1249 if (modifier == L_('O'))
1252 DO_SIGNED_NUMBER (4, tp->tm_year < -TM_YEAR_BASE,
1253 tp->tm_year + (unsigned int) TM_YEAR_BASE);
1256 if (modifier == L_('E'))
1258 #if HAVE_STRUCT_ERA_ENTRY
1259 struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG);
1262 int delta = tp->tm_year - era->start_date[0];
1263 DO_NUMBER (1, (era->offset
1264 + delta * era->absolute_direction));
1267 goto underlying_strftime;
1272 int yy = tp->tm_year % 100;
1274 yy = tp->tm_year < - TM_YEAR_BASE ? -yy : yy + 100;
1286 /* The tzset() call might have changed the value. */
1287 if (!(zone && *zone) && tp->tm_isdst >= 0)
1288 zone = tzname[tp->tm_isdst != 0];
1295 /* The zone string is always given in multibyte form. We have
1296 to transform it first. */
1299 widen (zone, wczone, len);
1303 cpy (strlen (zone), zone);
1308 /* :, ::, and ::: are valid only just before 'z'.
1309 :::: etc. are rejected later. */
1310 for (colons = 1; f[colons] == L_(':'); colons++)
1312 if (f[colons] != L_('z'))
1315 goto do_z_conversion;
1321 if (tp->tm_isdst < 0)
1330 diff = tp->tm_gmtoff;
1343 if (lt == (time_t) -1)
1345 /* mktime returns -1 for errors, but -1 is also a
1346 valid time_t value. Check whether an error really
1350 if (! __localtime_r (<, &tm)
1351 || ((ltm.tm_sec ^ tm.tm_sec)
1352 | (ltm.tm_min ^ tm.tm_min)
1353 | (ltm.tm_hour ^ tm.tm_hour)
1354 | (ltm.tm_mday ^ tm.tm_mday)
1355 | (ltm.tm_mon ^ tm.tm_mon)
1356 | (ltm.tm_year ^ tm.tm_year)))
1360 if (! __gmtime_r (<, >m))
1363 diff = tm_diff (<m, >m);
1367 hour_diff = diff / 60 / 60;
1368 min_diff = diff / 60 % 60;
1369 sec_diff = diff % 60;
1374 DO_TZ_OFFSET (5, diff < 0, 0, hour_diff * 100 + min_diff);
1376 case 1: tz_hh_mm: /* +hh:mm */
1377 DO_TZ_OFFSET (6, diff < 0, 04, hour_diff * 100 + min_diff);
1379 case 2: tz_hh_mm_ss: /* +hh:mm:ss */
1380 DO_TZ_OFFSET (9, diff < 0, 024,
1381 hour_diff * 10000 + min_diff * 100 + sec_diff);
1383 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1388 DO_TZ_OFFSET (3, diff < 0, 0, hour_diff);
1395 case L_('\0'): /* GNU extension: % at end of format. */
1399 /* Unknown format; output the format, including the '%',
1400 since this is most likely the right thing to do if a
1401 multibyte string has been misparsed. */
1405 for (flen = 1; f[1 - flen] != L_('%'); flen++)
1407 cpy (flen, &f[1 - flen]);
1414 if (p && maxsize != 0)
1421 /* Write information from TP into S according to the format
1422 string FORMAT, writing no more that MAXSIZE characters
1423 (including the terminating '\0') and returning number of
1424 characters written. If S is NULL, nothing will be written
1425 anywhere, so to determine how many characters would be
1426 written, use NULL for S and (size_t) -1 for MAXSIZE. */
1428 my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
1429 const CHAR_T *format,
1430 const struct tm *tp extra_args_spec LOCALE_PARAM_PROTO)
1432 return strftime_case_ (false, s, STRFTIME_ARG (maxsize)
1433 format, tp extra_args LOCALE_ARG);
1436 #if defined _LIBC && ! FPRINTFTIME
1437 libc_hidden_def (my_strftime)
1441 #if defined emacs && ! FPRINTFTIME
1442 /* For Emacs we have a separate interface which corresponds to the normal
1443 strftime function plus the ut argument, but without the ns argument. */
1445 emacs_strftimeu (char *s, size_t maxsize, const char *format,
1446 const struct tm *tp, int ut)
1448 return my_strftime (s, maxsize, format, tp, ut, 0);