OSDN Git Service

* libc/time/mktm_r.c: (__tzcalc_limits) Fix Julian day calculation.
authorcorinna <corinna>
Tue, 11 Oct 2011 11:28:04 +0000 (11:28 +0000)
committercorinna <corinna>
Tue, 11 Oct 2011 11:28:04 +0000 (11:28 +0000)
* libc/time/mktime.c: (mktime) Fix tm_yday, tm_mday updating when
timezone causes roll over.

newlib/ChangeLog
newlib/libc/time/mktime.c
newlib/libc/time/mktm_r.c

index 1f11c3c..e9d808c 100644 (file)
@@ -1,3 +1,9 @@
+2011-10-11  Steven Abner <pheonix@zoomtown.com>
+
+       * 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  <nickc@redhat.com>
 
        * libc/sys/arm/crt0.S: Synchronise with libgloss version.
index 93ca5c3..5bedf5a 100644 (file)
@@ -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;
 }
index c0ab219..9a3bc82 100644 (file)
@@ -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
        {