bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: date issues with YYYYMMDD/YYMMDD date format and relative offset


From: Jim Meyering
Subject: Re: date issues with YYYYMMDD/YYMMDD date format and relative offset
Date: Thu, 22 Nov 2007 22:22:07 +0100

Ondřej Vašík <address@hidden> wrote:
...
> I improved previous patch, created hybrid section - as is more clean
> to have such things out of common sections (maybe same thing from "zone"
> section should be moved here - of course with pc->zones_seen++) and used
> the same code as is in "number" section + relative signed offset code.
>
> This should solve your objection. Is the patch now acceptable?

Hi Ondřej,

Almost.  There was too much duplication, no ChangeLog entry,
and no test case.  I've taken care of those.  FYI, here is a patch
adding two tests to coreutils:

diff --git a/tests/misc/date b/tests/misc/date
index 7408ea2..838c54a 100755
--- a/tests/misc/date
+++ b/tests/misc/date
@@ -134,6 +134,11 @@ my @Tests =
      ['next-mo', "-d '$d1 next month' '+%Y-%m-%d %T'", {OUT=>"$dm $t0"}],
      ['next-y', "-d '$d1 next year'   '+%Y-%m-%d %T'", {OUT=>"$dy $t0"}],

+     # This has always worked, ...
+     ['rel-1',  "-d '20050101  1 day'  +%F", {OUT=>"2005-01-02"}],
+     # ...but up to coreutils-6.9, this was rejected due to the "+".
+     ['rel-1p', "-d '20050101 +1 day'  +%F", {OUT=>"2005-01-02"}],
+
      ['utc-0', "-u -d '08/01/97 6:00' '+%D,%H:%M'", {OUT=>"08/01/97,06:00"},
               {ENV => 'TZ=UTC+4'}],

And here's the part that affects gnulib.  I'll wait for Paul to
give feedback, since he's listed as the owner of the getdate module.
Once the gnulib change goes in, I'll add the coreutils tests.

+2007-11-22  Ondřej Vašík  <address@hidden>
+       and Jim Meyering  <address@hidden>
+
+       Adjust getdate' grammar to accept a slightly more regular language.
+       E.g., accept "YYYYMMDD +N days" as well as "YYYYMMDD N days".
+       Before, the former was rejected.
+       * lib/getdate.y (digits_to_date_time): New function, factored
+       out of ...
+       (number): ...here.  Just call digits_to_date_time.
+       (hybrid): New non-terminal to handle an <unsigned number,
+       signed relative offset> sequence consistently.
+
 2007-11-18  Jim Meyering  <address@hidden>

        Pull my changes from coreutils:
diff --git a/lib/getdate.y b/lib/getdate.y
index 591c7f0..e292f5e 100644
--- a/lib/getdate.y
+++ b/lib/getdate.y
@@ -208,6 +208,45 @@ static int yylex (union YYSTYPE *, parser_control *);
 static int yyerror (parser_control const *, char const *);
 static long int time_zone_hhmm (textint, long int);

+/* Extract into *PC any date and time info from a string of digits
+   of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,
+   YYYY, ...).  */
+static void
+digits_to_date_time (parser_control *pc, textint text_int)
+{
+  if (pc->dates_seen && ! pc->year.digits
+      && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits))
+    pc->year = text_int;
+  else
+    {
+      if (4 < text_int.digits)
+       {
+         pc->dates_seen++;
+         pc->day = text_int.value % 100;
+         pc->month = (text_int.value / 100) % 100;
+         pc->year.value = text_int.value / 10000;
+         pc->year.digits = text_int.digits - 4;
+       }
+      else
+       {
+         pc->times_seen++;
+         if (text_int.digits <= 2)
+           {
+             pc->hour = text_int.value;
+             pc->minutes = 0;
+           }
+         else
+           {
+             pc->hour = text_int.value / 100;
+             pc->minutes = text_int.value % 100;
+           }
+         pc->seconds.tv_sec = 0;
+         pc->seconds.tv_nsec = 0;
+         pc->meridian = MER24;
+       }
+    }
+}
+
 %}

 /* We want a reentrant parser, even if the TZ manipulation and the calls to
@@ -277,6 +316,7 @@ item:
   | rel
       { pc->rels_seen = true; }
   | number
+  | hybrid
   ;

 time:
@@ -552,38 +592,23 @@ unsigned_seconds:

 number:
     tUNUMBER
+      { digits_to_date_time (pc, $1); }
+  ;
+
+hybrid:
+    tUNUMBER relunit_snumber
       {
-       if (pc->dates_seen && ! pc->year.digits
-           && ! pc->rels_seen && (pc->times_seen || 2 < $1.digits))
-         pc->year = $1;
-       else
-         {
-           if (4 < $1.digits)
-             {
-               pc->dates_seen++;
-               pc->day = $1.value % 100;
-               pc->month = ($1.value / 100) % 100;
-               pc->year.value = $1.value / 10000;
-               pc->year.digits = $1.digits - 4;
-             }
-           else
-             {
-               pc->times_seen++;
-               if ($1.digits <= 2)
-                 {
-                   pc->hour = $1.value;
-                   pc->minutes = 0;
-                 }
-               else
-                 {
-                   pc->hour = $1.value / 100;
-                   pc->minutes = $1.value % 100;
-                 }
-               pc->seconds.tv_sec = 0;
-               pc->seconds.tv_nsec = 0;
-               pc->meridian = MER24;
-             }
-         }
+       /* Hybrid all-digit and relative offset, so that we accept e.g.,
+          "YYYYMMDD +N days" as well as "YYYYMMDD N days".  */
+       digits_to_date_time (pc, $1);
+       pc->rel.ns += $2.ns;
+       pc->rel.seconds += $2.seconds;
+       pc->rel.minutes += $2.minutes;
+       pc->rel.hour += $2.hour;
+       pc->rel.day += $2.day;
+       pc->rel.month += $2.month;
+       pc->rel.year += $2.year;
+       pc->rels_seen = true;
       }
   ;

--
1.5.3.6.736.gb7f30




reply via email to

[Prev in Thread] Current Thread [Next in Thread]