Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-10-11 15:28:05 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-10-11 15:28:05 +0400
commitf13f2da4ee2eb36a740caddbfb09bbfd927bc52f (patch)
tree885778528256232ea425a9e170a77cd5b98c0904 /newlib/libc/time
parenteefc33184a564c1d33384af6c9776274a72481f8 (diff)
* 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.
Diffstat (limited to 'newlib/libc/time')
-rw-r--r--newlib/libc/time/mktime.c40
-rw-r--r--newlib/libc/time/mktm_r.c7
2 files changed, 34 insertions, 13 deletions
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
{