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 Lesser 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 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 # define HAVE_MBRLEN 1
23 # define HAVE_STRUCT_ERA_ENTRY 1
24 # define HAVE_TM_GMTOFF 1
25 # define HAVE_TM_ZONE 1
26 # define HAVE_TZNAME 1
28 # define MULTIBYTE_IS_FORMAT_SAFE 1
29 # include "../locale/localeinfo.h"
33 # include "fprintftime.h"
40 #if HAVE_TZNAME && !HAVE_DECL_TZNAME
41 extern char *tzname
[];
44 /* Do multibyte processing if multibytes are supported, unless
45 multibyte sequences are safe in formats. Multibyte sequences are
46 safe if they cannot contain byte sequences that look like format
47 conversion specifications. The GNU C Library uses UTF8 multibyte
48 encoding, which is safe for formats, but strftime.c can be used
49 with other C libraries that use unsafe encodings. */
50 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE)
54 static const mbstate_t mbstate_zero
;
65 # define CHAR_T wchar_t
66 # define UCHAR_T unsigned int
67 # define L_(Str) L##Str
68 # define NLW(Sym) _NL_W##Sym
70 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
71 # define STRLEN(s) __wcslen (s)
75 # define UCHAR_T unsigned char
79 # define MEMCPY(d, s, n) memcpy (d, s, n)
80 # define STRLEN(s) strlen (s)
83 # define MEMPCPY(d, s, n) __mempcpy (d, s, n)
86 # define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n)))
91 /* Shift A right by B bits portably, by dividing A by 2**B and
92 truncating towards minus infinity. A and B should be free of side
93 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
94 INT_BITS is the number of useful bits in an int. GNU code can
95 assume that INT_BITS is at least 32.
97 ISO C99 says that A >> B is implementation-defined if A < 0. Some
98 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
99 right in the usual way when A < 0, so SHR falls back on division if
100 ordinary A >> B doesn't seem to be the usual signed shift. */
104 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
106 /* Bound on length of the string representing an integer type or expression T.
107 Subtract 1 for the sign bit if t is signed; log10 (2.0) < 146/485;
108 add 1 for integer division truncation; add 1 more for a minus sign
110 #define INT_STRLEN_BOUND(t) \
111 ((sizeof (t) * CHAR_BIT - 1) * 146 / 485 + 2)
113 #define TM_YEAR_BASE 1900
116 /* Nonzero if YEAR is a leap year (every 4 years,
117 except every 100th isn't, and every 400th is). */
118 # define __isleap(year) \
119 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
124 # define tzname __tzname
125 # define tzset __tzset
129 /* Portable standalone applications should supply a "time.h" that
130 declares a POSIX-compliant localtime_r, for the benefit of older
131 implementations that lack localtime_r or have a nonstandard one.
132 See the gnulib time_r module for one way to implement this. */
134 # undef __localtime_r
135 # define __gmtime_r gmtime_r
136 # define __localtime_r localtime_r
141 # define FPRINTFTIME 0
145 # define STREAM_OR_CHAR_T FILE
146 # define STRFTIME_ARG(x) /* empty */
148 # define STREAM_OR_CHAR_T CHAR_T
149 # define STRFTIME_ARG(x) x,
153 # define memset_byte(P, Len, Byte) \
154 do { size_t _i; for (_i = 0; _i < Len; _i++) fputc (Byte, P); } while (0)
155 # define memset_space(P, Len) memset_byte (P, Len, ' ')
156 # define memset_zero(P, Len) memset_byte (P, Len, '0')
157 #elif defined COMPILE_WIDE
158 # define memset_space(P, Len) (wmemset (P, L' ', Len), (P) += (Len))
159 # define memset_zero(P, Len) (wmemset (P, L'0', Len), (P) += (Len))
161 # define memset_space(P, Len) (memset (P, ' ', Len), (P) += (Len))
162 # define memset_zero(P, Len) (memset (P, '0', Len), (P) += (Len))
166 # define advance(P, N)
168 # define advance(P, N) ((P) += (N))
175 int _delta = width - _n; \
176 int _incr = _n + (_delta > 0 ? _delta : 0); \
177 if ((size_t) _incr >= maxsize - i) \
181 if (digits == 0 && _delta > 0) \
183 if (pad == L_('0')) \
184 memset_zero (p, _delta); \
186 memset_space (p, _delta); \
195 # define add1(C) add (1, fputc (C, p))
197 # define add1(C) add (1, *p = C)
204 fwrite_lowcase (p, (s), _n); \
205 else if (to_uppcase) \
206 fwrite_uppcase (p, (s), _n); \
208 fwrite ((s), _n, 1, p))
213 memcpy_lowcase (p, (s), _n LOCALE_ARG); \
214 else if (to_uppcase) \
215 memcpy_uppcase (p, (s), _n LOCALE_ARG); \
217 MEMCPY ((void *) p, (void const *) (s), _n))
221 # ifndef USE_IN_EXTENDED_LOCALE_MODEL
222 # undef __mbsrtowcs_l
223 # define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st)
225 # define widen(os, ws, l) \
228 const char *__s = os; \
229 memset (&__st, '\0', sizeof (__st)); \
230 l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \
231 ws = (wchar_t *) alloca ((l + 1) * sizeof (wchar_t)); \
232 (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \
237 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
238 /* We use this code also for the extended locale handling where the
239 function gets as an additional argument the locale which has to be
240 used. To access the values we have to redefine the _NL_CURRENT
242 # define strftime __strftime_l
243 # define wcsftime __wcsftime_l
245 # define _NL_CURRENT(category, item) \
246 (current->values[_NL_ITEM_INDEX (item)].string)
247 # define LOCALE_ARG , loc
248 # define LOCALE_PARAM_PROTO , __locale_t loc
249 # define HELPER_LOCALE_ARG , current
251 # define LOCALE_PARAM_PROTO
254 # define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME)
256 # define HELPER_LOCALE_ARG
261 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
262 # define TOUPPER(Ch, L) __towupper_l (Ch, L)
263 # define TOLOWER(Ch, L) __towlower_l (Ch, L)
265 # define TOUPPER(Ch, L) towupper (Ch)
266 # define TOLOWER(Ch, L) towlower (Ch)
269 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
270 # define TOUPPER(Ch, L) __toupper_l (Ch, L)
271 # define TOLOWER(Ch, L) __tolower_l (Ch, L)
273 # define TOUPPER(Ch, L) toupper (Ch)
274 # define TOLOWER(Ch, L) tolower (Ch)
277 /* We don't use `isdigit' here since the locale dependent
278 interpretation is not what we want here. We only need to accept
279 the arabic digits in the ASCII range. One day there is perhaps a
280 more reliable way to accept other sets of digits. */
281 #define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9)
285 fwrite_lowcase (FILE *fp
, const CHAR_T
*src
, size_t len
)
289 fputc (TOLOWER ((UCHAR_T
) *src
, loc
), fp
);
295 fwrite_uppcase (FILE *fp
, const CHAR_T
*src
, size_t len
)
299 fputc (TOUPPER ((UCHAR_T
) *src
, loc
), fp
);
305 memcpy_lowcase (CHAR_T
*dest
, const CHAR_T
*src
,
306 size_t len LOCALE_PARAM_PROTO
)
309 dest
[len
] = TOLOWER ((UCHAR_T
) src
[len
], loc
);
314 memcpy_uppcase (CHAR_T
*dest
, const CHAR_T
*src
,
315 size_t len LOCALE_PARAM_PROTO
)
318 dest
[len
] = TOUPPER ((UCHAR_T
) src
[len
], loc
);
325 /* Yield the difference between *A and *B,
326 measured in seconds, ignoring leap seconds. */
327 # define tm_diff ftime_tm_diff
329 tm_diff (const struct tm
*a
, const struct tm
*b
)
331 /* Compute intervening leap days correctly even if year is negative.
332 Take care to avoid int overflow in leap day calculations,
333 but it's OK to assume that A and B are close to each other. */
334 int a4
= SHR (a
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (a
->tm_year
& 3);
335 int b4
= SHR (b
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (b
->tm_year
& 3);
336 int a100
= a4
/ 25 - (a4
% 25 < 0);
337 int b100
= b4
/ 25 - (b4
% 25 < 0);
338 int a400
= SHR (a100
, 2);
339 int b400
= SHR (b100
, 2);
340 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
341 int years
= a
->tm_year
- b
->tm_year
;
342 int days
= (365 * years
+ intervening_leap_days
343 + (a
->tm_yday
- b
->tm_yday
));
344 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
345 + (a
->tm_min
- b
->tm_min
))
346 + (a
->tm_sec
- b
->tm_sec
));
348 #endif /* ! HAVE_TM_GMTOFF */
352 /* The number of days from the first day of the first ISO week of this
353 year to the year day YDAY with week day WDAY. ISO weeks start on
354 Monday; the first ISO week has the year's first Thursday. YDAY may
355 be as small as YDAY_MINIMUM. */
356 #define ISO_WEEK_START_WDAY 1 /* Monday */
357 #define ISO_WEEK1_WDAY 4 /* Thursday */
358 #define YDAY_MINIMUM (-366)
363 iso_week_days (int yday
, int wday
)
365 /* Add enough to the first operand of % to make it nonnegative. */
366 int big_enough_multiple_of_7
= (-YDAY_MINIMUM
/ 7 + 2) * 7;
368 - (yday
- wday
+ ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
369 + ISO_WEEK1_WDAY
- ISO_WEEK_START_WDAY
);
373 /* When compiling this file, GNU applications can #define my_strftime
374 to a symbol (typically nstrftime) to get an extended strftime with
375 extra arguments UT and NS. Emacs is a special case for now, but
376 this Emacs-specific code can be removed once Emacs's config.h
377 defines my_strftime. */
378 #if defined emacs && !defined my_strftime
379 # define my_strftime nstrftime
384 # define my_strftime fprintftime
388 # define extra_args , ut, ns
389 # define extra_args_spec , int ut, int ns
391 # if defined COMPILE_WIDE
392 # define my_strftime wcsftime
393 # define nl_get_alt_digit _nl_get_walt_digit
395 # define my_strftime strftime
396 # define nl_get_alt_digit _nl_get_alt_digit
399 # define extra_args_spec
400 /* We don't have this information in general. */
406 /* Just like my_strftime, below, but with one more parameter, UPCASE,
407 to indicate that the result should be converted to upper case. */
409 strftime_case_ (bool upcase
, STREAM_OR_CHAR_T
*s
,
410 STRFTIME_ARG (size_t maxsize
)
411 const CHAR_T
*format
,
412 const struct tm
*tp extra_args_spec LOCALE_PARAM_PROTO
)
414 #if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL
415 struct locale_data
*const current
= loc
->__locales
[LC_TIME
];
418 size_t maxsize
= (size_t) -1;
421 int hour12
= tp
->tm_hour
;
423 /* We cannot make the following values variables since we must delay
424 the evaluation of these values until really needed since some
425 expressions might not be valid in every situation. The `struct tm'
426 might be generated by a strptime() call that initialized
427 only a few elements. Dereference the pointers only if the format
428 requires this. Then it is ok to fail if the pointers are invalid. */
430 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday))
432 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday))
434 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon))
436 ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon))
438 ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \
439 ? NLW(PM_STR) : NLW(AM_STR)))
441 # define aw_len STRLEN (a_wkday)
442 # define am_len STRLEN (a_month)
443 # define ap_len STRLEN (ampm)
447 STREAM_OR_CHAR_T
*p
= s
;
449 #if DO_MULTIBYTE && !defined COMPILE_WIDE
450 const char *format_end
= NULL
;
453 #if ! defined _LIBC && ! HAVE_RUN_TZSET_TEST
454 /* Solaris 2.5.x and 2.6 tzset sometimes modify the storage returned
455 by localtime. On such systems, we must either use the tzset and
456 localtime wrappers to work around the bug (which sets
457 HAVE_RUN_TZSET_TEST) or make a copy of the structure. */
458 struct tm copy
= *tp
;
464 /* The POSIX test suite assumes that setting
465 the environment variable TZ to a new value before calling strftime()
466 will influence the result (the %Z format) even if the information in
467 TP is computed with a totally different time zone.
468 This is bogus: though POSIX allows bad behavior like this,
469 POSIX does not require it. Do the right thing instead. */
470 zone
= (const char *) tp
->tm_zone
;
475 if (! (zone
&& *zone
))
480 /* POSIX.1 requires that local time zone information be used as
481 though strftime called tzset. */
494 for (f
= format
; *f
!= '\0'; ++f
)
496 int pad
= 0; /* Padding for number ('-', '_', or 0). */
497 int modifier
; /* Field modifier ('E', 'O', or 0). */
498 int digits
= 0; /* Max digits for numeric format. */
499 int number_value
; /* Numeric value to be printed. */
500 unsigned int u_number_value
; /* (unsigned int) number_value. */
501 bool negative_number
; /* The number is negative. */
502 bool always_output_a_sign
; /* +/- should always be output. */
503 int tz_colon_mask
; /* Bitmask of where ':' should appear. */
504 const CHAR_T
*subfmt
;
508 + 2 /* for the two colons in a %::z or %:::z time zone */
509 + (sizeof (int) < sizeof (time_t)
510 ? INT_STRLEN_BOUND (time_t)
511 : INT_STRLEN_BOUND (int))];
513 bool to_lowcase
= false;
514 bool to_uppcase
= upcase
;
516 bool change_case
= false;
519 #if DO_MULTIBYTE && !defined COMPILE_WIDE
525 case L_('\b'): case L_('\t'): case L_('\n'):
526 case L_('\v'): case L_('\f'): case L_('\r'):
527 case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'):
528 case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'):
529 case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'):
530 case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'):
531 case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'):
532 case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'):
533 case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'):
534 case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'):
535 case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'):
536 case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'):
537 case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'):
538 case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'):
539 case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'):
540 case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
541 case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
542 case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
543 case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
544 case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
546 /* The C Standard requires these 98 characters (plus '%') to
547 be in the basic execution character set. None of these
548 characters can start a multibyte sequence, so they need
549 not be analyzed further. */
554 /* Copy this multibyte sequence until we reach its end, find
555 an error, or come back to the initial shift state. */
557 mbstate_t mbstate
= mbstate_zero
;
562 format_end
= f
+ strlen (f
) + 1;
563 fsize
= format_end
- f
;
567 size_t bytes
= mbrlen (f
+ len
, fsize
- len
, &mbstate
);
572 if (bytes
== (size_t) -2)
574 len
+= strlen (f
+ len
);
578 if (bytes
== (size_t) -1)
586 while (! mbsinit (&mbstate
));
594 #else /* ! DO_MULTIBYTE */
596 /* Either multibyte encodings are not supported, they are
597 safe for formats, so any non-'%' byte can be copied through,
598 or this is the wide character version. */
605 #endif /* ! DO_MULTIBYTE */
607 /* Check for flags that can modify a format. */
612 /* This influences the number formats. */
619 /* This changes textual output. */
633 /* As a GNU extension we allow to specify the field width. */
639 if (width
> INT_MAX
/ 10
640 || (width
== INT_MAX
/ 10 && *f
- L_('0') > INT_MAX
% 10))
641 /* Avoid overflow. */
646 width
+= *f
- L_('0');
650 while (ISDIGIT (*f
));
653 /* Check for modifiers. */
666 /* Now do the specified format. */
670 #define DO_NUMBER(d, v) \
672 number_value = v; goto do_number
673 #define DO_SIGNED_NUMBER(d, negative, v) \
675 negative_number = negative; \
676 u_number_value = v; goto do_signed_number
678 /* The mask is not what you might think.
679 When the ordinal i'th bit is set, insert a colon
680 before the i'th digit of the time zone representation. */
681 #define DO_TZ_OFFSET(d, negative, mask, v) \
683 negative_number = negative; \
684 tz_colon_mask = mask; \
685 u_number_value = v; goto do_tz_offset
686 #define DO_NUMBER_SPACEPAD(d, v) \
688 number_value = v; goto do_number_spacepad
705 cpy (aw_len
, a_wkday
);
708 goto underlying_strftime
;
720 cpy (STRLEN (f_wkday
), f_wkday
);
723 goto underlying_strftime
;
736 cpy (am_len
, a_month
);
739 goto underlying_strftime
;
751 cpy (STRLEN (f_month
), f_month
);
754 goto underlying_strftime
;
758 if (modifier
== L_('O'))
761 if (! (modifier
== 'E'
763 (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
766 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_T_FMT
));
768 goto underlying_strftime
;
773 size_t len
= strftime_case_ (to_uppcase
,
774 NULL
, STRFTIME_ARG ((size_t) -1)
776 tp extra_args LOCALE_ARG
);
777 add (len
, strftime_case_ (to_uppcase
, p
,
778 STRFTIME_ARG (maxsize
- i
)
780 tp extra_args LOCALE_ARG
));
784 #if !(defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY)
787 /* The relevant information is available only via the
788 underlying strftime implementation, so use that. */
791 char ubuf
[1024]; /* enough for any single format in practice */
793 /* Make sure we're calling the actual underlying strftime.
794 In some cases, config.h contains something like
795 "#define strftime rpl_strftime". */
801 /* The space helps distinguish strftime failure from empty
809 len
= strftime (ubuf
, sizeof ubuf
, ufmt
, tp
);
811 cpy (len
- 1, ubuf
+ 1);
817 if (modifier
== L_('O'))
819 if (modifier
== L_('E'))
821 #if HAVE_STRUCT_ERA_ENTRY
822 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
826 size_t len
= __wcslen (era
->era_wname
);
827 cpy (len
, era
->era_wname
);
829 size_t len
= strlen (era
->era_name
);
830 cpy (len
, era
->era_name
);
835 goto underlying_strftime
;
840 int century
= tp
->tm_year
/ 100 + TM_YEAR_BASE
/ 100;
841 century
-= tp
->tm_year
% 100 < 0 && 0 < century
;
842 DO_SIGNED_NUMBER (2, tp
->tm_year
< - TM_YEAR_BASE
, century
);
846 if (modifier
== L_('O'))
849 if (! (modifier
== L_('E')
851 (const CHAR_T
*)_NL_CURRENT (LC_TIME
, NLW(ERA_D_FMT
)))
853 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(D_FMT
));
856 goto underlying_strftime
;
861 subfmt
= L_("%m/%d/%y");
865 if (modifier
== L_('E'))
868 DO_NUMBER (2, tp
->tm_mday
);
871 if (modifier
== L_('E'))
874 DO_NUMBER_SPACEPAD (2, tp
->tm_mday
);
876 /* All numeric formats set DIGITS and NUMBER_VALUE (or U_NUMBER_VALUE)
877 and then jump to one of these labels. */
880 always_output_a_sign
= true;
884 /* Force `_' flag unless overridden by `0' or `-' flag. */
885 if (pad
!= L_('0') && pad
!= L_('-'))
889 /* Format NUMBER_VALUE according to the MODIFIER flag. */
890 negative_number
= number_value
< 0;
891 u_number_value
= number_value
;
894 always_output_a_sign
= false;
898 /* Format U_NUMBER_VALUE according to the MODIFIER flag.
899 NEGATIVE_NUMBER is nonzero if the original number was
900 negative; in this case it was converted directly to
901 unsigned int (i.e., modulo (UINT_MAX + 1)) without
903 if (modifier
== L_('O') && !negative_number
)
906 /* Get the locale specific alternate representation of
907 the number. If none exist NULL is returned. */
908 const CHAR_T
*cp
= nl_get_alt_digit (u_number_value
913 size_t digitlen
= STRLEN (cp
);
921 goto underlying_strftime
;
925 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
928 u_number_value
= - u_number_value
;
932 if (tz_colon_mask
& 1)
935 *--bufp
= u_number_value
% 10 + L_('0');
936 u_number_value
/= 10;
938 while (u_number_value
!= 0 || tz_colon_mask
!= 0);
940 do_number_sign_and_padding
:
944 sign_char
= (negative_number
? L_('-')
945 : always_output_a_sign
? L_('+')
955 int padding
= digits
- (buf
+ (sizeof (buf
) / sizeof (buf
[0]))
956 - bufp
) - !!sign_char
;
962 if ((size_t) padding
>= maxsize
- i
)
966 memset_space (p
, padding
);
968 width
= width
> padding
? width
- padding
: 0;
974 if ((size_t) digits
>= maxsize
- i
)
981 memset_zero (p
, padding
);
993 cpy (buf
+ sizeof (buf
) / sizeof (buf
[0]) - bufp
, bufp
);
999 subfmt
= L_("%Y-%m-%d");
1003 if (modifier
== L_('E'))
1006 DO_NUMBER (2, tp
->tm_hour
);
1009 if (modifier
== L_('E'))
1012 DO_NUMBER (2, hour12
);
1014 case L_('k'): /* GNU extension. */
1015 if (modifier
== L_('E'))
1018 DO_NUMBER_SPACEPAD (2, tp
->tm_hour
);
1020 case L_('l'): /* GNU extension. */
1021 if (modifier
== L_('E'))
1024 DO_NUMBER_SPACEPAD (2, hour12
);
1027 if (modifier
== L_('E'))
1030 DO_SIGNED_NUMBER (3, tp
->tm_yday
< -1, tp
->tm_yday
+ 1U);
1033 if (modifier
== L_('E'))
1036 DO_NUMBER (2, tp
->tm_min
);
1039 if (modifier
== L_('E'))
1042 DO_SIGNED_NUMBER (2, tp
->tm_mon
< -1, tp
->tm_mon
+ 1U);
1045 case L_('N'): /* GNU extension. */
1046 if (modifier
== L_('E'))
1054 /* Take an explicit width less than 9 as a precision. */
1056 for (j
= width
; j
< 9; j
++)
1060 DO_NUMBER (width
, number_value
);
1070 format_char
= L_('p');
1084 goto underlying_strftime
;
1088 subfmt
= L_("%H:%M");
1093 if (*(subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
,
1096 subfmt
= L_("%I:%M:%S %p");
1099 goto underlying_strftime
;
1103 if (modifier
== L_('E'))
1106 DO_NUMBER (2, tp
->tm_sec
);
1108 case L_('s'): /* GNU extension. */
1116 /* Generate string value for T using time_t arithmetic;
1117 this works even if sizeof (long) < sizeof (time_t). */
1119 bufp
= buf
+ sizeof (buf
) / sizeof (buf
[0]);
1120 negative_number
= t
< 0;
1126 *--bufp
= (negative_number
? -d
: d
) + L_('0');
1131 always_output_a_sign
= false;
1132 goto do_number_sign_and_padding
;
1136 if (modifier
== L_('O'))
1139 if (! (modifier
== L_('E')
1141 (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(ERA_T_FMT
)))
1143 subfmt
= (const CHAR_T
*) _NL_CURRENT (LC_TIME
, NLW(T_FMT
));
1146 goto underlying_strftime
;
1149 subfmt
= L_("%H:%M:%S");
1157 DO_NUMBER (1, (tp
->tm_wday
- 1 + 7) % 7 + 1);
1160 if (modifier
== L_('E'))
1163 DO_NUMBER (2, (tp
->tm_yday
- tp
->tm_wday
+ 7) / 7);
1168 if (modifier
== L_('E'))
1171 /* YEAR is a leap year if and only if (tp->tm_year + TM_YEAR_BASE)
1172 is a leap year, except that YEAR and YEAR - 1 both work
1173 correctly even when (tp->tm_year + TM_YEAR_BASE) would
1175 int year
= (tp
->tm_year
1177 ? TM_YEAR_BASE
% 400
1178 : TM_YEAR_BASE
% 400 - 400));
1179 int year_adjust
= 0;
1180 int days
= iso_week_days (tp
->tm_yday
, tp
->tm_wday
);
1184 /* This ISO week belongs to the previous year. */
1186 days
= iso_week_days (tp
->tm_yday
+ (365 + __isleap (year
- 1)),
1191 int d
= iso_week_days (tp
->tm_yday
- (365 + __isleap (year
)),
1195 /* This ISO week belongs to the next year. */
1205 int yy
= (tp
->tm_year
% 100 + year_adjust
) % 100;
1206 DO_NUMBER (2, (0 <= yy
1208 : tp
->tm_year
< -TM_YEAR_BASE
- year_adjust
1214 DO_SIGNED_NUMBER (4, tp
->tm_year
< -TM_YEAR_BASE
- year_adjust
,
1215 (tp
->tm_year
+ (unsigned int) TM_YEAR_BASE
1219 DO_NUMBER (2, days
/ 7 + 1);
1224 if (modifier
== L_('E'))
1227 DO_NUMBER (2, (tp
->tm_yday
- (tp
->tm_wday
- 1 + 7) % 7 + 7) / 7);
1230 if (modifier
== L_('E'))
1233 DO_NUMBER (1, tp
->tm_wday
);
1236 if (modifier
== 'E')
1238 #if HAVE_STRUCT_ERA_ENTRY
1239 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1242 # ifdef COMPILE_WIDE
1243 subfmt
= era
->era_wformat
;
1245 subfmt
= era
->era_format
;
1250 goto underlying_strftime
;
1253 if (modifier
== L_('O'))
1256 DO_SIGNED_NUMBER (4, tp
->tm_year
< -TM_YEAR_BASE
,
1257 tp
->tm_year
+ (unsigned int) TM_YEAR_BASE
);
1260 if (modifier
== L_('E'))
1262 #if HAVE_STRUCT_ERA_ENTRY
1263 struct era_entry
*era
= _nl_get_era_entry (tp HELPER_LOCALE_ARG
);
1266 int delta
= tp
->tm_year
- era
->start_date
[0];
1267 DO_NUMBER (1, (era
->offset
1268 + delta
* era
->absolute_direction
));
1271 goto underlying_strftime
;
1276 int yy
= tp
->tm_year
% 100;
1278 yy
= tp
->tm_year
< - TM_YEAR_BASE
? -yy
: yy
+ 100;
1290 /* The tzset() call might have changed the value. */
1291 if (!(zone
&& *zone
) && tp
->tm_isdst
>= 0)
1292 zone
= tzname
[tp
->tm_isdst
!= 0];
1299 /* The zone string is always given in multibyte form. We have
1300 to transform it first. */
1303 widen (zone
, wczone
, len
);
1307 cpy (strlen (zone
), zone
);
1312 /* :, ::, and ::: are valid only just before 'z'.
1313 :::: etc. are rejected later. */
1314 for (colons
= 1; f
[colons
] == L_(':'); colons
++)
1316 if (f
[colons
] != L_('z'))
1319 goto do_z_conversion
;
1325 if (tp
->tm_isdst
< 0)
1334 diff
= tp
->tm_gmtoff
;
1347 if (lt
== (time_t) -1)
1349 /* mktime returns -1 for errors, but -1 is also a
1350 valid time_t value. Check whether an error really
1354 if (! __localtime_r (<
, &tm
)
1355 || ((ltm
.tm_sec
^ tm
.tm_sec
)
1356 | (ltm
.tm_min
^ tm
.tm_min
)
1357 | (ltm
.tm_hour
^ tm
.tm_hour
)
1358 | (ltm
.tm_mday
^ tm
.tm_mday
)
1359 | (ltm
.tm_mon
^ tm
.tm_mon
)
1360 | (ltm
.tm_year
^ tm
.tm_year
)))
1364 if (! __gmtime_r (<
, >m
))
1367 diff
= tm_diff (<m
, >m
);
1371 hour_diff
= diff
/ 60 / 60;
1372 min_diff
= diff
/ 60 % 60;
1373 sec_diff
= diff
% 60;
1378 DO_TZ_OFFSET (5, diff
< 0, 0, hour_diff
* 100 + min_diff
);
1380 case 1: tz_hh_mm
: /* +hh:mm */
1381 DO_TZ_OFFSET (6, diff
< 0, 04, hour_diff
* 100 + min_diff
);
1383 case 2: tz_hh_mm_ss
: /* +hh:mm:ss */
1384 DO_TZ_OFFSET (9, diff
< 0, 024,
1385 hour_diff
* 10000 + min_diff
* 100 + sec_diff
);
1387 case 3: /* +hh if possible, else +hh:mm, else +hh:mm:ss */
1392 DO_TZ_OFFSET (3, diff
< 0, 0, hour_diff
);
1399 case L_('\0'): /* GNU extension: % at end of format. */
1403 /* Unknown format; output the format, including the '%',
1404 since this is most likely the right thing to do if a
1405 multibyte string has been misparsed. */
1409 for (flen
= 1; f
[1 - flen
] != L_('%'); flen
++)
1411 cpy (flen
, &f
[1 - flen
]);
1418 if (p
&& maxsize
!= 0)
1425 /* Write information from TP into S according to the format
1426 string FORMAT, writing no more that MAXSIZE characters
1427 (including the terminating '\0') and returning number of
1428 characters written. If S is NULL, nothing will be written
1429 anywhere, so to determine how many characters would be
1430 written, use NULL for S and (size_t) -1 for MAXSIZE. */
1432 my_strftime (STREAM_OR_CHAR_T
*s
, STRFTIME_ARG (size_t maxsize
)
1433 const CHAR_T
*format
,
1434 const struct tm
*tp extra_args_spec LOCALE_PARAM_PROTO
)
1436 return strftime_case_ (false, s
, STRFTIME_ARG (maxsize
)
1437 format
, tp extra_args LOCALE_ARG
);
1440 #if defined _LIBC && ! FPRINTFTIME
1441 libc_hidden_def (my_strftime
)
1445 #if defined emacs && ! FPRINTFTIME
1446 /* For Emacs we have a separate interface which corresponds to the normal
1447 strftime function plus the ut argument, but without the ns argument. */
1449 emacs_strftimeu (char *s
, size_t maxsize
, const char *format
,
1450 const struct tm
*tp
, int ut
)
1452 return my_strftime (s
, maxsize
, format
, tp
, ut
, 0);