[glib] GTimeZone: Parse more offset formats



commit 9fae921c3e3ecf312e7481f764894ef84add0d76
Author: Arnel A. Borja <kyoushuu yahoo com>
Date:   Mon Oct 15 10:57:09 2012 +0800

    GTimeZone: Parse more offset formats
    
    Allow more formats for offset. Parse seconds in offsets too. Make offset
    signs optional.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=686128

 glib/gtimezone.c |   46 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 37 insertions(+), 9 deletions(-)
---
diff --git a/glib/gtimezone.c b/glib/gtimezone.c
index 3380f8c..74c0a27 100644
--- a/glib/gtimezone.c
+++ b/glib/gtimezone.c
@@ -214,27 +214,51 @@ g_time_zone_ref (GTimeZone *tz)
 
 /* fake zoneinfo creation (for RFC3339/ISO 8601 timezones) {{{1 */
 /*
- * parses strings of the form 'hh' 'hhmm' or 'hh:mm' where:
- *  - hh is 00 to 23
+ * parses strings of the form h or hh[[:]mm[[[:]ss]]] where:
+ *  - h[h] is 0 to 23
  *  - mm is 00 to 59
+ *  - ss is 00 to 59
  */
 static gboolean
 parse_time (const gchar *time_,
             gint32      *offset)
 {
-  if (*time_ < '0' || '2' < *time_)
+  if (*time_ < '0' || '9' < *time_)
     return FALSE;
 
-  *offset = 10 * 60 * 60 * (*time_++ - '0');
+  *offset = 60 * 60 * (*time_++ - '0');
 
-  if (*time_ < '0' || '9' < *time_)
+  if (*time_ == '\0')
+    return TRUE;
+
+  if (*time_ != ':')
+    {
+      if (*time_ < '0' || '9' < *time_)
+        return FALSE;
+
+      *offset *= 10;
+      *offset += 60 * 60 * (*time_++ - '0');
+
+      if (*offset > 23 * 60 * 60)
+        return FALSE;
+
+      if (*time_ == '\0')
+        return TRUE;
+    }
+
+  if (*time_ == ':')
+    time_++;
+
+  if (*time_ < '0' || '5' < *time_)
     return FALSE;
 
-  *offset += 60 * 60 * (*time_++ - '0');
+  *offset += 10 * 60 * (*time_++ - '0');
 
-  if (*offset > 23 * 60 * 60)
+  if (*time_ < '0' || '9' < *time_)
     return FALSE;
 
+  *offset += 60 * (*time_++ - '0');
+
   if (*time_ == '\0')
     return TRUE;
 
@@ -244,12 +268,12 @@ parse_time (const gchar *time_,
   if (*time_ < '0' || '5' < *time_)
     return FALSE;
 
-  *offset += 10 * 60 * (*time_++ - '0');
+  *offset += 10 * (*time_++ - '0');
 
   if (*time_ < '0' || '9' < *time_)
     return FALSE;
 
-  *offset += 60 * (*time_++ - '0');
+  *offset += *time_++ - '0';
 
   return *time_ == '\0';
 }
@@ -263,6 +287,10 @@ parse_constant_offset (const gchar *name,
       *offset = 0;
       return TRUE;
     }
+
+  if (*name >= '0' && '9' >= *name)
+    return parse_time (name, offset);
+
   switch (*name++)
     {
     case 'Z':



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]