src: Don't use struct tm.tm_yday from strptime

This commit is contained in:
Tatsuhiro Tsujikawa 2015-07-19 17:14:25 +09:00
parent f2a1c8ee60
commit 5465cdf4a4
3 changed files with 39 additions and 1 deletions

View File

@ -53,3 +53,36 @@ time_t nghttp2_timegm(struct tm *tm) {
return (time_t)t; return (time_t)t;
} }
/* Returns nonzero if the |y| is the leap year. The |y| is the year,
including century (e.g., 2012) */
static int is_leap_year(int y) {
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
}
/* The number of days before ith month begins */
static int daysum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
time_t nghttp2_timegm_without_yday(struct tm *tm) {
int days;
int num_leap_year;
int64_t t;
if (tm->tm_mon > 11) {
return -1;
}
num_leap_year = count_leap_year(tm->tm_year + 1900) - count_leap_year(1970);
days = (tm->tm_year - 70) * 365 + num_leap_year + daysum[tm->tm_mon] +
tm->tm_mday - 1;
if (tm->tm_mon >= 2 && is_leap_year(tm->tm_year + 1900)) {
++days;
}
t = ((int64_t)days * 24 + tm->tm_hour) * 3600 + tm->tm_min * 60 + tm->tm_sec;
#if SIZEOF_TIME_T == 4
if (t < INT32_MIN || t > INT32_MAX) {
return -1;
}
#endif /* SIZEOF_TIME_T == 4 */
return t;
}

View File

@ -39,6 +39,11 @@ extern "C" {
time_t nghttp2_timegm(struct tm *tm); time_t nghttp2_timegm(struct tm *tm);
/* Just like nghttp2_timegm, but without using tm->tm_yday. This is
useful if we use tm from strptime, since some platforms do not
calculate tm_yday with that call. */
time_t nghttp2_timegm_without_yday(struct tm *tm);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -354,7 +354,7 @@ time_t parse_http_date(const std::string &s) {
if (r == 0) { if (r == 0) {
return 0; return 0;
} }
return nghttp2_timegm(&tm); return nghttp2_timegm_without_yday(&tm);
} }
namespace { namespace {