summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@cvs.gnome.org>2006-03-23 02:54:29 +0000
committerEmmanuele Bassi <ebassi@src.gnome.org>2006-03-23 02:54:29 +0000
commit6db9ec40708a4ad60a11a21856a1d54a48b01abd (patch)
tree3bf85717b4903d7847fac54f356890ea2986f849
parent0028b643bc40b38d59cdd3c74a33ec3e282dd397 (diff)
Check for timegm.
2006-03-23 Emmanuele Bassi <ebassi@cvs.gnome.org> * configure.in: Check for timegm. * glib/gtimer.h: * glib/gtimer.c: * glib/glib.symbols: * docs/reference/glib/glib-sections.txt: Added g_time_val_to_iso8601 and g_time_val_from_iso8601, to convert a GTimeVal to and from an ISO 8601 encoded date. * tests/testglib.c: Added test cases for g_time_val_to_iso8601() and g_time_val_from_iso8601() functions.
-rw-r--r--ChangeLog14
-rw-r--r--ChangeLog.pre-2-1014
-rw-r--r--ChangeLog.pre-2-1214
-rw-r--r--configure.in2
-rw-r--r--docs/reference/glib/glib-sections.txt2
-rw-r--r--glib/glib.symbols2
-rw-r--r--glib/gtimer.c155
-rw-r--r--glib/gtimer.h29
-rw-r--r--tests/testglib.c35
9 files changed, 253 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 1e2a8cd57..9234d7f5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2006-03-23 Emmanuele Bassi <ebassi@cvs.gnome.org>
+
+ * configure.in: Check for timegm.
+
+ * glib/gtimer.h:
+ * glib/gtimer.c:
+ * glib/glib.symbols:
+ * docs/reference/glib/glib-sections.txt: Added g_time_val_to_iso8601
+ and g_time_val_from_iso8601, to convert a GTimeVal to and from an
+ ISO 8601 encoded date.
+
+ * tests/testglib.c: Added test cases for g_time_val_to_iso8601()
+ and g_time_val_from_iso8601() functions.
+
2006-03-20 Vladimer Sichinava <vlsichinava@gmail.com>
* configure.in: Added "ka" (Georgian) to ALL_LINGUAS
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 1e2a8cd57..9234d7f5e 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,17 @@
+2006-03-23 Emmanuele Bassi <ebassi@cvs.gnome.org>
+
+ * configure.in: Check for timegm.
+
+ * glib/gtimer.h:
+ * glib/gtimer.c:
+ * glib/glib.symbols:
+ * docs/reference/glib/glib-sections.txt: Added g_time_val_to_iso8601
+ and g_time_val_from_iso8601, to convert a GTimeVal to and from an
+ ISO 8601 encoded date.
+
+ * tests/testglib.c: Added test cases for g_time_val_to_iso8601()
+ and g_time_val_from_iso8601() functions.
+
2006-03-20 Vladimer Sichinava <vlsichinava@gmail.com>
* configure.in: Added "ka" (Georgian) to ALL_LINGUAS
diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12
index 1e2a8cd57..9234d7f5e 100644
--- a/ChangeLog.pre-2-12
+++ b/ChangeLog.pre-2-12
@@ -1,3 +1,17 @@
+2006-03-23 Emmanuele Bassi <ebassi@cvs.gnome.org>
+
+ * configure.in: Check for timegm.
+
+ * glib/gtimer.h:
+ * glib/gtimer.c:
+ * glib/glib.symbols:
+ * docs/reference/glib/glib-sections.txt: Added g_time_val_to_iso8601
+ and g_time_val_from_iso8601, to convert a GTimeVal to and from an
+ ISO 8601 encoded date.
+
+ * tests/testglib.c: Added test cases for g_time_val_to_iso8601()
+ and g_time_val_from_iso8601() functions.
+
2006-03-20 Vladimer Sichinava <vlsichinava@gmail.com>
* configure.in: Added "ka" (Georgian) to ALL_LINGUAS
diff --git a/configure.in b/configure.in
index 8c5144f0e..2f32722bc 100644
--- a/configure.in
+++ b/configure.in
@@ -528,6 +528,8 @@ AC_CHECK_FUNCS(valloc)
AC_CHECK_FUNCS(atexit on_exit)
+AC_CHECK_FUNCS(timegm)
+
AC_CHECK_SIZEOF(char)
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(long)
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index ed5bb2018..0def2c675 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -1155,6 +1155,8 @@ GTimeVal
g_get_current_time
g_usleep
g_time_val_add
+g_time_val_from_iso8601
+g_time_val_to_iso8601
<SUBSECTION>
GDate
diff --git a/glib/glib.symbols b/glib/glib.symbols
index 2b88fec02..71e6974de 100644
--- a/glib/glib.symbols
+++ b/glib/glib.symbols
@@ -1111,6 +1111,8 @@ g_timer_reset
g_timer_start
g_timer_stop
g_time_val_add
+g_time_val_from_iso8601
+g_time_val_to_iso8601 G_GNUC_MALLOC
g_usleep
#endif
#endif
diff --git a/glib/gtimer.c b/glib/gtimer.c
index 6a6a06e3c..2d7678b6b 100644
--- a/glib/gtimer.c
+++ b/glib/gtimer.c
@@ -31,6 +31,8 @@
#include "config.h"
#include "glibconfig.h"
+#include <stdlib.h>
+
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
@@ -308,5 +310,158 @@ g_time_val_add (GTimeVal *time_, glong microseconds)
}
}
+/* converts a broken down date representation, relative to UTC, to
+ * a timestamp; it uses timegm() if it's available.
+ */
+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 == 2 && 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;
+}
+
+/**
+ * g_time_val_from_iso8601:
+ * @iso_date: a ISO 8601 encoded date string
+ * @time_: a #GTimeVal
+ *
+ * Converts a string containing an ISO 8601 encoded date and time
+ * to a #GTimeVal and puts it into @time_.
+ *
+ * Return value: %TRUE if the conversion was successful.
+ *
+ * Since: 2.10
+ */
+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;
+}
+
+/**
+ * g_time_val_to_iso8601:
+ * @time_: a #GTimeVal
+ *
+ * Converts @time_ into a ISO 8601 encoded string, relative to the
+ * Coordinated Universal Time (UTC).
+ *
+ * Return value: a newly allocated string containing a ISO 8601 date
+ *
+ * Since: 2.10
+ */
+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;
+}
+
#define __G_TIMER_C__
#include "galiasdef.c"
diff --git a/glib/gtimer.h b/glib/gtimer.h
index fc434d06a..d602ae1b9 100644
--- a/glib/gtimer.h
+++ b/glib/gtimer.h
@@ -39,19 +39,22 @@ typedef struct _GTimer GTimer;
#define G_USEC_PER_SEC 1000000
-GTimer* g_timer_new (void);
-void g_timer_destroy (GTimer *timer);
-void g_timer_start (GTimer *timer);
-void g_timer_stop (GTimer *timer);
-void g_timer_reset (GTimer *timer);
-void g_timer_continue (GTimer *timer);
-gdouble g_timer_elapsed (GTimer *timer,
- gulong *microseconds);
-
-void g_usleep (gulong microseconds);
-
-void g_time_val_add (GTimeVal *time_,
- glong microseconds);
+GTimer* g_timer_new (void);
+void g_timer_destroy (GTimer *timer);
+void g_timer_start (GTimer *timer);
+void g_timer_stop (GTimer *timer);
+void g_timer_reset (GTimer *timer);
+void g_timer_continue (GTimer *timer);
+gdouble g_timer_elapsed (GTimer *timer,
+ gulong *microseconds);
+
+void g_usleep (gulong microseconds);
+
+void g_time_val_add (GTimeVal *time_,
+ glong microseconds);
+gboolean g_time_val_from_iso8601 (const gchar *iso_date,
+ GTimeVal *time_);
+gchar* g_time_val_to_iso8601 (GTimeVal *time_) G_GNUC_MALLOC;
G_END_DECLS
diff --git a/tests/testglib.c b/tests/testglib.c
index 42f4fce9a..0aadec72a 100644
--- a/tests/testglib.c
+++ b/tests/testglib.c
@@ -475,7 +475,9 @@ main (int argc,
gint morenums[10] = { 8, 9, 7, 0, 3, 2, 5, 1, 4, 6};
gchar *string;
gint value = 120;
- gint *pvalue=NULL;
+ gint *pvalue=NULL;
+ GTimeVal ref_date, date;
+ gchar *date_str;
gchar *mem[10000], *tmp_string = NULL, *tmp_string_2;
gint i, j;
@@ -1176,6 +1178,37 @@ main (int argc,
g_timer_destroy(timer);
g_timer_destroy(timer2);
+#define REF_SEC_UTC 343737360
+#define REF_STR_UTC "1980-11-22T10:36:00Z"
+#define REF_STR_CEST "1980-11-22T12:36:00+02:00"
+#define REF_STR_EST "1980-11-22T05:36:00-05:00"
+
+ g_print ("checking g_time_val_from_iso8601...\n");
+ ref_date.tv_sec = REF_SEC_UTC;
+ ref_date.tv_usec = 0;
+ g_assert (g_time_val_from_iso8601 (REF_STR_UTC, &date) != FALSE);
+ g_print ("\t=> UTC stamp = %ld (should be: %ld) (%ld off)\n", date.tv_sec, ref_date.tv_sec, date.tv_sec - ref_date.tv_sec);
+ g_assert (date.tv_sec == ref_date.tv_sec);
+
+ g_assert (g_time_val_from_iso8601 (REF_STR_CEST, &date) != FALSE);
+ g_print ("\t=> CEST stamp = %ld (should be: %ld) (%ld off)\n", date.tv_sec, ref_date.tv_sec, date.tv_sec - ref_date.tv_sec);
+ g_assert (date.tv_sec == ref_date.tv_sec);
+
+ g_assert (g_time_val_from_iso8601 (REF_STR_EST, &date) != FALSE);
+ g_print ("\t=> EST stamp = %ld (should be: %ld) (%ld off)\n", date.tv_sec, ref_date.tv_sec, date.tv_sec - ref_date.tv_sec);
+ g_assert (date.tv_sec == ref_date.tv_sec);
+ g_print ("ok\n");
+
+ g_print ("checking g_time_val_to_iso8601...\n");
+ ref_date.tv_sec = REF_SEC_UTC;
+ ref_date.tv_usec = 1;
+ date_str = g_time_val_to_iso8601 (&ref_date);
+ g_assert (date_str != NULL);
+ g_print ("\t=> date string = %s (should be: %s)\n", date_str, REF_STR_UTC);
+ g_assert (strcmp (date_str, REF_STR_UTC) == 0);
+ g_free (date_str);
+ g_print ("ok\n");
+
g_print ("checking g_ascii_strcasecmp...");
g_assert (g_ascii_strcasecmp ("FroboZZ", "frobozz") == 0);
g_assert (g_ascii_strcasecmp ("frobozz", "frobozz") == 0);