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;
| day
{ pc->days_seen++; }
| rel
- { pc->rels_seen++; }
+ { pc->rels_seen = true; }
| number
;
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:
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
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;
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
*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;
}
/* 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