From b3bbf95507a9a739ee568d2413e7c8afe2807f07 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Mon, 1 Sep 2014 21:19:03 -0700 Subject: [PATCH] Util.pm: correct & loosen parse_any_date RFC 3339 / ISO 8601 parsing Accept '_' in place of 'T' (as well as ' ' which was previously accepted). Make the space before the zone optional (was incorrectly required before). Accept '_' in place of the space before the zone. Accept a single digit hour (both time and zone offset). Remove warnings caused by omitting the trailing 'Z'. Accept a form with no ':' or '-' characters (only 2-digit hours). Still does not accept fractional seconds. --- Girocco/Util.pm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Girocco/Util.pm b/Girocco/Util.pm index fe91c1d..8138b20 100644 --- a/Girocco/Util.pm +++ b/Girocco/Util.pm @@ -542,8 +542,9 @@ sub parse_rfc2822_date { # Will parse any supported date format. Actually there are three formats # currently supported: # 1. RFC 2822 (uses parse_rfc2822_date) -# 2. RFC 3339 / ISO 8601 (T may be ' ', 'Z' is optional, ':' optional in TZ) -# 3. unix seconds since epoch with optional +/- trailing TZ (may not have a ':') +# 2. RFC 3339 / ISO 8601 (T may be ' ' or '_', 'Z' is optional, ':' optional in TZ) +# 3. Same as #2 except no colons or hyphens allowed and hours MUST be 2 digits +# 4. unix seconds since epoch with optional +/- trailing TZ (may not have a ':') # Returns undef if unsupported date. # If the second argument is a SCALAR ref, its value will be set to the TZ offset in seconds sub parse_any_date { @@ -561,10 +562,13 @@ sub parse_any_date { $$tzoff = $off if ref($tzoff) eq 'SCALAR'; return $ts; } - if ($dstr =~ /^\s*(\d{4})-(\d{2})-(\d{2})[Tt ](\d{2}):(\d{2}):(\d{2})(?:[ ]([Zz]|(?:[-+]\d{2}:?\d{2})))?\s*$/) { + if ($dstr =~ /^\s*(\d{4})-(\d{2})-(\d{2})[Tt _](\d{1,2}):(\d{2}):(\d{2})(?:[ _]?([Zz]|(?:[-+]\d{1,2}:?\d{2})))?\s*$/ || + $dstr =~ /^\s*(\d{4})(\d{2})(\d{2})[Tt _](\d{2})(\d{2})(\d{2})(?:[ _]?([Zz]|(?:[-+]\d{2}\d{2})))?\s*$/) { my ($Y,$m,$d,$H,$M,$S,$z) = ($1,$2,$3,$4,$5,$6,$7||''); my $seconds = timegm(0+$S, 0+$M, 0+$H, 0+$d, $m-1, $Y-1900); + defined($z) && $z ne '' or $z = 'Z'; $z =~ s/://; + substr($z,1,0) = '0' if length($z) == 4; my $off = 0; if (uc($z) ne 'Z') { $off = 60 * (60 * (0+substr($z,1,2)) + (0+substr($z,3,2))); -- 2.11.4.GIT