bug-coreutils
[Top][All Lists]
Advanced

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

Re: bug in date(1)


From: Paul Eggert
Subject: Re: bug in date(1)
Date: Mon, 04 Apr 2005 12:55:42 -0700
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.4 (gnu/linux)

John Adams <address@hidden> writes:

> Hello,
>       I found some weird behavior in the date command version 5.2.1
> date --date=
>    displays Sat Apr  2 23:00:00 EST 2005
>     while 
> date
>    displays 
> Sun Apr  3 09:56:08 EDT 2005
>
> Seems to be a bug.

Thanks for reporting that.  The empty string is supposed to stand for
the start of the current day -- that's in the documentation.  I
installed this patch, to both coreutils and gnulib.

2005-04-04  Paul Eggert  <address@hidden>

        * lib/getdate.y (parser_control): rels_seen is now a boolean, not a
        count, since there's no maximum.  All uses changed.
        Add member dsts_seen.
        (local_zone): Accumulate dsts_seen rather than relying on tm_isdst
        not being INT_MAX.
        (get_date): Initialize dsts_seen, and check that it doesn't go over 1.
        Use pc_rels_seen to decide whther a date is absolute.

        * lib/getdate.y (number): Don't overwrite year.
        (get_date): Initialize pc.year.digits to 0, not 4, to enable above
        check.

--- lib/getdate.y       21 Feb 2005 08:08:38 -0000      1.95
+++ lib/getdate.y       4 Apr 2005 19:47:42 -0000
@@ -175,12 +175,13 @@ typedef struct
   long int rel_seconds;
   long int rel_ns;
 
-  /* Counts of nonterminals of various flavors parsed so far.  */
+  /* Presence or counts of nonterminals of various flavors parsed so far.  */
   bool timespec_seen;
+  bool rels_seen;
   size_t dates_seen;
   size_t days_seen;
   size_t local_zones_seen;
-  size_t rels_seen;
+  size_t dsts_seen;
   size_t times_seen;
   size_t zones_seen;
 
@@ -255,7 +256,7 @@ item:
   | day
       { pc->days_seen++; }
   | rel
-      { pc->rels_seen++; }
+      { pc->rels_seen = true; }
   | number
   ;
 
@@ -306,9 +307,15 @@ time:
 
 local_zone:
     tLOCAL_ZONE
-      { pc->local_isdst = $1; }
+      {
+       pc->local_isdst = $1;
+       pc->dsts_seen += (0 < $1);
+      }
   | tLOCAL_ZONE tDST
-      { pc->local_isdst = $1 < 0 ? 1 : $1 + 1; }
+      {
+       pc->local_isdst = 1;
+       pc->dsts_seen += (0 < $1) + 1;
+      }
   ;
 
 zone:
@@ -504,7 +511,7 @@ unsigned_seconds:
 number:
     tUNUMBER
       {
-       if (pc->dates_seen
+       if (pc->dates_seen && ! pc->year.digits
            && ! pc->rels_seen && (pc->times_seen || 2 < $1.digits))
          pc->year = $1;
        else
@@ -1179,7 +1186,7 @@ get_date (struct timespec *result, char 
   pc.input = p;
   pc.year.value = tmp->tm_year;
   pc.year.value += TM_YEAR_BASE;
-  pc.year.digits = 4;
+  pc.year.digits = 0;
   pc.month = tmp->tm_mon + 1;
   pc.day = tmp->tm_mday;
   pc.hour = tmp->tm_hour;
@@ -1197,11 +1204,12 @@ get_date (struct timespec *result, char 
   pc.rel_month = 0;
   pc.rel_year = 0;
   pc.timespec_seen = false;
+  pc.rels_seen = false;
   pc.dates_seen = 0;
   pc.days_seen = 0;
-  pc.rels_seen = 0;
   pc.times_seen = 0;
   pc.local_zones_seen = 0;
+  pc.dsts_seen = 0;
   pc.zones_seen = 0;
 
 #if HAVE_STRUCT_TM_TM_ZONE
@@ -1269,9 +1277,8 @@ get_date (struct timespec *result, char 
     *result = pc.seconds;
   else
     {
-      if (1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
-         || 1 < (pc.local_zones_seen + pc.zones_seen)
-         || (pc.local_zones_seen && 1 < pc.local_isdst))
+      if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen
+              | (pc.local_zones_seen + pc.zones_seen)))
        goto fail;
 
       tm.tm_year = to_year (pc.year) - TM_YEAR_BASE;
@@ -1292,7 +1299,7 @@ get_date (struct timespec *result, char 
        }
 
       /* Let mktime deduce tm_isdst if we have an absolute time stamp.  */
-      if (pc.dates_seen | pc.days_seen | pc.times_seen)
+      if (!pc.rels_seen)
        tm.tm_isdst = -1;
 
       /* But if the input explicitly specifies local time with or without




reply via email to

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