Newer
Older
}
else
{
tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
}
tm.tm_hour += cookie.yyRelHour;
tm.tm_min += cookie.yyRelMinutes;
tm.tm_sec += cookie.yyRelSeconds;
/* Let mktime deduce tm_isdst if we have an absolute timestamp,
or if the relative timestamp mentions days, months, or years. */
if (cookie.yyHaveDate | cookie.yyHaveDay | cookie.yyHaveTime |
cookie.yyRelDay | cookie.yyRelMonth | cookie.yyRelYear)
tm.tm_isdst = -1;
tm0 = tm;
Start = mktime (&tm);
if (Start == (time_t) -1)
{
/* Guard against falsely reporting errors near the time_t boundaries
when parsing times in other time zones. For example, if the min
time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
of UTC, then the min localtime value is 1970-01-01 08:00:00; if
we apply mktime to 1970-01-01 00:00:00 we will get an error, so
we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
zone by 24 hours to compensate. This algorithm assumes that
there is no DST transition within a day of the time_t boundaries. */
{
tm = tm0;
if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
{
tm.tm_mday++;
}
Start = mktime (&tm);
}
if (Start == (time_t) -1)
return Start;
}
if (cookie.yyHaveDay && !cookie.yyHaveDate)
tm.tm_mday += ((cookie.yyDayNumber - tm.tm_wday + 7) % 7
+ 7 * (cookie.yyDayOrdinal - (0 < cookie.yyDayOrdinal)));
Start = mktime (&tm);
if (Start == (time_t) -1)
return Start;
}
struct tm *gmt;
#ifdef HAVE_GMTIME_R
/* thread-safe version */
struct tm keeptime2;
gmt = (struct tm *)gmtime_r(&Start, &keeptime2);
#else
gmt = gmtime(&Start);
#endif
delta = cookie.yyTimezone * 60L + difftm (&tm, gmt);
if ((Start + delta < Start) != (delta < 0))
return -1; /* time_t overflow */
Start += delta;
}
return Start;
}