File Coverage

blib/lib/DateTime/Format/RFC3501.pm
Criterion Covered Total %
statement 44 45 97.7
branch 13 20 65.0
condition 2 6 33.3
subroutine 8 8 100.0
pod 3 3 100.0
total 70 82 85.3


line stmt bran cond sub pod time code
1 3     3   420112 use strict;
  3         7  
  3         92  
2 3     3   14 use warnings;
  3         6  
  3         134  
3              
4             package DateTime::Format::RFC3501;
5             BEGIN {
6 3     3   48 $DateTime::Format::RFC3501::VERSION = '0.02';
7             }
8             # ABSTRACT: Parse and format RFC3501 datetime strings
9              
10              
11 3     3   14 use Carp;
  3         5  
  3         195  
12 3     3   1144 use DateTime();
  3         215381  
  3         1975  
13              
14             # http://tools.ietf.org/html/rfc3501#section-9 (date-month)
15             my @date_month = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
16              
17             my %month_by_name;
18             @month_by_name{@date_month} = 1 .. @date_month;
19              
20              
21             sub new {
22 2     2 1 3 my $class = shift;
23 2         5 my %opts = @_;
24              
25 2         9 return bless \%opts, $class;
26             }
27              
28              
29              
30             sub parse_datetime {
31 2     2 1 23160 my $self = shift;
32 2         6 my ($str) = @_;
33              
34 2 50       14 $self = $self->new()
35             if !ref($self);
36              
37 2 50 33     43 my ( $D, $M, $Y ) = $str =~ s/^([ ]\d|\d{2})-([A-Z][a-z]{2})-(\d{4})// && (0+$1,$2,0+$3)
38             or croak("Incorrectly formatted date");
39              
40 2 50       13 $str =~ s/^ //
41             or croak("Incorrectly formatted datetime");
42              
43 2 50 33     26 my ( $h, $m, $s ) = $str =~ s/^(\d{2}):(\d{2}):(\d{2})// && (0+$1,0+$2,0+$3)
44             or croak("Incorrectly formatted time");
45              
46 2 50       12 $str =~ s/^ //
47             or croak("Incorrectly formatted datetime");
48              
49 2         3 my $tz;
50 2 50       20 if ( $str =~ s/^([+-])(\d{4})// ) {
51 2         7 $tz = "$1$2";
52             }
53             else {
54 0         0 croak("Missing time zone");
55             }
56              
57 2 50       9 $str =~ /^\z/ or croak("Incorrectly formatted datetime");
58              
59 2         15 return DateTime->new(
60             year => $Y,
61             month => $month_by_name{$M},
62             day => $D,
63             hour => $h,
64             minute => $m,
65             second => $s,
66             time_zone => $tz,
67             formatter => $self,
68             );
69             }
70              
71              
72             sub format_datetime {
73 7     7 1 30325 my ($self, $dt) = @_;
74 7         13 my $tz;
75              
76 7 100       25 if ( $dt->time_zone->is_utc() ) {
77 2         24 $tz = '+0000';
78             } else {
79 5         51 my $secs = $dt->offset;
80 5 100       304 my $sign = $secs < 0 ? '-' : '+'; $secs = abs($secs);
  5         9  
81 5         10 my $mins = int( $secs / 60 ); $secs %= 60;
  5         11  
82 5         8 my $hours = int( $mins / 60 ); $mins %= 60;
  5         7  
83 5 100       14 if ($secs) {
84 1         6 ( $dt = $dt->clone() )
85             ->set_time_zone('UTC');
86 1         229 $tz = '+0000';
87             }
88             else {
89 4         15 $tz = sprintf( '%s%02d%02d', $sign, $hours, $mins );
90             }
91             }
92              
93 7         26 return $dt->strftime('%e-%b-%Y %H:%M:%S ').$tz;
94             }
95              
96             1;
97              
98              
99             __END__