On Wed Feb 08 21:27:04 2012, autarch@urth.org wrote:
Show quoted text> On Wed, 8 Feb 2012, Douglas Wilson via RT wrote:
>
> >> I think this only makes sense as a constructor option.
> >
> > As in:
> >
> > my $fmt = DateTime::Format::Strptime(
> > zone_map => { PST => '-0800' }
> > );
>
> You're missing a "new", but yes, something like that would make sense, I
> think.
Here's a patch and some tests... :)
--- DateTime-Format-Strptime-1.5000/lib/DateTime/Format/Strptime.pm Sat Oct 16 13:26:44 2010
+++ DateTime-Format-Strptime-1.5001/lib/DateTime/Format/Strptime.pm Fri Feb 10 15:23:03 2012
@@ -8,7 +8,7 @@
use DateTime;
use DateTime::Locale;
use DateTime::TimeZone;
-use Params::Validate qw( validate SCALAR SCALARREF BOOLEAN OBJECT CODEREF );
+use Params::Validate qw( validate SCALAR SCALARREF BOOLEAN OBJECT HASHREF CODEREF );
use Carp;
use Exporter;
@@ -132,6 +132,7 @@
@_, {
pattern => { type => SCALAR | SCALARREF },
time_zone => { type => SCALAR | OBJECT, optional => 1 },
+ zone_map => { type => HASHREF, default => {} },
locale => { type => SCALAR | OBJECT, default => 'English' },
on_error => { type => SCALAR | CODEREF, default => 'undef' },
diagnostic => { type => SCALAR, default => 0 },
@@ -343,21 +344,22 @@
}
if ($timezone) {
+ my $tz = $self->{zone_map}{$timezone} || $ZONEMAP{$timezone};
$self->local_croak("I don't recognise the timezone $timezone.")
and return undef
- unless $ZONEMAP{$timezone};
+ unless $tz;
$self->local_croak("The timezone '$timezone' is ambiguous.")
and return undef
- if $ZONEMAP{$timezone} eq 'Ambiguous'
+ if $tz eq 'Ambiguous'
and not( $tz_offset or $tz_olson );
$self->local_croak(
"Your timezones ('$tz_offset' and '$timezone') do not match.")
and return undef
if $tz_offset
- and $ZONEMAP{$timezone} ne 'Ambiguous'
- and $ZONEMAP{$timezone} != $tz_offset;
- $use_timezone = $ZONEMAP{$timezone}
- if $ZONEMAP{$timezone} ne 'Ambiguous';
+ and $tz ne 'Ambiguous'
+ and $tz != $tz_offset;
+ $use_timezone = $tz
+ if $tz ne 'Ambiguous';
}
if ($tz_olson) {
@@ -1141,6 +1143,11 @@
string you pass to C<parse_datetime>, then the resulting C<DateTime> will
use that time zone.
+Some time zones are ambiguous (e.g. PST, EST, EDT). You may specify a
+zone_map parameter that specifies a mapping of time zone to offset, e.g.:
+
+ zone_map => { PST => '-0800', EST => '-0600' }
+
You can optionally use an on_error parameter. This parameter has three
valid options:
#!perl -w
# t/010_myzone.t - Custom time zone map
use Test::More tests => 6;
use DateTime;
use DateTime::Format::Strptime;
my %zone_map = (
PST => '-0800',
EST => '-0500',
EDT => '-0400',
CST => '-0500',
CDT => '-0600',
);
# 1-3
test(
input => '2009-07-13 11:37:42 PST',
output => '2009-07-13 11:37:42 -0800',
);
# 4-6
test(
input => '2009-07-13 11:37:42 EST',
output => '2009-07-13 11:37:42 -0500',
);
sub test {
my %arg = @_;
my $strptime = DateTime::Format::Strptime->new(
pattern => $arg{pattern} || '%F %T %Z',
locale => $arg{locale} || 'en',
diagnostic => $arg{diagnostic} || 0,
on_error => $arg{on_error} || 'undef',
zone_map => \%zone_map,
);
isa_ok( $strptime, 'DateTime::Format::Strptime' );
my $parsed = $strptime->parse_datetime( $arg{input} );
isa_ok( $parsed, 'DateTime' );
is( $parsed->strftime('%Y-%m-%d %H:%M:%S %z'), $arg{output}, 'Input/Output Matches' );
}