1 /* Copyright (C) 1991-2001, 2003-2007, 2009-2015 Free Software Foundation, Inc.
3 NOTE: The canonical source of this file is maintained with the GNU C Library.
4 Bugs can be reported to bug-glibc@prep.ai.mit.edu.
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 # define HAVE_STRUCT_ERA_ENTRY 1
21 # define HAVE_TM_GMTOFF 1
22 # define HAVE_TM_ZONE 1
23 # define HAVE_TZNAME 1
25 # include "../locale/localeinfo.h"
29 # include "fprintftime.h"
31 # include "strftime.h"
33 # include "time-internal.h"
39 #if HAVE_TZNAME && !HAVE_DECL_TZNAME
40 extern char *tzname
[];
43 /* Do multibyte processing if multibyte encodings are supported, unless
44 multibyte sequences are safe in formats. Multibyte sequences are
45 safe if they cannot contain byte sequences that look like format
46 conversion specifications. The multibyte encodings used by the
47 C library on the various platforms (UTF-8, GB2312, GBK, CP936,
48 GB18030, EUC-TW, BIG5, BIG5-HKSCS, CP950, EUC-JP, EUC-KR, CP949,
49 SHIFT_JIS, CP932, JOHAB) are safe for formats, because the byte '%'
50 cannot occur in a multibyte character except in the first byte.
52 The DEC-HANYU encoding used on OSF/1 is not safe for formats, but
53 this encoding has never been seen in real-life use, so we ignore
55 #if !(defined __osf__ && 0)
56 # define MULTIBYTE_IS_FORMAT_SAFE 1
58 #define DO_MULTIBYTE (! MULTIBYTE_IS_FORMAT_SAFE)
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)
92 /* Shift A right by B bits portably, by dividing A by 2**B and
93 truncating towards minus infinity. A and B should be free of side
94 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
95 INT_BITS is the number of useful bits in an int. GNU code can
96 assume that INT_BITS is at least 32.
98 ISO C99 says that A >> B is implementation-defined if A < 0. Some
99 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
100 right in the usual way when A < 0, so SHR falls back on division if
101 ordinary A >> B doesn't seem to be the usual signed shift. */
105 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
107 /* Bound on length of the string representing an integer type or expression T.
108 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
109 add 1 for integer division truncation; add 1 more for a minus sign
111 #define INT_STRLEN_BOUND(t) \
112 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
114 #define TM_YEAR_BASE 1900
117 /* Nonzero if YEAR is a leap year (every 4 years,
118 except every 100th isn't, and every 400th is). */
119 # define __isleap(year) \
120 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
125 # define mktime_z(tz, tm) mktime (tm)
126 # define tzname __tzname
127 # define tzset __tzset
131 # define FPRINTFTIME 0
135 # define STREAM_OR_CHAR_T FILE
136 # define STRFTIME_ARG(x) /* empty */
138 # define STREAM_OR_CHAR_T CHAR_T
139 # define STRFTIME_ARG(x) x,
143 # define memset_byte(P, Len, Byte) \
144 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
145 # define memset_space(P, Len) memset_byte (P, Len, ' ')
146 # define memset_zero(P, Len) memset_byte (P, Len, '0')
147 #elif defined COMPILE_WIDE
148 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
149 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
151 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
152 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
156 # define advance(P, N)
158 # define advance(P, N) ((P) += (N))
165 size_t _w = (width < 0 ? 0 : width); \
166 size_t _incr = _n < _w ? _w : _n; \
167 if (_incr >= maxsize - i) \
171 if (digits == 0 && _n < _w) \
173 size_t _delta = width - _n; \
174 if (pad == L_('0')) \
175 memset_zero (p, _delta); \
177 memset_space (p, _delta); \
186 # define add1(C) add (1, fputc (C, p))
188 # define add1(C) add (1, *p = C)
197 fwrite_lowcase (p, (s), _n); \
198 else if (to_uppcase) \
199 fwrite_uppcase (p, (s), _n); \
202 /* Ignore the value of fwrite. The caller can determine whether \
203 an error occurred by inspecting ferror (P). All known fwrite \
204 implementations set the stream's error indicator when they \
205 fail due to ENOMEM etc., even though C11 and POSIX.1-2008 do \
206 not require this. */ \
207 fwrite (s, _n, 1, p); \
216 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
217 else if (to_uppcase) \
218 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
220 MEMCPY ((void *) p, (void const *) (s), _n))
224 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
225 # undef __mbsrtowcs_l
226 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
228 # define widen(os, ws, l) \
231 const char *__s = os; \
232 memset (&__st, '\0', sizeof (__st)); \
233 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
234 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
235 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
240 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
241 /* We use this code also for the extended locale handling where the
242 function gets as an additional argument the locale which has to be
243 used. To access the values we have to redefine the _NL_CURRENT
245 # define strftime __strftime_l
246 # define wcsftime __wcsftime_l
248 # define _NL_CURRENT(category, item) \
249 (current->values[_NL_ITEM_INDEX (item)].string)
250 # define LOCALE_ARG , loc
251 # define LOCALE_PARAM_PROTO , __locale_t loc
252 # define HELPER_LOCALE_ARG , current
254 # define LOCALE_PARAM_PROTO
257 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
259 # define HELPER_LOCALE_ARG
264 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
265 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
266 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
268 # define TOUPPER(Ch, L) towupper (Ch)
269 # define TOLOWER(Ch, L) towlower (Ch)
272 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
273 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
274 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
276 # define TOUPPER(Ch, L) toupper (Ch)
277 # define TOLOWER(Ch, L) tolower (Ch)
280 /* We don't use 'isdigit' here since the locale dependent
281 interpretation is not what we want here. We only need to accept
282 the arabic digits in the ASCII range. One day there is perhaps a
283 more reliable way to accept other sets of digits. */
284 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
288 fwrite_lowcase (FILE *fp
, const CHAR_T
*src
, size_t len
)
292 fputc (TOLOWER ((UCHAR_T
) *src
, loc
), fp
);
298 fwrite_uppcase (FILE *fp
, const CHAR_T
*src
, size_t len
)
302 fputc (TOUPPER ((UCHAR_T
) *src
, loc
), fp
);
308 memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
,
309 size_t len LOCALE_PARAM_PROTO
)
312 dest
[len
] = TOLOWER ((UCHAR_T
) src
[len
], loc
);
317 memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
,
318 size_t len LOCALE_PARAM_PROTO
)
321 dest
[len
] = TOUPPER ((UCHAR_T
) src
[len
], loc
);
328 /* Yield the difference between *A and *B,
329 measured in seconds, ignoring leap seconds. */
330 # define tm_diff ftime_tm_diff
332 tm_diff (const struct tm
*a
, const struct tm
*b
)
334 /* Compute intervening leap days correctly even if year is negative.
335 Take care to avoid int overflow in leap day calculations,
336 but it's OK to assume that A and B are close to each other. */
337 int a4
= SHR (a
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (a
->tm_year
& 3);
338 int b4
= SHR (b
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (b
->tm_year
& 3);
339 int a100
= a4
/ 25 - (a4
% 25 < 0);
340 int b100
= b4
/ 25 - (b4
% 25 < 0);
341 int a400
= SHR (a100
, 2);
342 int b400
= SHR (b100
, 2);
343 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
344 int years
= a
->tm_year
- b
->tm_year
;
345 int days
= (365 * years
+ intervening_leap_days
346 + (a
->tm_yday
- b
->tm_yday
));
347 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
348 + (a
->tm_min
- b
->tm_min
))
349 + (a
->tm_sec
- b
->tm_sec
));
351 #endif /* ! HAVE_TM_GMTOFF */
355 /* The number of days from the first day of the first ISO week of this
356 year to the year day YDAY with week day WDAY. ISO weeks start on
357 Monday; the first ISO week has the year's first Thursday. YDAY may
358 be as small as YDAY_MINIMUM. */
359 #define ISO_WEEK_START_WDAY 1 /* Monday */
360 #define ISO_WEEK1_WDAY 4 /* Thursday */
361 #define YDAY_MINIMUM (-366)
366 iso_week_days (int yday
, int wday
)
368 /* Add enough to the first operand of % to make it nonnegative. */
369 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
371 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
372 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
376 /* When compiling this file, GNU applications can #define my_strftime
377 to a symbol (typically nstrftime) to get an extended strftime with
378 extra arguments TZ and NS. */
382 # define my_strftime fprintftime
387 # define extra_args , tz, ns
388 # define extra_args_spec , timezone_t tz, int ns
390 # if defined COMPILE_WIDE
391 # define my_strftime wcsftime
392 # define nl_get_alt_digit _nl_get_walt_digit
394 # define my_strftime strftime
395 # define nl_get_alt_digit _nl_get_alt_digit
398 # define extra_args_spec
399 /* We don't have this information in general. */
405 /* Just like my_strftime, below, but with one more parameter, UPCASE,
406 to indicate that the result should be converted to upper case. */
408 strftime_case_ (bool upcase
, STREAM_OR_CHAR_T
*s
,
409 STRFTIME_ARG (size_t maxsize
)
410 const CHAR_T
*format
,
411 const struct tm
*tp extra_args_spec LOCALE_PARAM_PROTO
)
413 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
414 struct locale_data
*const current
= loc
->__locales
[LC_TIME
];
417 size_t maxsize
= (size_t) -1;
420 int hour12
= tp
->tm_hour
;
422 /* We cannot make the following values variables since we must delay
423 the evaluation of these values until really needed since some
424 expressions might not be valid in every situation. The 'struct tm'
425 might be generated by a strptime() call that initialized
426 only a few elements. Dereference the pointers only if the format
427 requires this. Then it is ok to fail if the pointers are invalid. */
429 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
431 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
433 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
435 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
437 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
438 ? NLW(PM_STR) : NLW(AM_STR)))
440 # define aw_len STRLEN (a_wkday)
441 # define am_len STRLEN (a_month)
442 # define ap_len STRLEN (ampm)
445 char **tzname_vec
= tzname
;
449 STREAM_OR_CHAR_T
*p
= s
;
451 #if DO_MULTIBYTE && !defined COMPILE_WIDE
452 const char *format_end
= NULL
;
455 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
456 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
457 by localtime. On such systems, we must either use the tzset and
458 localtime wrappers to work around the bug (which sets
459 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
460 struct tm copy
= *tp
;
466 /* The POSIX test suite assumes that setting
467 the environment variable TZ to a new value before calling strftime()
468 will influence the result (the %Z format) even if the information in
469 TP is computed with a totally different time zone.
470 This is bogus: though POSIX allows bad behavior like this,
471 POSIX does not require it. Do the right thing instead. */
472 zone
= (const char *) tp
->tm_zone
;
477 if (! (zone
&& *zone
))
483 /* Infer the zone name from *TZ instead of from TZNAME. */
484 tzname_vec
= tz
->tzname_copy
;
486 /* POSIX.1 requires that local time zone information be used as
487 though strftime called tzset. */
492 /* The tzset() call might have changed the value. */
493 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
494 zone
= tzname_vec
[tp
->tm_isdst
!= 0];
505 for (f
= format
; *f
!= '\0'; ++f
)
507 int pad
= 0; /* Padding for number ('-', '_', or 0). */
508 int modifier
; /* Field modifier ('E', 'O', or 0). */
509 int digits
= 0; /* Max digits for numeric format. */
510 int number_value
; /* Numeric value to be printed. */
511 unsigned int u_number_value
; /* (unsigned int) number_value. */
512 bool negative_number
; /* The number is negative. */
513 bool always_output_a_sign
; /* +/- should always be output. */
514 int tz_colon_mask
; /* Bitmask of where ':' should appear. */
515 const CHAR_T
*subfmt
;
519 + 2 /* for the two colons in a %::z or %:::z time zone */
520 + (sizeof (int) < sizeof (time_t)
521 ? INT_STRLEN_BOUND (time_t)
522 : INT_STRLEN_BOUND (int))];
524 bool to_lowcase
= false;
525 bool to_uppcase
= upcase
;
527 bool change_case
= false;
530 #if DO_MULTIBYTE && !defined COMPILE_WIDE
536 case L_('\b'): case L_('\t'): case L_('\n'):
537 case L_('\v'): case L_('\f'): case L_('\r'):
538 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
539 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
540 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
541 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
542 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
543 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
544 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
545 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
546 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
547 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
548 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
549 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
550 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
551 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
552 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
553 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
554 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
555 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
557 /* The C Standard requires these 98 characters (plus '%') to
558 be in the basic execution character set. None of these
559 characters can start a multibyte sequence, so they need
560 not be analyzed further. */
565 /* Copy this multibyte sequence until we reach its end, find
566 an error, or come back to the initial shift state. */
568 mbstate_t mbstate
= mbstate_zero
;
573 format_end
= f
+ strlen (f
) + 1;
574 fsize
= format_end
- f
;
578 size_t bytes
= mbrlen (f
+ len
, fsize
- len
, &mbstate
);
583 if (bytes
== (size_t) -2)
585 len
+= strlen (f
+ len
);
589 if (bytes
== (size_t) -1)
597 while (! mbsinit (&mbstate
));
605 #else /* ! DO_MULTIBYTE */
607 /* Either multibyte encodings are not supported, they are
608 safe for formats, so any non-'%' byte can be copied through,
609 or this is the wide character version. */
616 #endif /* ! DO_MULTIBYTE */
618 /* Check for flags that can modify a format. */
623 /* This influences the number formats. */
630 /* This changes textual output. */
644 /* As a GNU extension we allow to specify the field width. */
650 if (width
> INT_MAX
/ 10
651 || (width
== INT_MAX
/ 10 && *f
- L_('0') > INT_MAX
% 10))
652 /* Avoid overflow. */
657 width
+= *f
- L_('0');
661 while (ISDIGIT (*f
));
664 /* Check for modifiers. */
677 /* Now do the specified format. */
681 #define DO_NUMBER(d, v) \
689 #define DO_SIGNED_NUMBER(d, negative, v) \
693 negative_number = negative; \
694 u_number_value = v; \
695 goto do_signed_number; \
699 /* The mask is not what you might think.
700 When the ordinal i'th bit is set, insert a colon
701 before the i'th digit of the time zone representation. */
702 #define DO_TZ_OFFSET(d, negative, mask, v) \
706 negative_number = negative; \
707 tz_colon_mask = mask; \
708 u_number_value = v; \
712 #define DO_NUMBER_SPACEPAD(d, v) \
717 goto do_number_spacepad; \
736 cpy (aw_len
, a_wkday
);
739 goto underlying_strftime
;
751 cpy (STRLEN (f_wkday
), f_wkday
);
754 goto underlying_strftime
;
767 cpy (am_len
, a_month
);
770 goto underlying_strftime
;
782 cpy (STRLEN (f_month
), f_month
);
785 goto underlying_strftime
;
789 if (modifier
== L_('O'))
792 if (! (modifier
== 'E'
794 (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
797 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_T_FMT
));
799 goto underlying_strftime
;
804 size_t len
= strftime_case_ (to_uppcase
,
805 NULL
, STRFTIME_ARG ((size_t) -1)
807 tp extra_args LOCALE_ARG
);
808 add (len
, strftime_case_ (to_uppcase
, p
,
809 STRFTIME_ARG (maxsize
- i
)
811 tp extra_args LOCALE_ARG
));
815 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
818 /* The relevant information is available only via the
819 underlying strftime implementation, so use that. */
822 char ubuf
[1024]; /* enough for any single format in practice */
824 /* Make sure we're calling the actual underlying strftime.
825 In some cases, config.h contains something like
826 "#define strftime rpl_strftime". */
832 /* The space helps distinguish strftime failure from empty
840 len
= strftime (ubuf
, sizeof ubuf
, ufmt
, tp
);
842 cpy (len
- 1, ubuf
+ 1);
848 if (modifier
== L_('O'))
850 if (modifier
== L_('E'))
852 #if HAVE_STRUCT_ERA_ENTRY
853 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
857 size_t len
= __wcslen (era
->era_wname
);
858 cpy (len
, era
->era_wname
);
860 size_t len
= strlen (era
->era_name
);
861 cpy (len
, era
->era_name
);
866 goto underlying_strftime
;
871 int century
= tp
->tm_year
/ 100 + TM_YEAR_BASE
/ 100;
872 century
-= tp
->tm_year
% 100 < 0 && 0 < century
;
873 DO_SIGNED_NUMBER (2, tp
->tm_year
< - TM_YEAR_BASE
, century
);
877 if (modifier
== L_('O'))
880 if (! (modifier
== L_('E')
882 (const CHAR_T
*)_NL_CURRENT (LC_TIME
, NLW(ERA_D_FMT
)))
884 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_FMT
));
887 goto underlying_strftime
;
892 subfmt
= L_("%m/%d/%y");
896 if (modifier
== L_('E'))
899 DO_NUMBER (2, tp
->tm_mday
);
902 if (modifier
== L_('E'))
905 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
907 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
908 and then jump to one of these labels. */
911 always_output_a_sign
= true;
915 /* Force '_' flag unless overridden by '0' or '-' flag. */
916 if (pad
!= L_('0') && pad
!= L_('-'))
920 /* Format NUMBER_VALUE according to the MODIFIER flag. */
921 negative_number
= number_value
< 0;
922 u_number_value
= number_value
;
925 always_output_a_sign
= false;
929 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
930 NEGATIVE_NUMBER is nonzero if the original number was
931 negative; in this case it was converted directly to
932 unsigned int (i.e., modulo (UINT_MAX + 1)) without
934 if (modifier
== L_('O') && !negative_number
)
937 /* Get the locale specific alternate representation of
938 the number. If none exist NULL is returned. */
939 const CHAR_T
*cp
= nl_get_alt_digit (u_number_value
944 size_t digitlen
= STRLEN (cp
);
952 goto underlying_strftime
;
956 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
959 u_number_value
= - u_number_value
;
963 if (tz_colon_mask
& 1)
966 *--bufp
= u_number_value
% 10 + L_('0');
967 u_number_value
/= 10;
969 while (u_number_value
!= 0 || tz_colon_mask
!= 0);
971 do_number_sign_and_padding
:
975 sign_char
= (negative_number
? L_('-')
976 : always_output_a_sign
? L_('+')
986 int padding
= digits
- (buf
+ (sizeof (buf
) / sizeof (buf
[0]))
987 - bufp
) - !!sign_char
;
993 if ((size_t) padding
>= maxsize
- i
)
997 memset_space (p
, padding
);
999 width
= width
> padding
? width
- padding
: 0;
1005 if ((size_t) digits
>= maxsize
- i
)
1012 memset_zero (p
, padding
);
1024 cpy (buf
+ sizeof (buf
) / sizeof (buf
[0]) - bufp
, bufp
);
1030 subfmt
= L_("%Y-%m-%d");
1034 if (modifier
== L_('E'))
1037 DO_NUMBER (2, tp
->tm_hour
);
1040 if (modifier
== L_('E'))
1043 DO_NUMBER (2, hour12
);
1045 case L_('k'): /* GNU extension. */
1046 if (modifier
== L_('E'))
1049 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
1051 case L_('l'): /* GNU extension. */
1052 if (modifier
== L_('E'))
1055 DO_NUMBER_SPACEPAD (2, hour12
);
1058 if (modifier
== L_('E'))
1061 DO_SIGNED_NUMBER (3, tp
->tm_yday
< -1, tp
->tm_yday
+ 1U);
1064 if (modifier
== L_('E'))
1067 DO_NUMBER (2, tp
->tm_min
);
1070 if (modifier
== L_('E'))
1073 DO_SIGNED_NUMBER (2, tp
->tm_mon
< -1, tp
->tm_mon
+ 1U);
1076 case L_('N'): /* GNU extension. */
1077 if (modifier
== L_('E'))
1085 /* Take an explicit width less than 9 as a precision. */
1087 for (j
= width
; j
< 9; j
++)
1091 DO_NUMBER (width
, number_value
);
1101 format_char
= L_('p');
1115 goto underlying_strftime
;
1119 subfmt
= L_("%H:%M");
1124 if (*(subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
1127 subfmt
= L_("%I:%M:%S %p");
1130 goto underlying_strftime
;
1134 if (modifier
== L_('E'))
1137 DO_NUMBER (2, tp
->tm_sec
);
1139 case L_('s'): /* GNU extension. */
1145 t
= mktime_z (tz
, <m
);
1147 /* Generate string value for T using time_t arithmetic;
1148 this works even if sizeof (long) < sizeof (time_t). */
1150 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1151 negative_number
= t
< 0;
1157 *--bufp
= (negative_number
? -d
: d
) + L_('0');
1162 always_output_a_sign
= false;
1163 goto do_number_sign_and_padding
;
1167 if (modifier
== L_('O'))
1170 if (! (modifier
== L_('E')
1172 (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(ERA_T_FMT
)))
1174 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(T_FMT
));
1177 goto underlying_strftime
;
1180 subfmt
= L_("%H:%M:%S");
1188 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
1191 if (modifier
== L_('E'))
1194 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
1199 if (modifier
== L_('E'))
1202 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1203 is a leap year, except that YEAR and YEAR - 1 both work
1204 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1206 int year
= (tp
->tm_year
1208 ? TM_YEAR_BASE
% 400
1209 : TM_YEAR_BASE
% 400 - 400));
1210 int year_adjust
= 0;
1211 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
1215 /* This ISO week belongs to the previous year. */
1217 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
- 1)),
1222 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
1226 /* This ISO week belongs to the next year. */
1236 int yy
= (tp
->tm_year
% 100 + year_adjust
) % 100;
1237 DO_NUMBER (2, (0 <= yy
1239 : tp
->tm_year
< -TM_YEAR_BASE
- year_adjust
1245 DO_SIGNED_NUMBER (4, tp
->tm_year
< -TM_YEAR_BASE
- year_adjust
,
1246 (tp
->tm_year
+ (unsigned int) TM_YEAR_BASE
1250 DO_NUMBER (2, days
/ 7 + 1);
1255 if (modifier
== L_('E'))
1258 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
1261 if (modifier
== L_('E'))
1264 DO_NUMBER (1, tp
->tm_wday
);
1267 if (modifier
== 'E')
1269 #if HAVE_STRUCT_ERA_ENTRY
1270 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1273 # ifdef COMPILE_WIDE
1274 subfmt
= era
->era_wformat
;
1276 subfmt
= era
->era_format
;
1281 goto underlying_strftime
;
1284 if (modifier
== L_('O'))
1287 DO_SIGNED_NUMBER (4, tp
->tm_year
< -TM_YEAR_BASE
,
1288 tp
->tm_year
+ (unsigned int) TM_YEAR_BASE
);
1291 if (modifier
== L_('E'))
1293 #if HAVE_STRUCT_ERA_ENTRY
1294 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1297 int delta
= tp
->tm_year
- era
->start_date
[0];
1298 DO_NUMBER (1, (era
->offset
1299 + delta
* era
->absolute_direction
));
1302 goto underlying_strftime
;
1307 int yy
= tp
->tm_year
% 100;
1309 yy
= tp
->tm_year
< - TM_YEAR_BASE
? -yy
: yy
+ 100;
1322 /* The zone string is always given in multibyte form. We have
1323 to transform it first. */
1326 widen (zone
, wczone
, len
);
1330 cpy (strlen (zone
), zone
);
1335 /* :, ::, and ::: are valid only just before 'z'.
1336 :::: etc. are rejected later. */
1337 for (colons
= 1; f
[colons
] == L_(':'); colons
++)
1339 if (f
[colons
] != L_('z'))
1342 goto do_z_conversion
;
1348 if (tp
->tm_isdst
< 0)
1357 diff
= tp
->tm_gmtoff
;
1368 lt
= mktime_z (tz
, <m
);
1370 if (lt
== (time_t) -1)
1372 /* mktime returns -1 for errors, but -1 is also a
1373 valid time_t value. Check whether an error really
1377 if (! localtime_rz (tz
, <
, &tm
)
1378 || ((ltm
.tm_sec
^ tm
.tm_sec
)
1379 | (ltm
.tm_min
^ tm
.tm_min
)
1380 | (ltm
.tm_hour
^ tm
.tm_hour
)
1381 | (ltm
.tm_mday
^ tm
.tm_mday
)
1382 | (ltm
.tm_mon
^ tm
.tm_mon
)
1383 | (ltm
.tm_year
^ tm
.tm_year
)))
1387 if (! localtime_rz (0, <
, >m
))
1390 diff
= tm_diff (<m
, >m
);
1394 hour_diff
= diff
/ 60 / 60;
1395 min_diff
= diff
/ 60 % 60;
1396 sec_diff
= diff
% 60;
1401 DO_TZ_OFFSET (5, diff
< 0, 0, hour_diff
* 100 + min_diff
);
1403 case 1: tz_hh_mm
: /* +hh:mm */
1404 DO_TZ_OFFSET (6, diff
< 0, 04, hour_diff
* 100 + min_diff
);
1406 case 2: tz_hh_mm_ss
: /* +hh:mm:ss */
1407 DO_TZ_OFFSET (9, diff
< 0, 024,
1408 hour_diff
* 10000 + min_diff
* 100 + sec_diff
);
1410 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1415 DO_TZ_OFFSET (3, diff
< 0, 0, hour_diff
);
1422 case L_('\0'): /* GNU extension: % at end of format. */
1426 /* Unknown format; output the format, including the '%',
1427 since this is most likely the right thing to do if a
1428 multibyte string has been misparsed. */
1432 for (flen
= 1; f
[1 - flen
] != L_('%'); flen
++)
1434 cpy (flen
, &f
[1 - flen
]);
1441 if (p
&& maxsize
!= 0)
1448 /* Write information from TP into S according to the format
1449 string FORMAT, writing no more that MAXSIZE characters
1450 (including the terminating '\0') and returning number of
1451 characters written. If S is NULL, nothing will be written
1452 anywhere, so to determine how many characters would be
1453 written, use NULL for S and (size_t) -1 for MAXSIZE. */
1455 my_strftime (STREAM_OR_CHAR_T
*s
, STRFTIME_ARG (size_t maxsize
)
1456 const CHAR_T
*format
,
1457 const struct tm
*tp extra_args_spec LOCALE_PARAM_PROTO
)
1459 return strftime_case_ (false, s
, STRFTIME_ARG (maxsize
)
1460 format
, tp extra_args LOCALE_ARG
);
1463 #if defined _LIBC && ! FPRINTFTIME
1464 libc_hidden_def (my_strftime
)