diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 1f11c3c40..e9d808ce2 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,9 @@ +2011-10-11 Steven Abner + + * libc/time/mktm_r.c: (__tzcalc_limits) Fix Julian day calculation. + * libc/time/mktime.c: (mktime) Fix tm_yday, tm_mday updating when + timezone causes roll over. + 2011-10-10 Nick Clifton * libc/sys/arm/crt0.S: Synchronise with libgloss version. diff --git a/newlib/libc/time/mktime.c b/newlib/libc/time/mktime.c index 93ca5c3a7..5bedf5afc 100644 --- a/newlib/libc/time/mktime.c +++ b/newlib/libc/time/mktime.c @@ -178,29 +178,22 @@ _DEFUN(mktime, (tim_p), /* compute day of the year */ tim_p->tm_yday = days; - if (tim_p->tm_year > 10000 - || tim_p->tm_year < -10000) - { + if (tim_p->tm_year > 10000 || tim_p->tm_year < -10000) return (time_t) -1; - } /* compute days in other years */ - if (tim_p->tm_year > 70) + if ((year = tim_p->tm_year) > 70) { for (year = 70; year < tim_p->tm_year; year++) days += _DAYS_IN_YEAR (year); } - else if (tim_p->tm_year < 70) + else if (year < 70) { for (year = 69; year > tim_p->tm_year; year--) days -= _DAYS_IN_YEAR (year); days -= _DAYS_IN_YEAR (year); } - /* compute day of the week */ - if ((tim_p->tm_wday = (days + 4) % 7) < 0) - tim_p->tm_wday += 7; - /* compute total seconds */ tim += (days * _SEC_IN_DAY); @@ -247,8 +240,29 @@ _DEFUN(mktime, (tim_p), if (!isdst) diff = -diff; tim_p->tm_sec += diff; - validate_structure (tim_p); tim += diff; /* we also need to correct our current time calculation */ + int mday = tim_p->tm_mday; + validate_structure (tim_p); + mday = tim_p->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 */ + days += mday; + /* handle yday */ + if ((tim_p->tm_yday += mday) < 0) { + --year; + tim_p->tm_yday = _DAYS_IN_YEAR(year) - 1; + } else { + mday = _DAYS_IN_YEAR(year); + if (tim_p->tm_yday > (mday - 1)) + tim_p->tm_yday -= mday; + } + } } } } @@ -265,5 +279,9 @@ _DEFUN(mktime, (tim_p), /* reset isdst flag to what we have calculated */ tim_p->tm_isdst = isdst; + /* compute day of the week */ + if ((tim_p->tm_wday = (days + 4) % 7) < 0) + tim_p->tm_wday += 7; + return tim; } diff --git a/newlib/libc/time/mktm_r.c b/newlib/libc/time/mktm_r.c index c0ab2191a..9a3bc820e 100644 --- a/newlib/libc/time/mktm_r.c +++ b/newlib/libc/time/mktm_r.c @@ -216,10 +216,13 @@ _DEFUN (__tzcalc_limits, (year), for (i = 0; i < 2; ++i) { - if (tz->__tzrule[i].ch == 'J') + if (tz->__tzrule[i].ch == 'J') { + /* The Julian day n (1 <= n <= 365). */ days = year_days + tz->__tzrule[i].d + (isleap(year) && tz->__tzrule[i].d >= 60); - else if (tz->__tzrule[i].ch == 'D') + /* Convert to yday */ + --days; + } else if (tz->__tzrule[i].ch == 'D') days = year_days + tz->__tzrule[i].d; else {