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
This commit is contained in:
Arnel A. Borja 2012-10-15 10:57:09 +08:00 committed by John Ralls
parent 59f2da1749
commit 9fae921c3e

View File

@ -214,30 +214,38 @@ g_time_zone_ref (GTimeZone *tz)
/* fake zoneinfo creation (for RFC3339/ISO 8601 timezones) {{{1 */ /* fake zoneinfo creation (for RFC3339/ISO 8601 timezones) {{{1 */
/* /*
* parses strings of the form 'hh' 'hhmm' or 'hh:mm' where: * parses strings of the form h or hh[[:]mm[[[:]ss]]] where:
* - hh is 00 to 23 * - h[h] is 0 to 23
* - mm is 00 to 59 * - mm is 00 to 59
* - ss is 00 to 59
*/ */
static gboolean static gboolean
parse_time (const gchar *time_, parse_time (const gchar *time_,
gint32 *offset) gint32 *offset)
{ {
if (*time_ < '0' || '2' < *time_)
return FALSE;
*offset = 10 * 60 * 60 * (*time_++ - '0');
if (*time_ < '0' || '9' < *time_) if (*time_ < '0' || '9' < *time_)
return FALSE; return FALSE;
*offset += 60 * 60 * (*time_++ - '0'); *offset = 60 * 60 * (*time_++ - '0');
if (*offset > 23 * 60 * 60)
return FALSE;
if (*time_ == '\0') if (*time_ == '\0')
return TRUE; 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_ == ':') if (*time_ == ':')
time_++; time_++;
@ -251,6 +259,22 @@ parse_time (const gchar *time_,
*offset += 60 * (*time_++ - '0'); *offset += 60 * (*time_++ - '0');
if (*time_ == '\0')
return TRUE;
if (*time_ == ':')
time_++;
if (*time_ < '0' || '5' < *time_)
return FALSE;
*offset += 10 * (*time_++ - '0');
if (*time_ < '0' || '9' < *time_)
return FALSE;
*offset += *time_++ - '0';
return *time_ == '\0'; return *time_ == '\0';
} }
@ -263,6 +287,10 @@ parse_constant_offset (const gchar *name,
*offset = 0; *offset = 0;
return TRUE; return TRUE;
} }
if (*name >= '0' && '9' >= *name)
return parse_time (name, offset);
switch (*name++) switch (*name++)
{ {
case 'Z': case 'Z':