/* Use platform timegm() if available. */
return (timegm(t));
#else
+ int64_t days, result;
+
/* Otherwise, calculate directly using POSIX assumptions. */
/* First, fix up tm_yday based on the year, month, and day. */
if (mktime(t) == (time_t)-1)
return ((time_t)-1);
/* Then compute timegm() from first principles. */
- return (t->tm_sec
- + t->tm_min * 60
- + t->tm_hour * 3600
- + t->tm_yday * 86400
- + (t->tm_year - 70) * 31536000
- + ((t->tm_year - 69) / 4) * 86400
- - ((t->tm_year - 1) / 100) * 86400
- + ((t->tm_year + 299) / 400) * 86400);
+ days = (int64_t)t->tm_yday
+ + ((int64_t)t->tm_year - 70) * 365
+ + ((int64_t)t->tm_year - 69) / 4
+ - ((int64_t)t->tm_year - 1) / 100
+ + ((int64_t)t->tm_year + 299) / 400;
+ if (archive_ckd_mul_i64(&result, days, 86400) ||
+ archive_ckd_add_i64(&result, result,
+ (int64_t)t->tm_hour * 3600 + t->tm_min * 60
+ + t->tm_sec))
+ return ((time_t)-1);
+ if (result < 0) {
+ if (TIME_MIN == 0 || result < (int64_t)TIME_MIN)
+ return ((time_t)-1);
+ } else if ((uint64_t)result > (uint64_t)TIME_MAX)
+ return ((time_t)-1);
+ return ((time_t)result);
#endif
}