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
|
fi
|
||||||
|
|
||||||
AC_CHECK_HEADERS(sys/poll.h sys/select.h)
|
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(socket, socket, [SOCK_LIBS="-lsocket"])
|
||||||
AC_CHECK_LIB(nsl, inet_ntoa, [SOCK_LIBS="$SOCK_LIBS -lnsl"])
|
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 );
|
void *memrchr( const void *s, int c, size_t n );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_TIMEGM
|
||||||
|
# include <time.h>
|
||||||
|
time_t timegm( struct tm *tm );
|
||||||
|
#endif
|
||||||
|
|
||||||
void *nfmalloc( size_t sz );
|
void *nfmalloc( size_t sz );
|
||||||
void *nfcalloc( size_t sz );
|
void *nfcalloc( size_t sz );
|
||||||
void *nfrealloc( void *mem, size_t sz );
|
void *nfrealloc( void *mem, size_t sz );
|
||||||
|
|
|
@ -835,11 +835,11 @@ parse_date( const char *str )
|
||||||
memset( &datetime, 0, sizeof(datetime) );
|
memset( &datetime, 0, sizeof(datetime) );
|
||||||
if (!(end = strptime( str, "%d-%b-%Y %H:%M:%S ", &datetime )))
|
if (!(end = strptime( str, "%d-%b-%Y %H:%M:%S ", &datetime )))
|
||||||
return -1;
|
return -1;
|
||||||
if ((date = mktime( &datetime )) == -1)
|
if ((date = timegm( &datetime )) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (sscanf( end, "%3d%2d", &hours, &mins ) != 2)
|
if (sscanf( end, "%3d%2d", &hours, &mins ) != 2)
|
||||||
return -1;
|
return -1;
|
||||||
return date - (hours * 60 + mins) * 60 - timezone;
|
return date - (hours * 60 + mins) * 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
65
src/util.c
65
src/util.c
|
@ -203,6 +203,71 @@ memrchr( const void *s, int c, size_t n )
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
void
|
||||||
oob( void )
|
oob( void )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user