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 ;
}