[glib] datetime: Fix leap year check



commit 5e65ed4e4458d0a359259298c33b222e16441e5e
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Wed Aug 25 12:30:09 2010 +0100

    datetime: Fix leap year check
    
    Remove a FIXME and an approximation when computing the seconds from
    the Unix epoch.

 glib/gdatetime.c |   23 +++++++++++++++--------
 1 files changed, 15 insertions(+), 8 deletions(-)
---
diff --git a/glib/gdatetime.c b/glib/gdatetime.c
index f76fc48..67c795d 100644
--- a/glib/gdatetime.c
+++ b/glib/gdatetime.c
@@ -86,7 +86,7 @@
 #define USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000))
 #define USEC_PER_DAY         (G_GINT64_CONSTANT (86400000000))
 
-#define GREGORIAN_LEAP(y)    (((y % 4) == 0) && (!(((y % 100) == 0) && ((y % 400) != 0))))
+#define GREGORIAN_LEAP(y)    ((((y) % 4) == 0) && (!((((y) % 100) == 0) && (((y) % 400) != 0))))
 #define JULIAN_YEAR(d)       ((d)->julian / 365.25)
 #define DAYS_PER_PERIOD      (G_GINT64_CONSTANT (2914695))
 
@@ -513,29 +513,36 @@ g_time_zone_new_from_epoch (const gchar *tzname,
 #define SECS_PER_JULIAN (DAYS_PER_PERIOD * SECS_PER_DAY)
 
 static gint64
-g_date_time_secs_offset (GDateTime * dt)
+g_date_time_secs_offset (const GDateTime * dt)
 {
   gint64 secs;
   gint d, y, h, m, s;
-  gint leaps;
+  gint i, leaps;
 
-  y = g_date_time_get_year (dt) - 1970;
+  y = g_date_time_get_year (dt);
   d = g_date_time_get_day_of_year (dt);
   h = g_date_time_get_hour (dt);
   m = g_date_time_get_minute (dt);
   s = g_date_time_get_second (dt);
 
-  /* FIXME this is an approximation */
-  leaps = y / 4;
+  leaps = GREGORIAN_LEAP (y) ? 1 : 0;
+  for (i = 1970; i < y; i++)
+    {
+      if (GREGORIAN_LEAP (i))
+        leaps += 1;
+    }
 
   secs = 0;
-  secs += y * SECS_PER_YEAR;
+  secs += (y - 1970) * SECS_PER_YEAR;
   secs += d * SECS_PER_DAY;
-  secs += leaps * SECS_PER_DAY;
+  secs += (leaps - 1) * SECS_PER_DAY;
   secs += h * SECS_PER_HOUR;
   secs += m * SECS_PER_MINUTE;
   secs += s;
 
+  if (dt->tz != NULL)
+    secs -= dt->tz->offset;
+
   return secs;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]