[Top][All Lists]
[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
- bug in date(1), John Adams, 2005/04/04
- Re: bug in date(1),
Paul Eggert <=