diff --git a/lib/isc/tests/time_test.c b/lib/isc/tests/time_test.c index 912127bda7..caddec2bec 100644 --- a/lib/isc/tests/time_test.c +++ b/lib/isc/tests/time_test.c @@ -15,6 +15,7 @@ */ #include +#include #include @@ -30,6 +31,7 @@ ATF_TC_BODY(isc_time_parsehttptimestamp, tc) { isc_time_t t, x; char buf[100]; + setenv("TZ", "PST8PDT", 1); result = isc_time_now(&t); ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); diff --git a/lib/isc/unix/time.c b/lib/isc/unix/time.c index b39d47b00a..9039b06a88 100644 --- a/lib/isc/unix/time.c +++ b/lib/isc/unix/time.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -407,6 +408,31 @@ isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) { INSIST(flen < len); } +static time_t +timetfromtm(struct tm *tm) { + time_t ret; + int i, yday = 0, leapday; + int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 }; + + leapday = ((((tm->tm_year + 1900 ) % 4) == 0 && + ((tm->tm_year + 1900 ) % 100) != 0) || + ((tm->tm_year + 1900 ) % 400) == 0) ? 1 : 0; + mdays[1] += leapday; + + yday = tm->tm_mday - 1; + for (i = 1; i <= tm->tm_mon; i++) + yday += mdays[i - 1]; + ret = tm->tm_sec + + (60 * tm->tm_min) + + (3600 * tm->tm_hour) + + (86400 * (yday + + ((tm->tm_year - 70) * 365) + + ((tm->tm_year - 69) / 4) - + ((tm->tm_year - 1) / 100) + + ((tm->tm_year + 299) / 400))); + return (ret); +} + isc_result_t isc_time_parsehttptimestamp(char *buf, isc_time_t *t) { struct tm t_tm; @@ -415,10 +441,10 @@ isc_time_parsehttptimestamp(char *buf, isc_time_t *t) { REQUIRE(buf != NULL); REQUIRE(t != NULL); - p = strptime(buf, "%a, %d %b %Y %H:%M:%S %Z", &t_tm); + p = strptime(buf, "%a, %d %b %Y %H:%M:%S", &t_tm); if (p == NULL) return (ISC_R_UNEXPECTED); - when = mktime(&t_tm); + when = timetfromtm(&t_tm); if (when == -1) return (ISC_R_UNEXPECTED); isc_time_set(t, when, 0); diff --git a/lib/isc/win32/time.c b/lib/isc/win32/time.c index f2782001a2..d5049950bf 100644 --- a/lib/isc/win32/time.c +++ b/lib/isc/win32/time.c @@ -318,6 +318,31 @@ isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) { } } +static time_t +timetfromtm(struct tm *tm) { + time_t ret; + int i, yday = 0, leapday; + int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 }; + + leapday = ((((tm->tm_year + 1900 ) % 4) == 0 && + ((tm->tm_year + 1900 ) % 100) != 0) || + ((tm->tm_year + 1900 ) % 400) == 0) ? 1 : 0; + mdays[1] += leapday; + + yday = tm->tm_mday - 1; + for (i = 1; i <= tm->tm_mon; i++) + yday += mdays[i - 1]; + ret = tm->tm_sec + + (60 * tm->tm_min) + + (3600 * tm->tm_hour) + + (86400 * (yday + + ((tm->tm_year - 70) * 365) + + ((tm->tm_year - 69) / 4) - + ((tm->tm_year - 1) / 100) + + ((tm->tm_year + 299) / 400))); + return (ret); +} + #include "strptime.c" isc_result_t isc_time_parsehttptimestamp(char *buf, isc_time_t *t) { @@ -330,7 +355,7 @@ isc_time_parsehttptimestamp(char *buf, isc_time_t *t) { p = strptime(buf, "%a, %d %b %Y %H:%M:%S %Z", &t_tm); if (p == NULL) return (ISC_R_UNEXPECTED); - when = mktime(&t_tm); + when = timetfromtm(&t_tm); if (when == -1) return (ISC_R_UNEXPECTED); isc_time_set(t, when, 0);