[Top][All Lists]

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

Re: Bugs in GNU date (sh-utils package)

From: David J. MacKenzie
Subject: Re: Bugs in GNU date (sh-utils package)
Date: Wed, 04 Apr 2001 20:56:01 -0400

> There is a bug in the GNU date program.  If this week is a new month and you
> look for the date for last friday (last month), it will give you a day
> earlier (which is the wrong date).  If this week has the same month as last
> week, then the output is correct.

Interesting.  It's not just for Friday, either; only Monday through Wednesday
are correct on today, a Wednesday.  The problem is in getdate.y, and appears to
be due to the Daylight Savings Time cutover intervening.
I can reproduce the problem on both Linux and BSD/OS using their native 

address@hidden 566 $ cc -DTEST getdate.c
address@hidden 567 $ ./a.out
Enter date, or blank line to exit.
        > last friday
Thu Mar 29 23:00:00 2001

I see some lint in that the type for "last" in OtherTable is tUNUMBER
although the value is signed (-1), but nothing seems to depend on the value
of yyDayOrdinal being unsigned, so those two bugs cancel out.

The bug you've reported is in this calculation in get_date():
  if (yyHaveDay && !yyHaveDate)
      tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7
                     + 7 * (yyDayOrdinal - (0 < yyDayOrdinal)));
      Start = mktime (&tm);
      if (Start == (time_t) -1)
        return Start;
Here, yyDayNumber is 0-6 and yyDayOrdinal is -1, which is what "last" 
translates to
in the lexer.  mktime() has already been called at least once, setting 
but now we're changing the day so we need to reset it to -1 meaning unknown.

The fix is:

--- getdate.y.save      Sat Aug  7 05:39:05 1999
+++ getdate.y   Wed Apr  4 20:49:09 2001
@@ -998,6 +998,7 @@
       tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7
                     + 7 * (yyDayOrdinal - (0 < yyDayOrdinal)));
+      tm.tm_isdst = -1;
       Start = mktime (&tm);
       if (Start == (time_t) -1)
        return Start;

reply via email to

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