make date parsing portable, take 2
the global timezone variable is glibc-specific.
so use timegm() instead of mktime() for the conversion.
as that is specific to the BSDs and glibc, provide a fallback.
amends 62a6099
.
This commit is contained in:
parent
6d2fd370a6
commit
aee0fa3b68
|
@ -29,7 +29,7 @@ if test "x$ob_cv_strftime_z" = x"no"; then
|
|||
fi
|
||||
|
||||
AC_CHECK_HEADERS(sys/poll.h sys/select.h)
|
||||
AC_CHECK_FUNCS(vasprintf memrchr)
|
||||
AC_CHECK_FUNCS(vasprintf memrchr timegm)
|
||||
|
||||
AC_CHECK_LIB(socket, socket, [SOCK_LIBS="-lsocket"])
|
||||
AC_CHECK_LIB(nsl, inet_ntoa, [SOCK_LIBS="$SOCK_LIBS -lnsl"])
|
||||
|
|
|
@ -94,6 +94,11 @@ void free_string_list( string_list_t *list );
|
|||
void *memrchr( const void *s, int c, size_t n );
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_TIMEGM
|
||||
# include <time.h>
|
||||
time_t timegm( struct tm *tm );
|
||||
#endif
|
||||
|
||||
void *nfmalloc( size_t sz );
|
||||
void *nfcalloc( size_t sz );
|
||||
void *nfrealloc( void *mem, size_t sz );
|
||||
|
|
|
@ -835,11 +835,11 @@ parse_date( const char *str )
|
|||
memset( &datetime, 0, sizeof(datetime) );
|
||||
if (!(end = strptime( str, "%d-%b-%Y %H:%M:%S ", &datetime )))
|
||||
return -1;
|
||||
if ((date = mktime( &datetime )) == -1)
|
||||
if ((date = timegm( &datetime )) == -1)
|
||||
return -1;
|
||||
if (sscanf( end, "%3d%2d", &hours, &mins ) != 2)
|
||||
return -1;
|
||||
return date - (hours * 60 + mins) * 60 - timezone;
|
||||
return date - (hours * 60 + mins) * 60;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
65
src/util.c
65
src/util.c
|
@ -203,6 +203,71 @@ memrchr( const void *s, int c, size_t n )
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_TIMEGM
|
||||
/*
|
||||
Converts struct tm to time_t, assuming the data in tm is UTC rather
|
||||
than local timezone.
|
||||
|
||||
mktime is similar but assumes struct tm, also known as the
|
||||
"broken-down" form of time, is in local time zone. timegm
|
||||
uses mktime to make the conversion understanding that an offset
|
||||
will be introduced by the local time assumption.
|
||||
|
||||
mktime_from_utc 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 <beeman@cisco.com>, with the help of
|
||||
Mark Baushke <mdb@cisco.com> and the rest of the Gurus at CISCO.
|
||||
Further improved by Roger with assistance from Edward J. Sabol
|
||||
based on input by Jamie Zawinski.
|
||||
*/
|
||||
|
||||
static time_t
|
||||
my_mktime( struct tm *t )
|
||||
{
|
||||
time_t tl = mktime( t );
|
||||
if (tl == -1) {
|
||||
t->tm_hour--;
|
||||
tl = mktime( t );
|
||||
if (tl != -1)
|
||||
tl += 3600;
|
||||
}
|
||||
return tl;
|
||||
}
|
||||
|
||||
time_t
|
||||
timegm( struct tm *t )
|
||||
{
|
||||
time_t tl, tb;
|
||||
struct tm *tg;
|
||||
|
||||
if ((tl = my_mktime( t )) == -1)
|
||||
return tl;
|
||||
tg = gmtime( &tl );
|
||||
tg->tm_isdst = 0;
|
||||
if ((tb = my_mktime( tg )) == -1)
|
||||
return tb;
|
||||
return tl - (tb - tl);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
oob( void )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user