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

[email protected] (David McMath)
Newsgroups perl.datetime
Message-ID <[email protected]>
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 ;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.