inconsistent handling of flags with nstrftime formats
Pádraig Brady <[email protected]>
| Newsgroups | gmane.comp.lib.gnulib.bugs |
|---|---|
| Message-ID | <[email protected]> |
The following are understandable/consistent: # Y (unlike glibc) defaults to 04Y $ date -d '1-2-3' +[%Y] [0001] # A flag can override that $ date -d '1-2-3' +[%_Y] [ 1] # The compound %D is %m/%d/%y $ date -d '1-2-3' +[%D] [02/03/01] $ The compound %F is %+4Y-%m-%d $ date -d '1-2-3' +[%F] [0001-02-03] So far so good. But what about flags on compound specifiers? I would expect them to propagate to the sub formats. But they don't on glibc, and are essentially ignored. That's a bit surprising, but consistent. E.g. glibc strftime() produces: %D [02/03/01] %_D [02/03/01] %-D [02/03/01] %10D [ 02/03/01] %_10D [ 02/03/01] %010D [0003/03/01] %-10D [ 02/03/01] %F [1-02-03] %_F [1-02-03] %-F [1-02-03] Still consistent so far. But with gnulib since commit 188d87b051 introducing support for the POSIX¹ '+' flag, all flags are now propagated to just the year component: $ date -d '1-2-3' +[%_D] [02/03/ 1] $ date -d "1-2-3" "+[%-D]" [02/03/1] That seems confusing and inconsistent to me (for the first 9 years of each century at least). I.e. these flags propagate to the %y sub specifier, but not the %m or %d. Note all these specifiers support these flags in isolation: $ date -d "1-2-3" "+%-y/%-m/%-d" 1/2/3 To make this consistent we could either: 1. Propagate flags to all sub specifiers 2. Ignore these glibc [_-] flags in all sub specifiers 1. would be more consistent with the '+' flag, and in my reading, the POSIX intent of propagating compound flags to sub specifiers 2. would be more consistent with glibc's strftime() output. Note glibc strftime() still doesn't support the POSIX '+' flag. Attached is a quick patch for discussion to effect option 2. cheers, Padraig ¹ https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/strftime.html
gnulib-strftime-compound-year-flag.diff
(text/x-patch, 2 KB)
diff --git a/lib/strftime.c b/lib/strftime.c
index 5a3544674e..f92fff90f5 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -1641,11 +1641,14 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
subwidth = -1;
subformat_width:
{
+ enum pad_style subpad =
+ (format_char == L_('F') || format_char == L_('Y')
+ ? pad : yr_spec);
retval_t len =
__strftime_internal (NULL, STRFTIME_ARG ((size_t) -1)
subfmt, tp,
CAL_ARGS (cal, caldate)
- to_uppcase, pad, subwidth,
+ to_uppcase, subpad, subwidth,
tzset_called
extra_args LOCALE_ARG);
if (FAILURE < 0 && len < 0)
@@ -1654,7 +1657,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
STRFTIME_ARG (maxsize - i)
subfmt, tp,
CAL_ARGS (cal, caldate)
- to_uppcase, pad, subwidth,
+ to_uppcase, subpad, subwidth,
tzset_called
extra_args LOCALE_ARG));
}
diff --git a/tests/test-nstrftime.h b/tests/test-nstrftime.h
index 7ab38b40c5..64a007b521 100644
--- a/tests/test-nstrftime.h
+++ b/tests/test-nstrftime.h
@@ -50,6 +50,8 @@ struct posixtm_test
static struct posixtm_test const T[] =
{
{ 1300000000, 0, "%F", "2011-03-13" },
+ { 1086393600, 0, "%_D", "06/05/04" },
+ { 1086393600, 0, "%-D", "06/05/04" },
{ 0, 10, "%T.%N", "00:00:00.000000010" },
{ 56, 123456789, "%T.%12N", "00:00:56.123456789000" },
{ 0, 123000000, "%T.%_6N", "00:00:00.123 " },