/**
* g_time_val_from_iso8601:
- * @iso_date: a ISO 8601 encoded date string
+ * @iso_date: an ISO 8601 encoded date string
* @time_: a #GTimeVal
*
* Converts a string containing an ISO 8601 encoded date and time
}
time_->tv_sec = mktime_utc (&tm);
- time_->tv_usec = 1;
+ time_->tv_usec = 0;
if (*iso_date == '.')
- time_->tv_usec = strtoul (iso_date + 1, (char **)&iso_date, 10);
+ {
+ glong mul = 100000;
+
+ while (g_ascii_isdigit (*++iso_date))
+ {
+ time_->tv_usec += (*iso_date - '0') * mul;
+ mul /= 10;
+ }
+ }
if (*iso_date == '+' || *iso_date == '-')
{
val = 60 * strtoul (iso_date + 1, (char **)&iso_date, 10);
if (*iso_date == ':')
- val = 60 * val + strtoul (iso_date + 1, NULL, 10);
+ val = 60 * val + strtoul (iso_date + 1, (char **)&iso_date, 10);
else
val = 60 * (val / 100) + (val % 100);
time_->tv_sec += (time_t) (val * sign);
}
+ else if (*iso_date++ != 'Z')
+ return FALSE;
- return TRUE;
+ while (g_ascii_isspace (*iso_date))
+ iso_date++;
+
+ return *iso_date == '\0';
}
/**
* g_time_val_to_iso8601:
* @time_: a #GTimeVal
*
- * Converts @time_ into a ISO 8601 encoded string, relative to the
+ * Converts @time_ into an ISO 8601 encoded string, relative to the
* Coordinated Universal Time (UTC).
*
- * Return value: a newly allocated string containing a ISO 8601 date
+ * Return value: a newly allocated string containing an ISO 8601 date
*
* Since: 2.12
*/
g_time_val_to_iso8601 (GTimeVal *time_)
{
gchar *retval;
+ struct tm *tm;
#ifdef HAVE_GMTIME_R
struct tm tm_;
#endif
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,
#ifdef HAVE_GMTIME_R
- gmtime_r (&(time_->tv_sec), &tm_)
+ tm = gmtime_r (&time_->tv_sec, &tm_);
#else
- gmtime (&(time_->tv_sec))
+ tm = gmtime (&time_->tv_sec);
#endif
- );
+
+ if (time_->tv_usec != 0)
+ {
+#define ISO_8601_FRAC_LEN 28
+#define ISO_8601_FRAC_FORMAT "%%Y-%%m-%%dT%%H:%%M:%%S.%06ldZ"
+ gchar *format = g_strdup_printf (ISO_8601_FRAC_FORMAT, time_->tv_usec);
+
+ retval = g_new0 (gchar, ISO_8601_FRAC_LEN + 1);
+ strftime (retval, ISO_8601_FRAC_LEN, format, tm);
+ g_free (format);
+ }
+ else
+ {
+#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, tm);
+ }
return retval;
}
g_free (tmp_string);
g_free (string);
-#define REF_INVALID "Wed Dec 19 17:20:20 GMT 2007"
-#define REF_SEC_UTC 320063760
-#define REF_STR_UTC "1980-02-22T10:36:00Z"
-#define REF_STR_CEST "1980-02-22T12:36:00+02:00"
-#define REF_STR_EST "1980-02-22T05:36:00-05:00"
+#define REF_INVALID1 "Wed Dec 19 17:20:20 GMT 2007"
+#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_CEST "1980-02-22T12:36:00+02:00"
+#define REF_STR_EST "19800222T053600-0500"
+#define REF_USEC_UTC 50000
+#define REF_STR_USEC_UTC "1980-02-22T10:36:00.050000Z"
+#define REF_STR_USEC_CEST "19800222T123600.050000000+0200"
+#define REF_STR_USEC_EST "1980-02-22T05:36:00.05-05:00"
if (g_test_verbose())
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_INVALID, &date) == FALSE);
+ g_assert (g_time_val_from_iso8601 (REF_INVALID1, &date) == FALSE);
+ g_assert (g_time_val_from_iso8601 (REF_INVALID2, &date) == FALSE);
g_assert (g_time_val_from_iso8601 (REF_STR_UTC, &date) != FALSE);
if (g_test_verbose())
- 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_print ("\t=> UTC 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);
g_assert (g_time_val_from_iso8601 (REF_STR_CEST, &date) != FALSE);
if (g_test_verbose())
- 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_print ("\t=> CEST 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);
g_assert (g_time_val_from_iso8601 (REF_STR_EST, &date) != FALSE);
if (g_test_verbose())
- 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 ("\t=> EST 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);
+
+ ref_date.tv_usec = REF_USEC_UTC;
+ g_assert (g_time_val_from_iso8601 (REF_STR_USEC_UTC, &date) != FALSE);
+ if (g_test_verbose())
+ g_print ("\t=> UTC 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);
+
+ g_assert (g_time_val_from_iso8601 (REF_STR_USEC_CEST, &date) != FALSE);
+ if (g_test_verbose())
+ g_print ("\t=> CEST 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);
+
+ g_assert (g_time_val_from_iso8601 (REF_STR_USEC_EST, &date) != FALSE);
+ if (g_test_verbose())
+ g_print ("\t=> EST 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);
if (g_test_verbose())
g_print ("checking g_time_val_to_iso8601...\n");
ref_date.tv_sec = REF_SEC_UTC;
- ref_date.tv_usec = 1;
+ ref_date.tv_usec = 0;
date_str = g_time_val_to_iso8601 (&ref_date);
g_assert (date_str != NULL);
if (g_test_verbose())
g_assert (strcmp (date_str, REF_STR_UTC) == 0);
g_free (date_str);
+ ref_date.tv_usec = REF_USEC_UTC;
+ date_str = g_time_val_to_iso8601 (&ref_date);
+ g_assert (date_str != NULL);
+ if (g_test_verbose())
+ g_print ("\t=> date string = %s (should be: %s)\n", date_str, REF_STR_USEC_UTC);
+ g_assert (strcmp (date_str, REF_STR_USEC_UTC) == 0);
+ g_free (date_str);
+
if (g_test_verbose())
g_print ("checking g_ascii_strcasecmp...");
g_assert (g_ascii_strcasecmp ("FroboZZ", "frobozz") == 0);