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

Reply via email to