static inline int UpdateToYMDYear(const int base_year, const struct tm *time) { int year = time->tm_year; if (base_year < -2100) { const int diff = year - 2100; year = abs(base_year) - diff; } if (base_year < -1900) { year *= -1; } else if (base_year >= 0 && base_year < 100) { year -= 1900; } else if (base_year < 0) { const int org_base_year = NormalizeYMDYear(-1 * base_year); year = base_year - (org_base_year - year); } return year; }
static void YMD_TO_TM(const YMD *ymd, struct tm *time, bool *leap_added) { time->tm_year = NormalizeYMDYear(ymd->year); time->tm_mon = ymd->mon; time->tm_wday = ymd->wday; time->tm_mday = ymd->mday; int t = ymd->time; t /= DateTimeTicks_PerSecond; // discard ms time->tm_sec = t % 60; t /= 60; time->tm_min = t % 60; t /= 60; time->tm_hour = t; // mktime etc. broken-out time accepts 1900 as a start year while epoch is 1970 // temporarily add a calendar day for leap pass bool leap_year = IsLeap(time->tm_year); *leap_added = false; if (ymd->yday == 60 && leap_year) { time->tm_mday++; *leap_added = true; } }
// Windows DateTime implementation normalizes the year beyond <1900 >2100 // mktime etc. broken-out time bases 1900 static inline int NormalizeYMDYear(const int base_year) { int retval = base_year; if (base_year < -2100) { retval = 2100; } else if (base_year < -1900) { retval = base_year * -1; } else if (base_year >= 0 && base_year < 100) { retval = 1900 + base_year; } else if (base_year < 0) { retval = NormalizeYMDYear(-1 * base_year); } return retval; }