r15472 - gnucash/trunk/src/backend/file - Implement gnc_timegm directly without mktime.

Andreas Köhler andi5 at cvs.gnucash.org
Tue Jan 30 19:05:24 EST 2007


Author: andi5
Date: 2007-01-30 19:05:23 -0500 (Tue, 30 Jan 2007)
New Revision: 15472
Trac: http://svn.gnucash.org/trac/changeset/15472

Modified:
   gnucash/trunk/src/backend/file/sixtp-utils.c
Log:
Implement gnc_timegm directly without mktime.

Calculate the seconds since the start of the UNIX epoch directly without
the help of mktime. This also works on Windows. Systems with timegm are
unaffected.


Modified: gnucash/trunk/src/backend/file/sixtp-utils.c
===================================================================
--- gnucash/trunk/src/backend/file/sixtp-utils.c	2007-01-31 00:03:06 UTC (rev 15471)
+++ gnucash/trunk/src/backend/file/sixtp-utils.c	2007-01-31 00:05:23 UTC (rev 15472)
@@ -381,35 +381,36 @@
 
 #ifdef HAVE_TIMEGM
 #  define gnc_timegm timegm
-#else
+#else /* !HAVE_TIMEGM */
+
+/* This code originates from GLib 2.12, gtimer.c and works until the year 2100
+ * or the system-dependent maximal date that can be represented by a time_t,
+ * whatever comes first.  The old implementation called mktime after setting
+ * the environment variable TZ to UTC.  It did not work on Windows, at least.
+ */
+static const gint days_before[] = {
+  0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+};
+
 static time_t
 gnc_timegm (struct tm *tm)
 {
-  time_t result;
-  char *old_tz;
+  time_t retval;
+  if (tm->tm_mon < 0 || tm->tm_mon > 11)
+    return (time_t) -1;
 
-  old_tz = g_strdup(g_getenv ("TZ"));
-  /* FIXME: there's no way to report this error to the caller. */
-  if (!g_setenv("TZ", "UTC", TRUE))
-    PERR ("couldn't switch the TZ.");
-  result = mktime (tm);
-  if(old_tz)
-  {
-    /* FIXME: there's no way to report this error to the caller. */
-    if (!g_setenv("TZ", old_tz, TRUE))
-      PERR ("couldn't switch the TZ back.");
-    g_free(old_tz);
-  }
-  else
-  {
-    /* FIXME: there's no way to report this error to the caller. */
-    g_unsetenv("TZ");
-    if(errno != 0)
-      PERR ("couldn't restore the TZ to undefined.");
-  }
-  return result;
+  retval = (tm->tm_year - 70) * 365;
+  retval += (tm->tm_year - 68) / 4;
+  retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
+
+  if (tm->tm_year % 4 == 0 && tm->tm_mon < 2)
+    retval -= 1;
+  
+  retval = ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 + tm->tm_sec;
+
+  return retval;
 }
-#endif
+#endif /* HAVE_TIMEGM */
 
 
 /****************************************************************************/



More information about the gnucash-changes mailing list