1 /* Copyright (C) 1991-2018 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
19 # define USE_IN_EXTENDED_LOCALE_MODEL 1
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 FALLTHROUGH ((void) 0)
75 # define FALLTHROUGH __attribute__ ((__fallthrough__))
81 # define CHAR_T wchar_t
82 # define UCHAR_T unsigned int
83 # define L_(Str) L##Str
84 # define NLW(Sym) _NL_W##Sym
86 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
87 # define STRLEN(s) __wcslen (s)
91 # define UCHAR_T unsigned char
95 # define MEMCPY(d, s, n) memcpy (d, s, n)
96 # define STRLEN(s) strlen (s)
100 /* Shift A right by B bits portably, by dividing A by 2**B and
101 truncating towards minus infinity. A and B should be free of side
102 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
103 INT_BITS is the number of useful bits in an int. GNU code can
104 assume that INT_BITS is at least 32.
106 ISO C99 says that A >> B is implementation-defined if A < 0. Some
107 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
108 right in the usual way when A < 0, so SHR falls back on division if
109 ordinary A >> B doesn't seem to be the usual signed shift. */
113 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
115 /* Bound on length of the string representing an integer type or expression T.
116 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
117 add 1 for integer division truncation; add 1 more for a minus sign
119 #define INT_STRLEN_BOUND(t) \
120 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
122 #define TM_YEAR_BASE 1900
125 /* Nonzero if YEAR is a leap year (every 4 years,
126 except every 100th isn't, and every 400th is). */
127 # define __isleap(year) \
128 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
133 # define mktime_z(tz, tm) mktime (tm)
134 # define tzname __tzname
135 # define tzset __tzset
139 # define FPRINTFTIME 0
143 # define STREAM_OR_CHAR_T FILE
144 # define STRFTIME_ARG(x) /* empty */
146 # define STREAM_OR_CHAR_T CHAR_T
147 # define STRFTIME_ARG(x) x,
151 # define memset_byte(P, Len, Byte) \
152 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
153 # define memset_space(P, Len) memset_byte (P, Len, ' ')
154 # define memset_zero(P, Len) memset_byte (P, Len, '0')
155 #elif defined COMPILE_WIDE
156 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
157 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
159 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
160 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
164 # define advance(P, N)
166 # define advance(P, N) ((P) += (N))
173 size_t _w = (width < 0 ? 0 : width); \
174 size_t _incr = _n < _w ? _w : _n; \
175 if (_incr >= maxsize - i) \
179 if (digits == 0 && _n < _w) \
181 size_t _delta = width - _n; \
182 if (pad == L_('0')) \
183 memset_zero (p, _delta); \
185 memset_space (p, _delta); \
194 # define add1(C) add (1, fputc (C, p))
196 # define add1(C) add (1, *p = C)
205 fwrite_lowcase (p, (s), _n); \
206 else if (to_uppcase) \
207 fwrite_uppcase (p, (s), _n); \
210 /* Ignore the value of fwrite. The caller can determine whether \
211 an error occurred by inspecting ferror (P). All known fwrite \
212 implementations set the stream's error indicator when they \
213 fail due to ENOMEM etc., even though C11 and POSIX.1-2008 do \
214 not require this. */ \
215 fwrite (s, _n, 1, p); \
224 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
225 else if (to_uppcase) \
226 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
228 MEMCPY ((void *) p, (void const *) (s), _n))
232 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
233 # undef __mbsrtowcs_l
234 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
236 # define widen(os, ws, l) \
239 const char *__s = os; \
240 memset (&__st, '\0', sizeof (__st)); \
241 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
242 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
243 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
248 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
249 /* We use this code also for the extended locale handling where the
250 function gets as an additional argument the locale which has to be
251 used. To access the values we have to redefine the _NL_CURRENT
253 # define strftime __strftime_l
254 # define wcsftime __wcsftime_l
256 # define _NL_CURRENT(category, item) \
257 (current->values[_NL_ITEM_INDEX (item)].string)
258 # define LOCALE_PARAM , __locale_t loc
259 # define LOCALE_ARG , loc
260 # define HELPER_LOCALE_ARG , current
262 # define LOCALE_PARAM
265 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
267 # define HELPER_LOCALE_ARG
272 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
273 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
274 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
276 # define TOUPPER(Ch, L) towupper (Ch)
277 # define TOLOWER(Ch, L) towlower (Ch)
280 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
281 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
282 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
284 # define TOUPPER(Ch, L) toupper (Ch)
285 # define TOLOWER(Ch, L) tolower (Ch)
288 /* We don't use 'isdigit' here since the locale dependent
289 interpretation is not what we want here. We only need to accept
290 the arabic digits in the ASCII range. One day there is perhaps a
291 more reliable way to accept other sets of digits. */
292 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
296 fwrite_lowcase (FILE *fp
, const CHAR_T
*src
, size_t len
)
300 fputc (TOLOWER ((UCHAR_T
) *src
, loc
), fp
);
306 fwrite_uppcase (FILE *fp
, const CHAR_T
*src
, size_t len
)
310 fputc (TOUPPER ((UCHAR_T
) *src
, loc
), fp
);
315 static CHAR_T
*memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
,
316 size_t len LOCALE_PARAM
);
319 memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
, size_t len LOCALE_PARAM
)
322 dest
[len
] = TOLOWER ((UCHAR_T
) src
[len
], loc
);
326 static CHAR_T
*memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
,
327 size_t len LOCALE_PARAM
);
330 memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
, size_t len LOCALE_PARAM
)
333 dest
[len
] = TOUPPER ((UCHAR_T
) src
[len
], loc
);
340 /* Yield the difference between *A and *B,
341 measured in seconds, ignoring leap seconds. */
342 # define tm_diff ftime_tm_diff
343 static int tm_diff (const struct tm
*, const struct tm
*);
345 tm_diff (const struct tm
*a
, const struct tm
*b
)
347 /* Compute intervening leap days correctly even if year is negative.
348 Take care to avoid int overflow in leap day calculations,
349 but it's OK to assume that A and B are close to each other. */
350 int a4
= SHR (a
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (a
->tm_year
& 3);
351 int b4
= SHR (b
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (b
->tm_year
& 3);
352 int a100
= a4
/ 25 - (a4
% 25 < 0);
353 int b100
= b4
/ 25 - (b4
% 25 < 0);
354 int a400
= SHR (a100
, 2);
355 int b400
= SHR (b100
, 2);
356 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
357 int years
= a
->tm_year
- b
->tm_year
;
358 int days
= (365 * years
+ intervening_leap_days
359 + (a
->tm_yday
- b
->tm_yday
));
360 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
361 + (a
->tm_min
- b
->tm_min
))
362 + (a
->tm_sec
- b
->tm_sec
));
364 #endif /* ! HAVE_TM_GMTOFF */
368 /* The number of days from the first day of the first ISO week of this
369 year to the year day YDAY with week day WDAY. ISO weeks start on
370 Monday; the first ISO week has the year's first Thursday. YDAY may
371 be as small as YDAY_MINIMUM. */
372 #define ISO_WEEK_START_WDAY 1 /* Monday */
373 #define ISO_WEEK1_WDAY 4 /* Thursday */
374 #define YDAY_MINIMUM (-366)
375 static int iso_week_days (int, int);
380 iso_week_days (int yday
, int wday
)
382 /* Add enough to the first operand of % to make it nonnegative. */
383 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
385 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
386 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
390 /* When compiling this file, GNU applications can #define my_strftime
391 to a symbol (typically nstrftime) to get an extended strftime with
392 extra arguments TZ and NS. */
396 # define my_strftime fprintftime
401 # define extra_args , tz, ns
402 # define extra_args_spec , timezone_t tz, int ns
404 # if defined COMPILE_WIDE
405 # define my_strftime wcsftime
406 # define nl_get_alt_digit _nl_get_walt_digit
408 # define my_strftime strftime
409 # define nl_get_alt_digit _nl_get_alt_digit
412 # define extra_args_spec
413 /* We don't have this information in general. */
418 static size_t __strftime_internal (STREAM_OR_CHAR_T
*, STRFTIME_ARG (size_t)
419 const CHAR_T
*, const struct tm
*,
421 extra_args_spec LOCALE_PARAM
);
423 /* Write information from TP into S according to the format
424 string FORMAT, writing no more that MAXSIZE characters
425 (including the terminating '\0') and returning number of
426 characters written. If S is NULL, nothing will be written
427 anywhere, so to determine how many characters would be
428 written, use NULL for S and (size_t) -1 for MAXSIZE. */
430 my_strftime (STREAM_OR_CHAR_T
*s
, STRFTIME_ARG (size_t maxsize
)
431 const CHAR_T
*format
,
432 const struct tm
*tp extra_args_spec LOCALE_PARAM
)
434 bool tzset_called
= false;
435 return __strftime_internal (s
, STRFTIME_ARG (maxsize
) format
, tp
,
436 false, &tzset_called extra_args LOCALE_ARG
);
438 #if defined _LIBC && ! FPRINTFTIME
439 libc_hidden_def (my_strftime
)
442 /* Just like my_strftime, above, but with two more parameters.
443 UPCASE indicate that the result should be converted to upper case,
444 and *TZSET_CALLED indicates whether tzset has been called here. */
446 __strftime_internal (STREAM_OR_CHAR_T
*s
, STRFTIME_ARG (size_t maxsize
)
447 const CHAR_T
*format
,
448 const struct tm
*tp
, bool upcase
, bool *tzset_called
449 extra_args_spec LOCALE_PARAM
)
451 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
452 struct __locale_data
*const current
= loc
->__locales
[LC_TIME
];
455 size_t maxsize
= (size_t) -1;
458 int hour12
= tp
->tm_hour
;
460 /* We cannot make the following values variables since we must delay
461 the evaluation of these values until really needed since some
462 expressions might not be valid in every situation. The 'struct tm'
463 might be generated by a strptime() call that initialized
464 only a few elements. Dereference the pointers only if the format
465 requires this. Then it is ok to fail if the pointers are invalid. */
467 ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
468 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)))
470 ((const CHAR_T *) (tp->tm_wday < 0 || tp->tm_wday > 6 \
471 ? "?" : _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)))
473 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
474 ? "?" : _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)))
476 ((const CHAR_T *) (tp->tm_mon < 0 || tp->tm_mon > 11 \
477 ? "?" : _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)))
479 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
480 ? NLW(PM_STR) : NLW(AM_STR)))
482 # define aw_len STRLEN (a_wkday)
483 # define am_len STRLEN (a_month)
484 # define ap_len STRLEN (ampm)
487 char **tzname_vec
= tzname
;
491 STREAM_OR_CHAR_T
*p
= s
;
493 #if DO_MULTIBYTE && !defined COMPILE_WIDE
494 const char *format_end
= NULL
;
497 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
498 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
499 by localtime. On such systems, we must either use the tzset and
500 localtime wrappers to work around the bug (which sets
501 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
502 struct tm copy
= *tp
;
508 /* The POSIX test suite assumes that setting
509 the environment variable TZ to a new value before calling strftime()
510 will influence the result (the %Z format) even if the information in
511 TP is computed with a totally different time zone.
512 This is bogus: though POSIX allows bad behavior like this,
513 POSIX does not require it. Do the right thing instead. */
514 zone
= (const char *) tp
->tm_zone
;
519 if (! (zone
&& *zone
))
525 /* Infer the zone name from *TZ instead of from TZNAME. */
526 tzname_vec
= tz
->tzname_copy
;
529 /* The tzset() call might have changed the value. */
530 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
532 /* POSIX.1 requires that local time zone information be used as
533 though strftime called tzset. */
538 *tzset_called
= true;
541 zone
= tzname_vec
[tp
->tm_isdst
!= 0];
553 for (f
= format
; *f
!= '\0'; ++f
)
555 int pad
= 0; /* Padding for number ('-', '_', or 0). */
556 int modifier
; /* Field modifier ('E', 'O', or 0). */
557 int digits
= 0; /* Max digits for numeric format. */
558 int number_value
; /* Numeric value to be printed. */
559 unsigned int u_number_value
; /* (unsigned int) number_value. */
560 bool negative_number
; /* The number is negative. */
561 bool always_output_a_sign
; /* +/- should always be output. */
562 int tz_colon_mask
; /* Bitmask of where ':' should appear. */
563 const CHAR_T
*subfmt
;
567 + 2 /* for the two colons in a %::z or %:::z time zone */
568 + (sizeof (int) < sizeof (time_t)
569 ? INT_STRLEN_BOUND (time_t)
570 : INT_STRLEN_BOUND (int))];
572 bool to_lowcase
= false;
573 bool to_uppcase
= upcase
;
575 bool change_case
= false;
578 #if DO_MULTIBYTE && !defined COMPILE_WIDE
584 case L_('\b'): case L_('\t'): case L_('\n'):
585 case L_('\v'): case L_('\f'): case L_('\r'):
586 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
587 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
588 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
589 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
590 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
591 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
592 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
593 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
594 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
595 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
596 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
597 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
598 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
599 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
600 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
601 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
602 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
603 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
605 /* The C Standard requires these 98 characters (plus '%') to
606 be in the basic execution character set. None of these
607 characters can start a multibyte sequence, so they need
608 not be analyzed further. */
613 /* Copy this multibyte sequence until we reach its end, find
614 an error, or come back to the initial shift state. */
616 mbstate_t mbstate
= mbstate_zero
;
621 format_end
= f
+ strlen (f
) + 1;
622 fsize
= format_end
- f
;
626 size_t bytes
= mbrlen (f
+ len
, fsize
- len
, &mbstate
);
631 if (bytes
== (size_t) -2)
633 len
+= strlen (f
+ len
);
637 if (bytes
== (size_t) -1)
645 while (! mbsinit (&mbstate
));
653 #else /* ! DO_MULTIBYTE */
655 /* Either multibyte encodings are not supported, they are
656 safe for formats, so any non-'%' byte can be copied through,
657 or this is the wide character version. */
664 #endif /* ! DO_MULTIBYTE */
666 /* Check for flags that can modify a format. */
671 /* This influences the number formats. */
678 /* This changes textual output. */
692 /* As a GNU extension we allow the field width to be specified. */
698 if (width
> INT_MAX
/ 10
699 || (width
== INT_MAX
/ 10 && *f
- L_('0') > INT_MAX
% 10))
700 /* Avoid overflow. */
705 width
+= *f
- L_('0');
709 while (ISDIGIT (*f
));
712 /* Check for modifiers. */
725 /* Now do the specified format. */
729 #define DO_NUMBER(d, v) \
737 #define DO_SIGNED_NUMBER(d, negative, v) \
741 negative_number = negative; \
742 u_number_value = v; \
743 goto do_signed_number; \
747 /* The mask is not what you might think.
748 When the ordinal i'th bit is set, insert a colon
749 before the i'th digit of the time zone representation. */
750 #define DO_TZ_OFFSET(d, mask, v) \
754 tz_colon_mask = mask; \
755 u_number_value = v; \
759 #define DO_NUMBER_SPACEPAD(d, v) \
764 goto do_number_spacepad; \
783 cpy (aw_len
, a_wkday
);
786 goto underlying_strftime
;
798 cpy (STRLEN (f_wkday
), f_wkday
);
801 goto underlying_strftime
;
814 cpy (am_len
, a_month
);
817 goto underlying_strftime
;
829 cpy (STRLEN (f_month
), f_month
);
832 goto underlying_strftime
;
836 if (modifier
== L_('O'))
839 if (! (modifier
== 'E'
841 (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
844 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_T_FMT
));
846 goto underlying_strftime
;
851 size_t len
= __strftime_internal (NULL
, STRFTIME_ARG ((size_t) -1)
853 tp
, to_uppcase
, tzset_called
854 extra_args LOCALE_ARG
);
855 add (len
, __strftime_internal (p
,
856 STRFTIME_ARG (maxsize
- i
)
858 tp
, to_uppcase
, tzset_called
859 extra_args LOCALE_ARG
));
863 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
866 /* The relevant information is available only via the
867 underlying strftime implementation, so use that. */
870 char ubuf
[1024]; /* enough for any single format in practice */
872 /* Make sure we're calling the actual underlying strftime.
873 In some cases, config.h contains something like
874 "#define strftime rpl_strftime". */
880 /* The space helps distinguish strftime failure from empty
888 len
= strftime (ubuf
, sizeof ubuf
, ufmt
, tp
);
890 cpy (len
- 1, ubuf
+ 1);
896 if (modifier
== L_('E'))
898 #if HAVE_STRUCT_ERA_ENTRY
899 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
903 size_t len
= __wcslen (era
->era_wname
);
904 cpy (len
, era
->era_wname
);
906 size_t len
= strlen (era
->era_name
);
907 cpy (len
, era
->era_name
);
912 goto underlying_strftime
;
917 int century
= tp
->tm_year
/ 100 + TM_YEAR_BASE
/ 100;
918 century
-= tp
->tm_year
% 100 < 0 && 0 < century
;
919 DO_SIGNED_NUMBER (2, tp
->tm_year
< - TM_YEAR_BASE
, century
);
923 if (modifier
== L_('O'))
926 if (! (modifier
== L_('E')
928 (const CHAR_T
*)_NL_CURRENT (LC_TIME
, NLW(ERA_D_FMT
)))
930 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_FMT
));
933 goto underlying_strftime
;
938 subfmt
= L_("%m/%d/%y");
942 if (modifier
== L_('E'))
945 DO_NUMBER (2, tp
->tm_mday
);
948 if (modifier
== L_('E'))
951 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
953 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
954 and then jump to one of these labels. */
957 always_output_a_sign
= true;
961 /* Force '_' flag unless overridden by '0' or '-' flag. */
962 if (pad
!= L_('0') && pad
!= L_('-'))
966 /* Format NUMBER_VALUE according to the MODIFIER flag. */
967 negative_number
= number_value
< 0;
968 u_number_value
= number_value
;
971 always_output_a_sign
= false;
975 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
976 NEGATIVE_NUMBER is nonzero if the original number was
977 negative; in this case it was converted directly to
978 unsigned int (i.e., modulo (UINT_MAX + 1)) without
980 if (modifier
== L_('O') && !negative_number
)
983 /* Get the locale specific alternate representation of
984 the number. If none exist NULL is returned. */
985 const CHAR_T
*cp
= nl_get_alt_digit (u_number_value
990 size_t digitlen
= STRLEN (cp
);
998 goto underlying_strftime
;
1002 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1004 if (negative_number
)
1005 u_number_value
= - u_number_value
;
1009 if (tz_colon_mask
& 1)
1011 tz_colon_mask
>>= 1;
1012 *--bufp
= u_number_value
% 10 + L_('0');
1013 u_number_value
/= 10;
1015 while (u_number_value
!= 0 || tz_colon_mask
!= 0);
1017 do_number_sign_and_padding
:
1021 sign_char
= (negative_number
? L_('-')
1022 : always_output_a_sign
? L_('+')
1032 int padding
= digits
- (buf
+ (sizeof (buf
) / sizeof (buf
[0]))
1033 - bufp
) - !!sign_char
;
1039 if ((size_t) padding
>= maxsize
- i
)
1043 memset_space (p
, padding
);
1045 width
= width
> padding
? width
- padding
: 0;
1051 if ((size_t) digits
>= maxsize
- i
)
1058 memset_zero (p
, padding
);
1070 cpy (buf
+ sizeof (buf
) / sizeof (buf
[0]) - bufp
, bufp
);
1076 subfmt
= L_("%Y-%m-%d");
1080 if (modifier
== L_('E'))
1083 DO_NUMBER (2, tp
->tm_hour
);
1086 if (modifier
== L_('E'))
1089 DO_NUMBER (2, hour12
);
1091 case L_('k'): /* GNU extension. */
1092 if (modifier
== L_('E'))
1095 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
1097 case L_('l'): /* GNU extension. */
1098 if (modifier
== L_('E'))
1101 DO_NUMBER_SPACEPAD (2, hour12
);
1104 if (modifier
== L_('E'))
1107 DO_SIGNED_NUMBER (3, tp
->tm_yday
< -1, tp
->tm_yday
+ 1U);
1110 if (modifier
== L_('E'))
1113 DO_NUMBER (2, tp
->tm_min
);
1116 if (modifier
== L_('E'))
1119 DO_SIGNED_NUMBER (2, tp
->tm_mon
< -1, tp
->tm_mon
+ 1U);
1122 case L_('N'): /* GNU extension. */
1123 if (modifier
== L_('E'))
1131 /* Take an explicit width less than 9 as a precision. */
1133 for (j
= width
; j
< 9; j
++)
1137 DO_NUMBER (width
, number_value
);
1147 format_char
= L_('p');
1160 goto underlying_strftime
;
1163 case L_('q'): /* GNU extension. */
1164 DO_SIGNED_NUMBER (1, false, ((tp
->tm_mon
* 11) >> 5) + 1);
1168 subfmt
= L_("%H:%M");
1173 if (*(subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
1176 subfmt
= L_("%I:%M:%S %p");
1179 goto underlying_strftime
;
1183 if (modifier
== L_('E'))
1186 DO_NUMBER (2, tp
->tm_sec
);
1188 case L_('s'): /* GNU extension. */
1194 t
= mktime_z (tz
, <m
);
1196 /* Generate string value for T using time_t arithmetic;
1197 this works even if sizeof (long) < sizeof (time_t). */
1199 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1200 negative_number
= t
< 0;
1206 *--bufp
= (negative_number
? -d
: d
) + L_('0');
1211 always_output_a_sign
= false;
1212 goto do_number_sign_and_padding
;
1216 if (modifier
== L_('O'))
1219 if (! (modifier
== L_('E')
1221 (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(ERA_T_FMT
)))
1223 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(T_FMT
));
1226 goto underlying_strftime
;
1229 subfmt
= L_("%H:%M:%S");
1237 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
1240 if (modifier
== L_('E'))
1243 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
1248 if (modifier
== L_('E'))
1251 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1252 is a leap year, except that YEAR and YEAR - 1 both work
1253 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1255 int year
= (tp
->tm_year
1257 ? TM_YEAR_BASE
% 400
1258 : TM_YEAR_BASE
% 400 - 400));
1259 int year_adjust
= 0;
1260 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
1264 /* This ISO week belongs to the previous year. */
1266 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
- 1)),
1271 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
1275 /* This ISO week belongs to the next year. */
1285 int yy
= (tp
->tm_year
% 100 + year_adjust
) % 100;
1286 DO_NUMBER (2, (0 <= yy
1288 : tp
->tm_year
< -TM_YEAR_BASE
- year_adjust
1294 DO_SIGNED_NUMBER (4, tp
->tm_year
< -TM_YEAR_BASE
- year_adjust
,
1295 (tp
->tm_year
+ (unsigned int) TM_YEAR_BASE
1299 DO_NUMBER (2, days
/ 7 + 1);
1304 if (modifier
== L_('E'))
1307 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
1310 if (modifier
== L_('E'))
1313 DO_NUMBER (1, tp
->tm_wday
);
1316 if (modifier
== 'E')
1318 #if HAVE_STRUCT_ERA_ENTRY
1319 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1322 # ifdef COMPILE_WIDE
1323 subfmt
= era
->era_wformat
;
1325 subfmt
= era
->era_format
;
1330 goto underlying_strftime
;
1333 if (modifier
== L_('O'))
1336 DO_SIGNED_NUMBER (4, tp
->tm_year
< -TM_YEAR_BASE
,
1337 tp
->tm_year
+ (unsigned int) TM_YEAR_BASE
);
1340 if (modifier
== L_('E'))
1342 #if HAVE_STRUCT_ERA_ENTRY
1343 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1346 int delta
= tp
->tm_year
- era
->start_date
[0];
1347 DO_NUMBER (1, (era
->offset
1348 + delta
* era
->absolute_direction
));
1351 goto underlying_strftime
;
1356 int yy
= tp
->tm_year
% 100;
1358 yy
= tp
->tm_year
< - TM_YEAR_BASE
? -yy
: yy
+ 100;
1371 /* The zone string is always given in multibyte form. We have
1372 to transform it first. */
1375 widen (zone
, wczone
, len
);
1379 cpy (strlen (zone
), zone
);
1384 /* :, ::, and ::: are valid only just before 'z'.
1385 :::: etc. are rejected later. */
1386 for (colons
= 1; f
[colons
] == L_(':'); colons
++)
1388 if (f
[colons
] != L_('z'))
1391 goto do_z_conversion
;
1397 if (tp
->tm_isdst
< 0)
1406 diff
= tp
->tm_gmtoff
;
1416 /* POSIX.1 requires that local time zone information be used as
1417 though strftime called tzset. */
1422 *tzset_called
= true;
1427 lt
= mktime_z (tz
, <m
);
1429 if (lt
== (time_t) -1)
1431 /* mktime returns -1 for errors, but -1 is also a
1432 valid time_t value. Check whether an error really
1436 if (! localtime_rz (tz
, <
, &tm
)
1437 || ((ltm
.tm_sec
^ tm
.tm_sec
)
1438 | (ltm
.tm_min
^ tm
.tm_min
)
1439 | (ltm
.tm_hour
^ tm
.tm_hour
)
1440 | (ltm
.tm_mday
^ tm
.tm_mday
)
1441 | (ltm
.tm_mon
^ tm
.tm_mon
)
1442 | (ltm
.tm_year
^ tm
.tm_year
)))
1446 if (! localtime_rz (0, <
, >m
))
1449 diff
= tm_diff (<m
, >m
);
1453 negative_number
= diff
< 0 || (diff
== 0 && *zone
== '-');
1454 hour_diff
= diff
/ 60 / 60;
1455 min_diff
= diff
/ 60 % 60;
1456 sec_diff
= diff
% 60;
1461 DO_TZ_OFFSET (5, 0, hour_diff
* 100 + min_diff
);
1463 case 1: tz_hh_mm
: /* +hh:mm */
1464 DO_TZ_OFFSET (6, 04, hour_diff
* 100 + min_diff
);
1466 case 2: tz_hh_mm_ss
: /* +hh:mm:ss */
1467 DO_TZ_OFFSET (9, 024,
1468 hour_diff
* 10000 + min_diff
* 100 + sec_diff
);
1470 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1475 DO_TZ_OFFSET (3, 0, hour_diff
);
1482 case L_('\0'): /* GNU extension: % at end of format. */
1486 /* Unknown format; output the format, including the '%',
1487 since this is most likely the right thing to do if a
1488 multibyte string has been misparsed. */
1492 for (flen
= 1; f
[1 - flen
] != L_('%'); flen
++)
1494 cpy (flen
, &f
[1 - flen
]);
1501 if (p
&& maxsize
!= 0)