develooper Front page | perl.datetime | Postings from March 2012

Re: Are the formats in DateTime::Format::Strptime extensible?

Thread Previous
From:
David McMath
Date:
March 16, 2012 08:38
Subject:
Re: Are the formats in DateTime::Format::Strptime extensible?
Message ID:
4F635E62.7090303@stanford.edu
On 03/15/2012 08:58 PM, Nathan Gray wrote:
> On Thu, Mar 15, 2012 at 04:43:32PM -0500, David McMath wrote:
>> A while back, I needed to some routines to parse timestamps so I
>> started using DateTime::Format::Strptime.  The times were uniformly
>> formatted like "2012-03-13T07:43:07-07:00".  That /almost/ matched
>> the pattern "%FT%T%z" but I couldn't figure out how to force the
>> match.  So I ended up taking a shortcut and removing the final ":"
>> before processing.
>>
>> Now I want to recycle the code and handle a few more formats and I'd
>> /really/ like it to be the case that I don't have to do any
>> manipulations of the strings before parsing; I'd much rather just
>> have the caller specify what the proper format is and go from there.
>
> You might take a look at DateTime::Format::Builder.
>
> -kolibrie

Oh, thanks!  My solution totally cribs from

	http://search.cpan.org/~drolsky/DateTime-Format-Builder-0.80/lib/DateTime/Format/Builder/Tutorial.pod

but it's just so simple.  I have my own master-list of common formats, 
but if I come across something that's inconsistent with them I can 
"easily" make a new parser now.  This is really cool.

I put my solution below.  I know it's got a problem in _parse_tz because 
my timezone-matching is too permissive, and it's barely debugged at all, 
but as proof of concept I'm quite happy with it.

Thanks again,

dave

--

use DateTime::Format::Builder (
   parsers => {
     parse_datetime => [
       [ preprocess => \&_parse_tz ],
       {
        params => [ qw( year month day hour minute second ) ],
        regex  => qr/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/,
       },
       {
        params => [ qw( year month day ) ],
        regex  => qr/^(\d{4})-(\d{2})-(\d{2})/,
       },
		      ]
	     },
			      ) ;
sub _parse_tz {
   my %args = @_ ;
   my ($date, $p) = @args{qw/input parsed/} ;
   if ($date =~ s/(.\d{2}:\d{2})$//) {
     ($p->{time_zone} = $1) =~ s/:// ;
   }
   else {
     $p->{time_zone} = 'floating' ;
   }
   return $date ;
}

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About