1
0
mirror of https://github.com/mirror/wget.git synced 2025-02-28 12:50:22 +08:00

[svn] A new timegm implementation.

This commit is contained in:
hniksic 2005-07-05 03:26:57 -07:00
parent cca63ff3f1
commit 1ebb66269f
2 changed files with 31 additions and 53 deletions

View File

@ -1,3 +1,8 @@
2005-07-05 Hrvoje Niksic <hniksic@xemacs.org>
* cmpt.c (timegm): Don't call mktime; simply count the seconds
between 1970-01-01 and the specified date.
2005-07-05 Hrvoje Niksic <hniksic@xemacs.org> 2005-07-05 Hrvoje Niksic <hniksic@xemacs.org>
* wget.h (or): Define HAVE_SSL when either HAVE_OPENSSL or * wget.h (or): Define HAVE_SSL when either HAVE_OPENSSL or

View File

@ -1226,64 +1226,37 @@ fnmatch (const char *pattern, const char *string, int flags)
possibly elsewhere. */ possibly elsewhere. */
/* Inverse of gmtime: converts struct tm to time_t, assuming the data /* Inverse of gmtime: converts struct tm to time_t, assuming the data
in tm is UTC rather than local timezone. in tm is UTC rather than local timezone. This implementation
returns the number of seconds since 1070-01-01, converted to
time_t. */
mktime is similar but assumes struct tm, also known as the #define IS_LEAP(year) \
"broken-down" form of time, is in local time zone. This ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
implementation of timegm uses mktime to make the conversion
understanding that an offset will be introduced by the local time
assumption.
It then measures the introduced offset by applying gmtime to the
initial result and applying mktime to the resulting "broken-down"
form. The difference between the two mktime results is the
measured offset which is then subtracted from the initial mktime
result to yield a calendar time which is the value returned.
tm_isdst in struct tm is set to 0 to force mktime to introduce a
consistent offset (the non DST offset) since tm and tm+o might be
on opposite sides of a DST change.
Some implementations of mktime return -1 for the nonexistent
localtime hour at the beginning of DST. In this event, use
mktime(tm - 1hr) + 3600.
Schematically
mktime(tm) --> t+o
gmtime(t+o) --> tm+o
mktime(tm+o) --> t+2o
t+o - (t+2o - t+o) = t
Contributed by Roger Beeman, with the help of Mark Baushke and
other experts at CISCO. Further improved by Roger with assistance
from Edward J. Sabol based on input by Jamie Zawinski. */
time_t time_t
timegm (struct tm *t) timegm (struct tm *t)
{ {
time_t tl, tb; static const unsigned short int month_to_days[][13] = {
struct tm *tg; { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
};
unsigned long secs;
int year, days;
tl = mktime (t); /* Only handles years between 1970 and 2099. */
if (tl == -1) if (t->tm_year < 70 || t->tm_year > 129)
{ return (time_t) -1;
t->tm_hour--;
tl = mktime (t); days = 365 * (t->tm_year - 70);
if (tl == -1) /* Take into account the leap days between 1970 and YEAR-1; all
return -1; /* can't deal with contents of T */ years divisible by four between 1968 and 2100 should be leap. */
tl += 3600; days += (t->tm_year - 1 - 68) / 4;
} if (t->tm_mon < 0 || t->tm_mon >= 12)
tg = gmtime (&tl); return (time_t) -1;
tg->tm_isdst = 0; days += month_to_days[IS_LEAP (1900 + t->tm_year)][t->tm_mon];
tb = mktime (tg); days += t->tm_mday - 1;
if (tb == -1)
{ secs = days * 86400 + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec;
tg->tm_hour--; return (time_t) secs;
tb = mktime (tg);
if (tb == -1)
return -1; /* can't deal with output from gmtime */
tb += 3600;
}
return (tl - (tb - tl));
} }
#endif /* HAVE_TIMEGM */ #endif /* HAVE_TIMEGM */