# 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 */ + +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 */ + +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