static void YMDLocalToUtc(YMD *local, YMD *utc) { struct tm local_tm; bool leap_added; YMD_TO_TM(local, (&local_tm), &leap_added); // tm doesn't have milliseconds int milliseconds = local->time % 1000; tzset(); time_t utime = timegm(&local_tm); // mktime min year is 1900 if (local_tm.tm_year < 1900) { local_tm.tm_year = 1900; } mktime(&local_tm); utime -= local_tm.tm_gmtoff; struct tm utc_tm; if (gmtime_r(&utime, &utc_tm) == 0) { AssertMsg(false, "gmtime() failed"); } TM_TO_YMD((&utc_tm), utc, leap_added, local->year); // put milliseconds back utc->time += milliseconds; }
static void YMDUtcToLocal(YMD *utc, YMD *local, int &bias, int &offset, bool &isDaylightSavings) { struct tm utc_tm; bool leap_added; YMD_TO_TM(utc, &utc_tm, &leap_added); // tm doesn't have milliseconds int milliseconds = utc->time % 1000; tzset(); time_t ltime = timegm(&utc_tm); struct tm local_tm; localtime_r(<ime, &local_tm); TM_TO_YMD((&local_tm), local, leap_added, utc->year); // put milliseconds back local->time += milliseconds; // ugly hack but; // right in between dst pass // we need mktime trick to get the correct dst utc_tm.tm_isdst = 1; ltime = mktime(&utc_tm); ltime += utc_tm.tm_gmtoff; localtime_r(<ime, &utc_tm); isDaylightSavings = utc_tm.tm_isdst; offset = utc_tm.tm_gmtoff / 60; bias = offset; }
static void YMDLocalToUtc(YMD *local, YMD *utc) { struct tm local_tm; bool leap_added; YMD_TO_TM(local, (&local_tm), &leap_added); // tm doesn't have milliseconds int milliseconds = local->time % 1000; tzset(); time_t utime = timegm(&local_tm); // we alter the original date // and mktime doesn't know that // so calculate gmtoff manually and keep dst from being included mktime(&local_tm); utime -= local_tm.tm_gmtoff; struct tm utc_tm; if (gmtime_r(&utime, &utc_tm) == 0) { AssertMsg(false, "gmtime() failed"); } TM_TO_YMD((&utc_tm), utc, leap_added, local->year); // put milliseconds back utc->time += milliseconds; }