diff --git a/src/common/conversions.c b/src/common/conversions.c index 04156bc6..1d24e25e 100644 --- a/src/common/conversions.c +++ b/src/common/conversions.c @@ -50,12 +50,44 @@ time_t timegm (struct tm *tm) #ifdef _WIN32 -time_t -timegm(struct tm* tm_time) +#ifndef _MSC_VER +/* Algorithm: http://howardhinnant.github.io/date_algorithms.html */ +static int +days_from_civil(int y, int m, int d) { - return mktime(tm_time) - _timezone; + y -= m <= 2; + int era = y / 400; + int yoe = y - era * 400; /* [0, 399] */ + int doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; /* [0, 365] */ + int doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; /* [0, 146096] */ + return era * 146097 + doe - 719468; } +/* from https://stackoverflow.com/questions/16647819/timegm-cross-platform */ +time_t +timegm(tm const* t) /* does not modify broken-down time */ +{ + int year = t->tm_year + 1900; + int month = t->tm_mon; /* 0-11 */ + if (month > 11) + { + year += month / 12; + month %= 12; + } + else if (month < 0) + { + int years_diff = (11 - month) / 12; + year -= years_diff; + month += 12 * years_diff; + } + int days_since_1970 = days_from_civil(year, month + 1, t->tm_mday); + + return 60 * (60 * (24L * days_since_1970 + t->tm_hour) + t->tm_min) + t->tm_sec; +} +#else +#define timegm _mkgmtime +#endif + #if defined(__MINGW32__) static inline // assuming gmtime is thread safe in windows! @@ -169,7 +201,7 @@ getSecondsOffset(const char* offsetString) uint64_t Conversions_generalizedTimeToMsTime(const char* gtString) { - int gtStringLen = strlen(gtString); + int gtStringLen = (int) strlen(gtString); if (gtStringLen < 14) return -1;