bug-sh-utils
[Top][All Lists]
Advanced

[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 
mktime():

/usr/src/RPM/BUILD/sh-utils-2.0/lib
address@hidden 566 $ cc -DTEST getdate.c
/usr/src/RPM/BUILD/sh-utils-2.0/lib
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 
tm.tm_isdst,
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]