time_t handle_daylight_savings( _In_ struct tm* TimePointer, _In_ int Year, _In_ int DayCount, _In_ time_t LinearTime) { __tzinfo_type* tz = __gettzinfo(); int isdst = 0; TZ_LOCK; _tzset_unlocked(); if (__daylight) { int tm_isdst; int y = TimePointer->tm_year + YEAR_BASE; /* Convert user positive into 1 */ tm_isdst = TimePointer->tm_isdst > 0 ? 1 : TimePointer->tm_isdst; isdst = tm_isdst; if (y == tz->__tzyear || __tzcalc_limits (y)) { /* calculate start of dst in dst local time and start of std in both std local time and dst local time */ time_t startdst_dst = tz->__tzrule[0].change - (time_t) tz->__tzrule[1].offset; time_t startstd_dst = tz->__tzrule[1].change - (time_t) tz->__tzrule[1].offset; time_t startstd_std = tz->__tzrule[1].change - (time_t) tz->__tzrule[0].offset; /* if the time is in the overlap between dst and std local times */ if (LinearTime >= startstd_std && LinearTime < startstd_dst) ; /* we let user decide or leave as -1 */ else { isdst = (tz->__tznorth ? (LinearTime >= startdst_dst && LinearTime < startstd_std) : (LinearTime >= startdst_dst || LinearTime < startstd_std)); /* if user committed and was wrong, perform correction, but not * if the user has given a negative value (which * asks mktime() to determine if DST is in effect or not) */ if (tm_isdst >= 0 && (isdst ^ tm_isdst) == 1) { /* we either subtract or add the difference between time zone offsets, depending on which way the user got it wrong. The diff is typically one hour, or 3600 seconds, and should fit in a 16-bit int, even though offset is a long to accomodate 12 hours. */ int diff = (int) (tz->__tzrule[0].offset - tz->__tzrule[1].offset); if (!isdst) diff = -diff; TimePointer->tm_sec += diff; LinearTime += diff; /* we also need to correct our current time calculation */ int mday = TimePointer->tm_mday; validate_structure (TimePointer); mday = TimePointer->tm_mday - mday; /* roll over occurred */ if (mday) { /* compensate for month roll overs */ if (mday > 1) mday = -1; else if (mday < -1) mday = 1; /* update days for wday calculation */ DayCount += mday; /* handle yday */ if ((TimePointer->tm_yday += mday) < 0) { --Year; TimePointer->tm_yday = DAYSPERYEAR(Year) - 1; } else { mday = DAYSPERYEAR(Year); if (TimePointer->tm_yday > (mday - 1)) TimePointer->tm_yday -= mday; } } } } } } // add appropriate offset to put time in gmt format if (isdst == 1) { LinearTime += (time_t) tz->__tzrule[1].offset; } else { // otherwise assume std time LinearTime += (time_t) tz->__tzrule[0].offset; } TZ_UNLOCK; // Update the daylight savings result TimePointer->tm_isdst = isdst; TimePointer->tm_wday = (DayCount + 4) % 7; if (TimePointer->tm_wday < 0) { TimePointer->tm_wday += 7; } return LinearTime; }
365, 366 } ; struct tm * _DEFUN (_mktm_r, (tim_p, res, is_gmtime), _CONST time_t * tim_p _AND struct tm *res _AND int is_gmtime) { long days, rem; time_t lcltime; int y; int yleap; _CONST int *ip; __tzinfo_type *tz = __gettzinfo (); /* base decision about std/dst time on current time */ lcltime = *tim_p; days = ((long)lcltime) / SECSPERDAY; rem = ((long)lcltime) % SECSPERDAY; while (rem < 0) { rem += SECSPERDAY; --days; } while (rem >= SECSPERDAY) { rem -= SECSPERDAY; ++days;
* Converts the calendar time pointed to by tim_p into a broken-down time * expressed as local time. Returns a pointer to a structure containing the * broken-down time. */ #include "local.h" struct tm * _DEFUN (localtime_r, (tim_p, res), _CONST time_t *__restrict tim_p _AND struct tm *__restrict res) { long offset; int hours, mins, secs; int year; __tzinfo_type *_CONST tz = __gettzinfo (); _CONST int *ip; res = gmtime_r (tim_p, res); year = res->tm_year + YEAR_BASE; ip = __month_lengths[isleap(year)]; TZ_LOCK; if (_daylight) { if (year == tz->__tzyear || __tzcalc_limits (year)) res->tm_isdst = (tz->__tznorth ? (*tim_p >= tz->__tzrule[0].change && *tim_p < tz->__tzrule[1].change) : (*tim_p >= tz->__tzrule[0].change