On 02/11/16 15:25, Pádraig Brady wrote:
> On 06/10/16 12:53, Pádraig Brady wrote:
>> On 06/10/16 11:11, john woods wrote:
>>> date +%YW%V gives week and year; it would be nice if date +%YQ%q could
>>> return, eg 2016Q3 as having a quarters code in date would save AWKwardness
>>> or shell arithmetic.
>>>
>>> Perhaps we could have
>>> %q 1,2,3,4
> 
>> This is one of those marginal calls.
>>
>> It's not that awkward to get the quarter number: $(( ($(date +%-m)-1)/3+1 ))
>> But I agree it would be useful to give the number directly.
> 
>> Note perl Date::Format uses %q to give the quarter number, starting with 1
> 
> Attached in the gnulib portion.
> 
> I'll suggest for inclusion to glibc also.

I proposed this for glibc with little push back,
and the only significant suggestion to add to strptime()
also for consistency.  Therefore I did that in the attached,
added a test, and pushed.


thanks,
Pádraig.

>From fb7edffd0276efbfe78b3b75f420002828edd83e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <pbr...@fb.com>
Date: Wed, 19 Oct 2016 14:46:14 -0700
Subject: [PATCH] strftime,strptime: support %q to represent the quarter

* lib/strftime.c (strftime_case_): Add %q case.
* lib/strptime.c (__strptime_internal): Likewise.
* tests/test-strftime.c (quarter_test): A new test case.
---
 lib/strftime.c        |  4 ++++
 lib/strptime.c        | 18 ++++++++++++++++++
 tests/test-strftime.c | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+)

diff --git a/lib/strftime.c b/lib/strftime.c
index 4e65190..564e819 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -1115,6 +1115,10 @@ strftime_case_ (bool upcase, STREAM_OR_CHAR_T *s,
           goto underlying_strftime;
 #endif
 
+        case L_('q'):           /* GNU extension.  */
+          DO_SIGNED_NUMBER (1, tp->tm_mon < -3, tp->tm_mon / 3 + 1U);
+          break;
+
         case L_('R'):
           subfmt = L_("%H:%M");
           goto subformat;
diff --git a/lib/strptime.c b/lib/strptime.c
index f9f6d46..7cedb77 100644
--- a/lib/strptime.c
+++ b/lib/strptime.c
@@ -525,6 +525,15 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM)
                 return NULL;
             }
           break;
+        case 'q':
+          /* Match quarter of year.  GNU extension.  */
+          get_number (1, 4, 1);
+          tm->tm_mon = (val - 1) * 3;
+          tm->tm_mday = 1;
+          s.have_mon = 1;
+          s.have_mday = 1;
+          s.want_xday = 1;
+          break;
         case 'r':
 #ifdef _NL_CURRENT
           if (*decided != raw)
@@ -982,6 +991,15 @@ __strptime_internal (rp, fmt, tm, decided, era_cnt LOCALE_PARAM)
               get_alt_number (0, 59, 2);
               tm->tm_min = val;
               break;
+            case 'q':
+              /* Match quarter using alternate numeric symbols.  */
+              get_alt_number (1, 4, 1);
+              tm->tm_mon = (val - 1) * 3;
+              tm->tm_mday = 1;
+              s.have_mon = 1;
+              s.have_mday = 1;
+              s.want_xday = 1;
+              break;
             case 'S':
               /* Match seconds using alternate numeric symbols.  */
               get_alt_number (0, 61, 2);
diff --git a/tests/test-strftime.c b/tests/test-strftime.c
index 39494e6..41c1861 100644
--- a/tests/test-strftime.c
+++ b/tests/test-strftime.c
@@ -200,12 +200,48 @@ tzalloc_test (void)
   return fail;
 }
 
+
+static int
+quarter_test (void)
+{
+  int result = 0;
+  size_t mon;
+
+  /* Check %q.  */
+  for (mon = 1; mon <= 12; mon++)
+    {
+      char out[2];
+      char exp[2] = {0,};
+      struct tm qtm = { .tm_mon = mon - 1 };
+      char fmt[3] = {'%','q','\0'};
+
+      size_t r = nstrftime (out, sizeof (out), fmt, &qtm, 0, 0);
+      if (r == 0)
+        {
+          puts ("nstrftime(\"%q\") failed");
+          result = 1;
+          break;
+        }
+
+      exp[0] = mon < 4 ? '1' : mon < 7 ? '2' : mon < 10 ? '3' : '4';
+      if (strcmp (out, exp) != 0)
+        {
+          printf ("nstrftime %%q: expected \"%s\", got \"%s\"\n", exp, out);
+          result = 1;
+          break;
+        }
+    }
+
+  return result;
+}
+
 int
 main (void)
 {
   int fail = 0;
   fail |= posixtm_test ();
   fail |= tzalloc_test ();
+  fail |= quarter_test ();
   return fail;
 }
 
-- 
2.5.5

Reply via email to