File Coverage

lib/DateTime/Format/DateParse.pm
Criterion Covered Total %
statement 39 43 90.7
branch 20 26 76.9
condition 1 3 33.3
subroutine 7 7 100.0
pod 1 1 100.0
total 68 80 85.0


line stmt bran cond sub pod time code
1             package DateTime::Format::DateParse;
2              
3             # Copyright (C) 2005-6 Joshua Hoblitt
4             #
5             # $Id: DateParse.pm 4429 2010-04-10 19:14:33Z jhoblitt $
6              
7 3     3   325414 use strict;
  3         8  
  3         138  
8              
9 3     3   17 use vars qw($VERSION);
  3         5  
  3         196  
10             $VERSION = '0.05';
11              
12 3     3   3106 use DateTime;
  3         460700  
  3         103  
13 3     3   29 use DateTime::TimeZone;
  3         8  
  3         63  
14 3     3   67615 use Date::Parse qw( strptime );
  3         45849  
  3         356  
15 3     3   31 use Time::Zone qw( tz_offset );
  3         7  
  3         1580  
16              
17             sub parse_datetime {
18 260     260 1 354805 my ($class, $date, $zone) = @_;
19              
20             # str2time() calls strptime() internally so it's more efficent to use
21             # strptime() directly. However, the extra validation done by using
22             # DateTime->new() instad of DateTime->from_epoch() may make it into a net
23             # loss. In the end, it turns out that strptime()'s offset information is
24             # needed anyways.
25 260         8024 my @t = strptime( $date, $zone );
26              
27 260 50       62558 return undef unless @t;
28              
29 260         615 my ($ss, $mm, $hh, $day, $month, $year, $offset) = @t;
30              
31 260         356 my %p;
32 260 100       582 if ( $ss ) {
33 230         637 my $fraction = $ss - int( $ss );
34 230 100       475 if ($fraction) {
35 4         9 my $nano = $fraction * 1e9;
36 4 50       16 if ( $nano != int( $nano ) ) {
37 4 100       13 $nano++ if $nano - int( $nano ) >= 0.5;
38             }
39 4         12 $p{ nanosecond } = int( $nano );
40             }
41 230         472 $p{ second } = int $ss;
42             }
43 260 100       756 $p{ minute } = $mm if $mm;
44 260 100       660 $p{ hour } = $hh if $hh;
45 260 100       1285 $p{ day } = $day if $day;
46 260 100       745 $p{ month } = $month + 1 if $month;
47 260 100       843 $p{ year } = $year ? $year + 1900 : DateTime->now->year;
48              
49             # unless there is an explict ZONE, Date::Parse seems to parse date only
50             # formats, eg. "1995-01-24", as being in the 'local' timezone.
51 260 50 33     2086 unless ( defined $zone || defined $offset ) {
52 0         0 return DateTime->new(
53             %p,
54             time_zone => 'local',
55             );
56             }
57              
58 260 50       468 if ( $zone ) {
59 0 0       0 if ( DateTime::TimeZone->is_valid_name( $zone ) ) {
60 0         0 return DateTime->new(
61             %p,
62             time_zone => $zone,
63             );
64             } else {
65             # attempt to convert Time::Zone tz's into an offset
66 0         0 return DateTime->new(
67             %p,
68             time_zone =>
69             # not an Olson timezone, no DST info
70             DateTime::TimeZone::offset_as_string( tz_offset( $zone ) ),
71             );
72             }
73             }
74              
75 260         1307 return DateTime->new(
76             %p,
77             time_zone =>
78             # not an Olson timezone, no DST info
79             DateTime::TimeZone::offset_as_string( $offset ),
80             );
81             }
82              
83             1;
84              
85             __END__