Re: Fw: [PATCH 1/2] strftime.c(__strftime): add %i, %q, %v, tests; tweak %Z docs

Brian Inglis <[email protected]>
Newsgroups gmane.comp.lib.newlib
Organization Systematic Software
Message-ID <[email protected]>
On 2022-10-18 08:03, Corinna Vinschen wrote:
> On Sep 19 11:51, C Howland wrote:
>> On Saturday, September 17, 2022 1:00 AM, Brian Inglis wrote:
>>> newlib/libc/time/strftime.c(__strftime):
>>> %i year in century [00..99] Synonym for "%y". Non-POSIX extension.
>>> [tm_year]
>>> %q GNU quarter of the year (from `<<1>>' to `<<4>>') [tm_mon]
>>> %v OSX/Ruby VMS/Oracle date "%d-%b-%Y". Non-POSIX extension. [tm_mday,
>>> tm_mon, tm_year]
>>> add %i %q %v tests
>>> %Z clarify current time zone *abbreviation* not "name" [tm_isdst]
>>> ---
>>>   newlib/libc/time/strftime.c | 67 +++++++++++++++++++++++++++++++++++--
>>>   1 file changed, 64 insertions(+), 3 deletions(-)

> - %i: Where is used and documented?  I don't see this in glibc, not even
>    in the latest from the glibc git repo.

Some portable language implementations for non-Unix platforms that I came across 
and documented but did not keep track of, and now can't find!

> - %q: Ditto. For a GNU extension, it's surprisingly absent from the
>    most recent glibc code, or do I miss something?

Looks like this may have been lost in the discussion:

https://inbox.sourceware.org/libc-alpha/[email protected]/

but as he says, it was already in gnulib, and made it into date the same month:

https://git.savannah.gnu.org/cgit/coreutils.git/diff/?id=30012b290facf66551cdf395ace397903d00483d

also in Perl and ksh93 printf %(...)T.

> - %v: OSX/Ruby?  Isn't that already gone?  Also, it introduces another
>    ambiguous date format where %F or equivalent should be used instead.

All the BSDs, Darwin, Oracle, and Ruby support it: it is localized, but not 
ambiguous, as it's dd-Mon-yyyy.

> It's nice to add features, but it wouldn't hurt to have some
> clarification and justification if it's non-standard stuff.
> Availability in glibc or in the BSDs is typically justification enough,
> but I don't see this here.

See attached sh and log for doc and code searches.

-- 
Take care. Thanks, Brian Inglis			Calgary, Alberta, Canada

La perfection est atteinte			Perfection is achieved
non pas lorsqu'il n'y a plus rien à ajouter	not when there is no more to add
mais lorsqu'il n'y a plus rien à retirer	but when there is no more to cut
			-- Antoine de Saint-Exupéry
date-iqv.sh (text/plain, 639 B)
#!/bin/bash
# date-iqv.sh

echo "$ man date | grep \"'[iqv]'\|%[iqv]\""
man date | grep "'[iqv]'\|%[iqv]"

echo "$ perldoc Date::Format | grep \"'[iqv]'\|%[iqv]\""
perldoc Date::Format | grep "'[iqv]'\|%[iqv]"

echo "$ ri Date.strftime | grep \"'[iqv]'\|%[iqv]\""
ri Date.strftime | grep "'[iqv]'\|%[iqv]"

echo "$ grep -A8 \"'[iqv]'\|%[iqv]\" ../{BSD/*BSD,cygwin/coreutils/coreutils-9.0-?.x*/origsrc/coreutils-9.0/*,glibc/time,gnulib/lib,musl/time}/*{date,{str,wcs}[fp]time}*"
grep -A8 "'[iqv]'\|%[iqv]" ../{BSD/*BSD,cygwin/coreutils/coreutils-9.0-?.x*/origsrc/coreutils-9.0/*,glibc/time,gnulib/lib,musl/time}/*{date,{str,wcs}[fp]time}*
date-iqv.log (text/plain, 12.8 KB)
$ man date | grep "'[iqv]'\|%[iqv]"
       %q     quarter of year (1..4)
$ perldoc Date::Format | grep "'[iqv]'\|%[iqv]"
            %q      Quarter number, starting with 1
    %d, %e, %H, %I, %j, %k, %l, %m, %M, %q, %y and %Y can be output in Roman
$ ri Date.strftime | grep "'[iqv]'\|%[iqv]"
    %v - VMS date (%e-%b-%Y)
$ grep -A8 "'[iqv]'\|%[iqv]" ../{BSD/*BSD,cygwin/coreutils/coreutils-9.0-?.x*/origsrc/coreutils-9.0/*,glibc/time,gnulib/lib,musl/time}/*{date,{str,wcs}[fp]time}*
../BSD/FreeBSD/strftime.c:			case 'v':
../BSD/FreeBSD/strftime.c-				/*
../BSD/FreeBSD/strftime.c-				 * From Arnold Robbins' strftime version 3.0:
../BSD/FreeBSD/strftime.c-				 * "date as dd-bbb-YYYY"
../BSD/FreeBSD/strftime.c-				 * (ado, 1993-05-24)
../BSD/FreeBSD/strftime.c-				 */
../BSD/FreeBSD/strftime.c-				pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, loc);
../BSD/FreeBSD/strftime.c-				continue;
../BSD/FreeBSD/strftime.c-			case 'W':
--
../BSD/NetBSD/strftime.c:			case 'v':
../BSD/NetBSD/strftime.c-				/*
../BSD/NetBSD/strftime.c-				** From Arnold Robbins' strftime version 3.0:
../BSD/NetBSD/strftime.c-				** "date as dd-bbb-YYYY"
../BSD/NetBSD/strftime.c-				** (ado, 1993-05-24)
../BSD/NetBSD/strftime.c-				*/
../BSD/NetBSD/strftime.c-				pt = _fmt(sp, "%e-%b-%Y", t, pt, ptlim, warnp,
../BSD/NetBSD/strftime.c-				    loc);
../BSD/NetBSD/strftime.c-				continue;
--
../BSD/OpenBSD/strftime.c:			case 'v':
../BSD/OpenBSD/strftime.c-				/*
../BSD/OpenBSD/strftime.c-				** From Arnold Robbins' strftime version 3.0:
../BSD/OpenBSD/strftime.c-				** "date as dd-bbb-YYYY"
../BSD/OpenBSD/strftime.c-				** (ado, 1993-05-24)
../BSD/OpenBSD/strftime.c-				*/
../BSD/OpenBSD/strftime.c-				pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
../BSD/OpenBSD/strftime.c-				continue;
../BSD/OpenBSD/strftime.c-			case 'W':
--
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1:%q
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1-quarter of year (1..4)
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1-.TP
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1-%r
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1-locale's 12\-hour clock time (e.g., 11:11:04 PM)
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1-.TP
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1-%R
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1-24\-hour hour and minute; same as %H:%M
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/man/date.1-.TP
--
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c:  %q   quarter of year (1..4)\n\
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c-  %r   locale's 12-hour clock time (e.g., 11:11:04 PM)\n\
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c-  %R   24-hour hour and minute; same as %H:%M\n\
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c-  %s   seconds since the Epoch (1970-01-01 00:00 UTC)\n\
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c-"), stdout);
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c-      fputs (_("\
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c-  %S   second (00..60)\n\
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c-  %t   a tab\n\
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/src/date.c-  %T   time; same as %H:%M:%S\n\
--
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c:  /* Check %q.  */
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-  for (mon = 1; mon <= 12; mon++)
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-    {
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-      char out[2];
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-      char exp[2] = {0,};
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-      struct tm qtm = { .tm_mon = mon - 1 };
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c:      char fmt[3] = {'%','q','\0'};
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-      size_t r = nstrftime (out, sizeof (out), fmt, &qtm, 0, 0);
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-      if (r == 0)
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-        {
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c:          puts ("nstrftime(\"%q\") failed");
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-          result = 1;
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-          break;
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-        }
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-      exp[0] = mon < 4 ? '1' : mon < 7 ? '2' : mon < 10 ? '3' : '4';
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-      if (strcmp (out, exp) != 0)
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-        {
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c:          printf ("nstrftime %%q: expected \"%s\", got \"%s\"\n", exp, out);
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-          result = 1;
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-          break;
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-        }
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-    }
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-  return result;
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-}
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/gnulib-tests/test-nstrftime.c-
--
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c:        case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-        case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c:        case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c:        case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-        case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-        case L_('~'):
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-          /* The C Standard requires these 98 characters (plus '%') to
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-             be in the basic execution character set.  None of these
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-             characters can start a multibyte sequence, so they need
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-             not be analyzed further.  */
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-          add1 (*f);
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-          continue;
--
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c:        case L_('q'):           /* GNU extension.  */
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-          DO_SIGNED_NUMBER (1, false, ((tp->tm_mon * 11) >> 5) + 1);
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-          break;
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-        case L_('R'):
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-          subfmt = L_("%H:%M");
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-          goto subformat;
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-
../cygwin/coreutils/coreutils-9.0-1.x86_64/origsrc/coreutils-9.0/lib/nstrftime.c-        case L_('r'):
--
../glibc/time/strftime_l.c:	case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
../glibc/time/strftime_l.c-	case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
../glibc/time/strftime_l.c:	case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
../glibc/time/strftime_l.c:	case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
../glibc/time/strftime_l.c-	case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
../glibc/time/strftime_l.c-	case L_('~'):
../glibc/time/strftime_l.c-	  /* The C Standard requires these 98 characters (plus '%') to
../glibc/time/strftime_l.c-	     be in the basic execution character set.  None of these
../glibc/time/strftime_l.c-	     characters can start a multibyte sequence, so they need
../glibc/time/strftime_l.c-	     not be analyzed further.  */
../glibc/time/strftime_l.c-	  add (1, *p = *f);
../glibc/time/strftime_l.c-	  continue;
--
../gnulib/lib/nstrftime.c:        case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'):
../gnulib/lib/nstrftime.c-        case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'):
../gnulib/lib/nstrftime.c:        case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'):
../gnulib/lib/nstrftime.c:        case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'):
../gnulib/lib/nstrftime.c-        case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'):
../gnulib/lib/nstrftime.c-        case L_('~'):
../gnulib/lib/nstrftime.c-          /* The C Standard requires these 98 characters (plus '%') to
../gnulib/lib/nstrftime.c-             be in the basic execution character set.  None of these
../gnulib/lib/nstrftime.c-             characters can start a multibyte sequence, so they need
../gnulib/lib/nstrftime.c-             not be analyzed further.  */
../gnulib/lib/nstrftime.c-          add1 (*f);
../gnulib/lib/nstrftime.c-          continue;
--
../gnulib/lib/nstrftime.c:        case L_('q'):           /* GNU extension.  */
../gnulib/lib/nstrftime.c-          DO_SIGNED_NUMBER (1, false, ((tp->tm_mon * 11) >> 5) + 1);
../gnulib/lib/nstrftime.c-
../gnulib/lib/nstrftime.c-        case L_('R'):
../gnulib/lib/nstrftime.c-          subfmt = L_("%H:%M");
../gnulib/lib/nstrftime.c-          goto subformat;
../gnulib/lib/nstrftime.c-
../gnulib/lib/nstrftime.c-        case L_('r'):
../gnulib/lib/nstrftime.c-#ifdef _NL_CURRENT
--
../gnulib/lib/strptime.c:        case 'q':
../gnulib/lib/strptime.c-          /* Match quarter of year.  GNU extension.  */
../gnulib/lib/strptime.c-          get_number (1, 4, 1);
../gnulib/lib/strptime.c-          tm->tm_mon = (val - 1) * 3;
../gnulib/lib/strptime.c-          tm->tm_mday = 1;
../gnulib/lib/strptime.c-          have_mon = 1;
../gnulib/lib/strptime.c-          have_mday = 1;
../gnulib/lib/strptime.c-          want_xday = 1;
../gnulib/lib/strptime.c-          break;
--
../gnulib/lib/strptime.c:            case 'q':
../gnulib/lib/strptime.c-              /* Match quarter using alternate numeric symbols.  */
../gnulib/lib/strptime.c-              get_alt_number (1, 4, 1);
../gnulib/lib/strptime.c-              tm->tm_mon = (val - 1) * 3;
../gnulib/lib/strptime.c-              tm->tm_mday = 1;
../gnulib/lib/strptime.c-              have_mon = 1;
../gnulib/lib/strptime.c-              have_mday = 1;
../gnulib/lib/strptime.c-              want_xday = 1;
../gnulib/lib/strptime.c-              break;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.