# HG changeset patch
# User renatofilho
# Date 1166465906 0
# Node ID 803672c406ec7c1e11d79203309061521ec6f30b
# Parent  b250ee0438a221aa259f489fb2da288ffdf27b9e
[svn r223] backport of glib functions

diff -r b250ee0438a2 -r 803672c406ec gmyth/src/gmyth_util.c
--- a/gmyth/src/gmyth_util.c	Fri Dec 15 00:21:57 2006 +0000
+++ b/gmyth/src/gmyth_util.c	Mon Dec 18 18:18:26 2006 +0000
@@ -39,6 +39,18 @@
 
 #include "gmyth.h"
 
+#if !GLIB_CHECK_VERSION (2, 10, 0)
+gchar *
+g_time_val_to_iso8601 (GTimeVal *time_);
+gboolean
+g_time_val_from_iso8601 (const gchar *iso_date,
+                         GTimeVal    *time_);
+void
+g_date_set_time_val (GDate    *date,
+             GTimeVal *timeval);
+
+#endif
+
 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
 
 /** Converts a time_t struct in a GString at ISO standard format 
@@ -415,3 +427,195 @@
     return res;    
 }
 
+
+#if !GLIB_CHECK_VERSION (2, 10, 0)
+
+
+/* Hacked from glib 2.10 <gtime.c> */
+
+static time_t
+mktime_utc (struct tm *tm)
+{
+  time_t retval;
+  
+#ifndef HAVE_TIMEGM
+  static const gint days_before[] =
+  {
+    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+  };
+#endif
+
+#ifndef HAVE_TIMEGM
+  if (tm->tm_mon < 0 || tm->tm_mon > 11)
+    return (time_t) -1;
+
+  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;
+#else
+  retval = timegm (tm);
+#endif /* !HAVE_TIMEGM */
+  
+  return retval;
+}
+
+gboolean
+g_time_val_from_iso8601 (const gchar *iso_date,
+                         GTimeVal    *time_)
+{
+  struct tm tm;
+  long val;
+
+  g_return_val_if_fail (iso_date != NULL, FALSE);
+  g_return_val_if_fail (time_ != NULL, FALSE);
+
+  val = strtoul (iso_date, (char **)&iso_date, 10);
+  if (*iso_date == '-')
+    {
+      /* YYYY-MM-DD */
+      tm.tm_year = val - 1900;
+      iso_date++;
+      tm.tm_mon = strtoul (iso_date, (char **)&iso_date, 10) - 1;
+      
+      if (*iso_date++ != '-')
+        return FALSE;
+      
+      tm.tm_mday = strtoul (iso_date, (char **)&iso_date, 10);
+    }
+  else
+    {
+      /* YYYYMMDD */
+      tm.tm_mday = val % 100;
+      tm.tm_mon = (val % 10000) / 100 - 1;
+      tm.tm_year = val / 10000 - 1900;
+    }
+
+  if (*iso_date++ != 'T')
+    return FALSE;
+  
+  val = strtoul (iso_date, (char **)&iso_date, 10);
+  if (*iso_date == ':')
+    {
+      /* hh:mm:ss */
+      tm.tm_hour = val;
+      iso_date++;
+      tm.tm_min = strtoul (iso_date, (char **)&iso_date, 10);
+      
+      if (*iso_date++ != ':')
+        return FALSE;
+      
+      tm.tm_sec = strtoul (iso_date, (char **)&iso_date, 10);
+    }
+  else
+    {
+      /* hhmmss */
+      tm.tm_sec = val % 100;
+      tm.tm_min = (val % 10000) / 100;
+      tm.tm_hour = val / 10000;
+    }
+
+  time_->tv_sec = mktime_utc (&tm);
+  time_->tv_usec = 1;
+  
+  if (*iso_date == '.')
+    time_->tv_usec = strtoul (iso_date + 1, (char **)&iso_date, 10);
+    
+  if (*iso_date == '+' || *iso_date == '-')
+    {
+      gint sign = (*iso_date == '+') ? -1 : 1;
+      
+      val = 60 * strtoul (iso_date + 1, (char **)&iso_date, 10);
+      
+      if (*iso_date == ':')
+    val = 60 * val + strtoul (iso_date + 1, NULL, 10);
+      else
+        val = 60 * (val / 100) + (val % 100);
+
+      time_->tv_sec += (time_t) (val * sign);
+    }
+
+  return TRUE;
+}
+
+
+gchar *
+g_time_val_to_iso8601 (GTimeVal *time_)
+{
+  gchar *retval;
+
+  g_return_val_if_fail (time_->tv_usec >= 0 && time_->tv_usec < G_USEC_PER_SEC, NULL);
+
+#define ISO_8601_LEN    21
+#define ISO_8601_FORMAT "%Y-%m-%dT%H:%M:%SZ"
+  retval = g_new0 (gchar, ISO_8601_LEN + 1);
+  
+  strftime (retval, ISO_8601_LEN,
+        ISO_8601_FORMAT,
+        gmtime (&(time_->tv_sec)));
+  
+  return retval;
+}
+
+
+/* Hacked from glib 2.10 <gdate.c> */
+
+void         
+g_date_set_time_t (GDate *date,
+           time_t timet)
+{
+  struct tm tm;
+  
+  g_return_if_fail (date != NULL);
+  
+#ifdef HAVE_LOCALTIME_R
+  localtime_r (&timet, &tm);
+#else
+  {
+    struct tm *ptm = localtime (&timet);
+
+    if (ptm == NULL)
+      {
+    /* Happens at least in Microsoft's C library if you pass a
+     * negative time_t. Use 2000-01-01 as default date.
+     */
+#ifndef G_DISABLE_CHECKS
+    g_return_if_fail_warning (G_LOG_DOMAIN, "g_date_set_time", "ptm != NULL");
+#endif
+
+    tm.tm_mon = 0;
+    tm.tm_mday = 1;
+    tm.tm_year = 100;
+      }
+    else
+      memcpy ((void *) &tm, (void *) ptm, sizeof(struct tm));
+  }
+#endif
+  
+  date->julian = FALSE;
+  
+  date->month = tm.tm_mon + 1;
+  date->day   = tm.tm_mday;
+  date->year  = tm.tm_year + 1900;
+  
+  g_return_if_fail (g_date_valid_dmy (date->day, date->month, date->year));
+  
+  date->dmy    = TRUE;
+}
+
+
+void
+g_date_set_time_val (GDate    *date,
+             GTimeVal *timeval)
+{
+  g_date_set_time_t (date, (time_t) timeval->tv_sec);
+}
+
+
+
+
+#endif