]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/normal/datetime.c (grub_unixtime2datetime): Fix mishandling
authorVladimir Serbinenko <phcoder@gmail.com>
Sat, 26 Oct 2013 00:47:40 +0000 (02:47 +0200)
committerVladimir Serbinenko <phcoder@gmail.com>
Sat, 26 Oct 2013 00:47:40 +0000 (02:47 +0200)
of first three years after start of validity of unixtime.

ChangeLog
grub-core/normal/datetime.c
include/grub/types.h

index ec6052472793f8970f2a02c5a40962cb3a159686..045f04573fa7bcf3872da0035b2b112406e26d81 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-10-26  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * grub-core/normal/datetime.c (grub_unixtime2datetime): Fix mishandling
+       of first three years after start of validity of unixtime.
+
 2013-10-26  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/normal/menu_entry.c (get_logical_num_lines): Use unsigned
index bbc2cdea91f31e30027b95e6fe109c1c22f76e27..2b0faca90a92978e8db5ab2ef31f9d9dbe205daa 100644 (file)
@@ -52,50 +52,55 @@ grub_get_weekday_name (struct grub_datetime *datetime)
 #define SECPERMIN 60
 #define SECPERHOUR (60*SECPERMIN)
 #define SECPERDAY (24*SECPERHOUR)
-#define SECPERYEAR (365*SECPERDAY)
-#define SECPER4YEARS (4*SECPERYEAR+SECPERDAY)
+#define DAYSPERYEAR 365
+#define DAYSPER4YEARS (4*DAYSPERYEAR+1)
 
 
 void
 grub_unixtime2datetime (grub_int32_t nix, struct grub_datetime *datetime)
 {
   int i;
-  int div;
   grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
   /* In the period of validity of unixtime all years divisible by 4
      are bissextile*/
   /* Convenience: let's have 3 consecutive non-bissextile years
-     at the beginning of the epoch. So count from 1973 instead of 1970 */
-  nix -= 3*SECPERYEAR + SECPERDAY;
+     at the beginning of the counting date. So count from 1901. */
+  int days_epoch;
+  /* Number of days since 1st Januar, 1901.  */
+  unsigned days;
+  /* Seconds into current day.  */
+  unsigned secs_in_day;
   /* Transform C divisions and modulos to mathematical ones */
-  div = nix / SECPER4YEARS;
   if (nix < 0)
-    div--;
-  datetime->year = 1973 + 4 * div;
-  nix -= div * SECPER4YEARS;
+    days_epoch = -(((unsigned) (SECPERDAY-nix-1)) / SECPERDAY);
+  else
+    days_epoch = ((unsigned) nix) / SECPERDAY;
+  secs_in_day = nix - days_epoch * SECPERDAY;
+  days = days_epoch + 69 * DAYSPERYEAR + 17;
 
+  datetime->year = 1901 + 4 * (days / DAYSPER4YEARS);
+  days %= DAYSPER4YEARS;
   /* On 31st December of bissextile years 365 days from the beginning
      of the year elapsed but year isn't finished yet */
-  if (nix / SECPERYEAR == 4)
+  if (days / DAYSPERYEAR == 4)
     {
       datetime->year += 3;
-      nix -= 3*SECPERYEAR;
+      days -= 3*DAYSPERYEAR;
     }
   else
     {
-      datetime->year += nix / SECPERYEAR;
-      nix %= SECPERYEAR;
+      datetime->year += days / DAYSPERYEAR;
+      days %= DAYSPERYEAR;
     }
   for (i = 0; i < 12
-        && nix >= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
-                                   ? 29 : months[i]))*SECPERDAY; i++)
-    nix -= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
-                           ? 29 : months[i]))*SECPERDAY;
+        && days >= (i==1 && datetime->year % 4 == 0
+                     ? 29 : months[i]); i++)
+    days -= (i==1 && datetime->year % 4 == 0
+                           ? 29 : months[i]);
   datetime->month = i + 1;
-  datetime->day = 1 + (nix / SECPERDAY);
-  nix %= SECPERDAY;
-  datetime->hour = (nix / SECPERHOUR);
-  nix %= SECPERHOUR;
-  datetime->minute = nix / SECPERMIN;
-  datetime->second = nix % SECPERMIN;
+  datetime->day = 1 + days;
+  datetime->hour = (secs_in_day / SECPERHOUR);
+  secs_in_day %= SECPERHOUR;
+  datetime->minute = secs_in_day / SECPERMIN;
+  datetime->second = secs_in_day % SECPERMIN;
 }
index 02e1182f29accdd1fc8fb210ef9345cf39978137..8c737aa6f17ac70e234072577a04963ceacdd5ee 100644 (file)
@@ -129,6 +129,8 @@ typedef grub_int32_t        grub_ssize_t;
 #define GRUB_SHRT_MAX 0x7fff
 #define GRUB_UINT_MAX 4294967295U
 #define GRUB_INT_MAX 0x7fffffff
+#define GRUB_INT32_MIN (-2147483647 - 1)
+#define GRUB_INT32_MAX 2147483647
 
 #if GRUB_CPU_SIZEOF_LONG == 8
 # define GRUB_ULONG_MAX 18446744073709551615UL