Skip Menu |

This queue is for tickets about the DateTime-Format-DateParse CPAN distribution.

Report information
The Basics
Id: 40384
Status: open
Priority: 0/
Queue: DateTime-Format-DateParse

People
Owner: Nobody in particular
Requestors: MIKO [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.04
Fixed in: (no value)



Subject: Default time zone overriding explicit time zone (includes solution)
The bug involves the situation in which the first argument for parse_datetime includes an explicit time zone, and the second argument is a default timezone. Consider the following code. A $zone argument is sent but the date string already has an explicit timezone. $date = '2008-01-04T00:00:00-0800'; $zone = '-0500'; $dt = DateTime::Format::DateParse->parse_datetime($date, $zone); In situations like that, Date::Parse returns the zone that was set in the date/time string, not the default zone. Currently DateTime::Format::DateParse returns the default zone. I've attached a test script that demonstrates the situation. I've also attached a modified DateParse.pm that fixes the problem. Look for the string "# FIX" in the code. The fix is to simply check if $offset is defined. If it is, the script uses DateTime::TimeZone->offset_as_string($offset) to produce an offset string compatible with DateTime->new.
Subject: DateParse.pm
package DateTime::Format::DateParse; # Copyright (C) 2005-6 Joshua Hoblitt # # $Id: DateParse.pm 3517 2006-09-17 23:10:10Z jhoblitt $ use strict; use vars qw($VERSION); $VERSION = '0.04'; use DateTime; use DateTime::TimeZone; use Date::Parse qw( strptime ); use Time::Zone qw( tz_offset ); sub parse_datetime { my ($class, $date, $zone) = @_; # str2time() calls strptime() internally so it's more efficent to use # strptime() directly. However, the extra validation done by using # DateTime->new() instad of DateTime->from_epoch() may make it into a net # loss. In the end, it turns out that strptime()'s offset information is # needed anyways. my @t = strptime( $date, $zone ); return undef unless @t; my ($ss, $mm, $hh, $day, $month, $year, $offset) = @t; my %p; if ( $ss ) { my $fraction = $ss - int( $ss ); $p{ nanosecond } = $fraction * 1e9 if $fraction; $p{ second } = int $ss; } $p{ minute } = $mm if $mm; $p{ hour } = $hh if $hh; $p{ day } = $day if $day; $p{ month } = $month + 1 if $month; $p{ year } = $year ? $year + 1900 : DateTime->now->year; # unless there is an explict ZONE, Date::Parse seems to parse date only # formats, eg. "1995-01-24", as being in the 'local' timezone. unless ( defined $zone || defined $offset ) { return DateTime->new( %p, time_zone => 'local', ); } # FIX if ( defined $offset ) { return DateTime->new( %p, time_zone => DateTime::TimeZone->offset_as_string($offset), ); } if ( $zone ) { if ( DateTime::TimeZone->is_valid_name( $zone ) ) { return DateTime->new( %p, time_zone => $zone, ); } else { # attempt to convert Time::Zone tz's into an offset return DateTime->new( %p, time_zone => # not an Olson timezone, no DST info DateTime::TimeZone::offset_as_string( tz_offset( $zone ) ), ); } } return DateTime->new( %p, time_zone => # not an Olson timezone, no DST info DateTime::TimeZone::offset_as_string( $offset ), ); } 1; __END__
Subject: default-timezone.4posting.pl
#!/usr/bin/perl -w use strict; use DateTime::Format::DateParse; # variables my ($dt, $date_str, $default_tz); $date_str = '2008-01-04T00:00:00-0800'; $default_tz = '-0500'; $dt = DateTime::Format::DateParse->parse_datetime($date_str, $default_tz); # SHOULD return -0800, actually returns -0500 print 'parsed tz: ', $dt->strftime('%z'), "\n";