File Coverage

blib/lib/DateTime/Format/RFC3501.pm
Criterion Covered Total %
statement 43 44 97.7
branch 13 20 65.0
condition 2 6 33.3
subroutine 7 7 100.0
pod 3 3 100.0
total 68 80 85.0


line stmt bran cond sub pod time code
1 3     3   1232617 use strict;
  3         23  
  3         103  
2 3     3   18 use warnings;
  3         6  
  3         154  
3              
4             package DateTime::Format::RFC3501;
5             # ABSTRACT: Parse and format RFC3501 datetime strings
6             $DateTime::Format::RFC3501::VERSION = '0.03';
7              
8 3     3   21 use Carp;
  3         5  
  3         246  
9 3     3   1023 use DateTime();
  3         514345  
  3         1902  
10              
11             # http://tools.ietf.org/html/rfc3501#section-9 (date-month)
12             my @date_month = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
13              
14             my %month_by_name;
15             @month_by_name{@date_month} = 1 .. @date_month;
16              
17              
18             sub new {
19 2     2 1 3 my $class = shift;
20 2         5 my %opts = @_;
21              
22 2         8 return bless \%opts, $class;
23             }
24              
25              
26              
27             sub parse_datetime {
28 2     2 1 18000 my $self = shift;
29 2         7 my ($str) = @_;
30              
31 2 50       13 $self = $self->new()
32             if !ref($self);
33              
34 2 50 33     34 my ( $D, $M, $Y ) = $str =~ s/^([ ]\d|\d{2})-([A-Z][a-z]{2})-(\d{4})// && (0+$1,$2,0+$3)
35             or croak("Incorrectly formatted date");
36              
37 2 50       10 $str =~ s/^ //
38             or croak("Incorrectly formatted datetime");
39              
40 2 50 33     19 my ( $h, $m, $s ) = $str =~ s/^(\d{2}):(\d{2}):(\d{2})// && (0+$1,0+$2,0+$3)
41             or croak("Incorrectly formatted time");
42              
43 2 50       12 $str =~ s/^ //
44             or croak("Incorrectly formatted datetime");
45              
46 2         4 my $tz;
47 2 50       10 if ( $str =~ s/^([+-])(\d{4})// ) {
48 2         5 $tz = "$1$2";
49             }
50             else {
51 0         0 croak("Missing time zone");
52             }
53              
54 2 50       9 $str =~ /^\z/ or croak("Incorrectly formatted datetime");
55              
56             return DateTime->new(
57             year => $Y,
58 2         11 month => $month_by_name{$M},
59             day => $D,
60             hour => $h,
61             minute => $m,
62             second => $s,
63             time_zone => $tz,
64             formatter => $self,
65             );
66             }
67              
68              
69             sub format_datetime {
70 7     7 1 29400 my ($self, $dt) = @_;
71 7         15 my $tz;
72              
73 7 100       22 if ( $dt->time_zone->is_utc() ) {
74 2         25 $tz = '+0000';
75             } else {
76 5         60 my $secs = $dt->offset;
77 5 100       423 my $sign = $secs < 0 ? '-' : '+'; $secs = abs($secs);
  5         11  
78 5         12 my $mins = int( $secs / 60 ); $secs %= 60;
  5         9  
79 5         9 my $hours = int( $mins / 60 ); $mins %= 60;
  5         9  
80 5 100       11 if ($secs) {
81 1         20 ( $dt = $dt->clone() )
82             ->set_time_zone('UTC');
83 1         234 $tz = '+0000';
84             }
85             else {
86 4         22 $tz = sprintf( '%s%02d%02d', $sign, $hours, $mins );
87             }
88             }
89              
90 7         25 return $dt->strftime('%e-%b-%Y %H:%M:%S ').$tz;
91             }
92              
93             1;
94              
95             __END__
96              
97             =pod
98              
99             =encoding UTF-8
100              
101             =head1 NAME
102              
103             DateTime::Format::RFC3501 - Parse and format RFC3501 datetime strings
104              
105             =head1 VERSION
106              
107             version 0.03
108              
109             =head1 SYNOPSIS
110              
111             use DateTime::Format::RFC3501;
112            
113             my $f = DateTime::Format::RFC3501->new();
114             my $dt = $f->parse_datetime( ' 1-Jul-2002 13:50:05 +0200' );
115            
116             # 1-Jul-2002 13:50:05 +0200
117             print $f->format_datetime($dt);
118              
119             =head1 DESCRIPTION
120              
121             This module understands the RFC3501 date-time format, defined
122             at http://tools.ietf.org/html/rfc3501.
123              
124             It can be used to parse this format in order to create the
125             appropriate objects.
126              
127             =head1 METHODS
128              
129             =head2 new()
130              
131             Returns a new RFC3501 parser object.
132              
133             =head2 parse_datetime($string)
134              
135             Given a RFC3501 date-time string, this method will return a new
136             L<DateTime> object.
137              
138             If given an improperly formatted string, this method will croak.
139              
140             For a more flexible parser, see L<DateTime::Format::Strptime>.
141              
142             =head2 format_datetime($datetime)
143              
144             Given a L<DateTime> object, this methods returns a RFC3501 date-time string.
145              
146             =head1 CREDITS
147              
148             This module was heavily inspired by L<DateTime::Format::RFC3339>.
149              
150             =head1 SEE ALSO
151              
152             =over 4
153              
154             =item *
155              
156             L<DateTime>
157              
158             =item *
159              
160             L<DateTime::Format::RFC3339>
161              
162             =item *
163              
164             L<DateTime::Format::Strptime>
165              
166             =item *
167              
168             L<http://tools.ietf.org/html/rfc3501>, "Internet Message Access Protocol - version 4rev1"
169              
170             =back
171              
172             =head1 BUGS
173              
174             Please report any bugs or feature requests
175             through the web interface at
176             L<https://github.com/alexm/DateTime-Format-RFC3501/issues>.
177             I will be notified, and then you'll automatically be notified of progress
178             on your bug as I make changes.
179              
180             =head1 SUPPORT
181              
182             You can find documentation for this module with the perldoc command.
183              
184             perldoc DateTime::Format::RFC3501
185              
186             =head1 AUTHOR
187              
188             Alex Muntada <alexm@cpan.org>
189              
190             =head1 COPYRIGHT AND LICENSE
191              
192             This software is copyright (c) 2011-2021 by Alex Muntada.
193              
194             This is free software; you can redistribute it and/or modify it under
195             the same terms as the Perl 5 programming language system itself.
196              
197             =cut