From: Dan Winship Date: Tue, 1 Sep 2009 13:37:48 +0000 (-0400) Subject: g_time_val_from_iso8601: handle timezoneless dates X-Git-Tag: 2.21.6~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8212aadac79d70153d880fe1f21914a2b491dca3;p=platform%2Fupstream%2Fglib.git g_time_val_from_iso8601: handle timezoneless dates per ISO 8601:2004 4.2.5.2 Based on a patch from Andy Shevchenko http://bugzilla.gnome.org/show_bug.cgi?id=589491 --- diff --git a/glib/gtimer.c b/glib/gtimer.c index c52eeb7..407ce85 100644 --- a/glib/gtimer.c +++ b/glib/gtimer.c @@ -364,7 +364,6 @@ g_time_val_from_iso8601 (const gchar *iso_date, tm.tm_hour = val / 10000; } - time_->tv_sec = mktime_utc (&tm); time_->tv_usec = 0; if (*iso_date == ',' || *iso_date == '.') @@ -378,7 +377,13 @@ g_time_val_from_iso8601 (const gchar *iso_date, } } - if (*iso_date == '+' || *iso_date == '-') + /* Now parse the offset and convert tm to a time_t */ + if (*iso_date == 'Z') + { + iso_date++; + time_->tv_sec = mktime_utc (&tm); + } + else if (*iso_date == '+' || *iso_date == '-') { gint sign = (*iso_date == '+') ? -1 : 1; @@ -389,10 +394,13 @@ g_time_val_from_iso8601 (const gchar *iso_date, else val = 60 * (val / 100) + (val % 100); - time_->tv_sec += (time_t) (60 * val * sign); + time_->tv_sec = mktime_utc (&tm) + (time_t) (60 * val * sign); + } + else + { + /* No "Z" or offset, so local time */ + time_->tv_sec = mktime (&tm); } - else if (*iso_date++ != 'Z') - return FALSE; while (g_ascii_isspace (*iso_date)) iso_date++; diff --git a/tests/testglib.c b/tests/testglib.c index 2eeea1e..88b11ae 100644 --- a/tests/testglib.c +++ b/tests/testglib.c @@ -1279,6 +1279,7 @@ various_string_tests (void) GTimeVal ref_date, date; gchar *tmp_string = NULL, *tmp_string_2, *string, *date_str; guint i; + gchar *tz; if (g_test_verbose()) g_print ("checking string chunks..."); @@ -1308,6 +1309,7 @@ various_string_tests (void) #define REF_INVALID2 "1980-02-22T10:36:00Zulu" #define REF_SEC_UTC 320063760 #define REF_STR_UTC "1980-02-22T10:36:00Z" +#define REF_STR_LOCAL "1980-02-22T13:36:00" #define REF_STR_CEST "1980-02-22T12:36:00+02:00" #define REF_STR_EST "19800222T053600-0500" #define REF_STR_NST "1980-02-22T07:06:00-03:30" @@ -1330,6 +1332,25 @@ various_string_tests (void) date.tv_sec - ref_date.tv_sec, date.tv_usec - ref_date.tv_usec); g_assert (date.tv_sec == ref_date.tv_sec && date.tv_usec == ref_date.tv_usec); + /* predefine time zone */ + tz = g_getenv("TZ"); + g_setenv("TZ", "UTC-03:00", 1); + tzset(); + + g_assert (g_time_val_from_iso8601 (REF_STR_LOCAL, &date) != FALSE); + if (g_test_verbose()) + g_print ("\t=> LOCAL stamp = %ld.%06ld (should be: %ld.%06ld) (%ld.%06ld off)\n", + date.tv_sec, date.tv_usec, ref_date.tv_sec, ref_date.tv_usec, + date.tv_sec - ref_date.tv_sec, date.tv_usec - ref_date.tv_usec); + g_assert (date.tv_sec == ref_date.tv_sec && date.tv_usec == ref_date.tv_usec); + + /* revert back user defined time zone */ + if (tz) + g_setenv("TZ", tz, TRUE); + else + g_unsetenv("TZ"); + tzset(); + g_assert (g_time_val_from_iso8601 (REF_STR_CEST, &date) != FALSE); if (g_test_verbose()) g_print ("\t=> CEST stamp = %ld.%06ld (should be: %ld.%06ld) (%ld.%06ld off)\n",