File Coverage

blib/lib/DateTime/Format/RFC3339.pm
Criterion Covered Total %
statement 55 57 96.4
branch 16 26 61.5
condition 2 6 33.3
subroutine 11 11 100.0
pod 2 3 66.6
total 86 103 83.5


line stmt bran cond sub pod time code
1              
2             package DateTime::Format::RFC3339;
3              
4 3     3   464726 use strict;
  3         11  
  3         148  
5 3     3   16 use warnings;
  3         5  
  3         94  
6              
7 3     3   2861 use version; our $VERSION = qv('v1.0.5');
  3         7465  
  3         22  
8              
9 3     3   295 use Carp qw( croak );
  3         8  
  3         217  
10 3     3   1619 use DateTime qw( );
  3         214874  
  3         76  
11              
12              
13 3     3   25 use constant FIRST_IDX => 0;
  3         6  
  3         255  
14 3     3   17 use constant IDX_UC_ONLY => FIRST_IDX + 0;
  3         5  
  3         167  
15 3     3   17 use constant NEXT_IDX => FIRST_IDX + 1;
  3         8  
  3         2479  
16              
17              
18             sub new {
19 2     2 0 7 my ($class, %opts) = @_;
20              
21 2         5 my $uc_only = delete( $opts{uc_only} );
22              
23 2         9 return bless([
24             $uc_only, # IDX_UC_ONLY
25             ], $class);
26             }
27              
28              
29             sub parse_datetime {
30 2     2 1 1555 my ($self, $str) = @_;
31              
32 2 50       13 $self = $self->new()
33             if !ref($self);
34              
35 2 50       15 $str = uc($str)
36             if !$self->[IDX_UC_ONLY];
37            
38 2 50 33     39 my ($Y,$M,$D) = $str =~ s/^(\d{4})-(\d{2})-(\d{2})// && (0+$1,0+$2,0+$3)
39             or croak("Incorrectly formatted date");
40              
41 2 50       13 $str =~ s/^T//
42             or croak("Incorrectly formatted datetime");
43              
44 2 50 33     24 my ($h,$m,$s) = $str =~ s/^(\d{2}):(\d{2}):(\d{2})// && (0+$1,0+$2,0+$3)
45             or croak("Incorrectly formatted time");
46              
47 2 100       12 my $ns = $str =~ s/^\.(\d{1,9})\d*// ? 0+substr($1.('0'x8),0,9) : 0;
48              
49 2         3 my $tz;
50 2 50       9 if ( $str =~ s/^Z// ) { $tz = 'UTC'; }
  2 0       3  
51 0         0 elsif ( $str =~ s/^([+-])(\d{2}):(\d{2})// ) { $tz = "$1$2$3"; }
52 0         0 else { croak("Missing time zone"); }
53              
54 2 50       9 $str =~ /^\z/ or croak("Incorrectly formatted datetime");
55              
56 2         15 return DateTime->new(
57             year => $Y,
58             month => $M,
59             day => $D,
60             hour => $h,
61             minute => $m,
62             second => $s,
63             nanosecond => $ns,
64             time_zone => $tz,
65             formatter => $self,
66             );
67             }
68              
69              
70             sub format_datetime {
71 5     5 1 3264 my ($self, $dt) = @_;
72              
73 5         9 my $tz;
74 5 100       16 if ($dt->time_zone()->is_utc()) {
75 1         15 $tz = 'Z';
76             } else {
77 4         57 my $secs = $dt->offset();
78 4 100       392 my $sign = $secs < 0 ? '-' : '+'; $secs = abs($secs);
  4         5  
79 4         8 my $mins = int($secs / 60); $secs %= 60;
  4         7  
80 4         7 my $hours = int($mins / 60); $mins %= 60;
  4         7  
81 4 100       8 if ($secs) {
82 1         6 ( $dt = $dt->clone() )
83             ->set_time_zone('UTC');
84 1         303 $tz = 'Z';
85             } else {
86 3         15 $tz = sprintf('%s%02d:%02d', $sign, $hours, $mins);
87             }
88             }
89              
90             return
91 5 50       19 $dt->strftime(
92             ($dt->nanosecond()
93             ? '%Y-%m-%dT%H:%M:%S.%9N'
94             : '%Y-%m-%dT%H:%M:%S'
95             )
96             ).$tz;
97             }
98              
99              
100             1;
101              
102              
103             __END__
104              
105             =head1 NAME
106              
107             DateTime::Format::RFC3339 - Parse and format RFC3339 datetime strings
108              
109              
110             =head1 VERSION
111              
112             Version 1.0.5
113              
114              
115             =head1 SYNOPSIS
116              
117             use DateTime::Format::RFC3339;
118              
119             my $f = DateTime::Format::RFC3339->new();
120             my $dt = $f->parse_datetime( '2002-07-01T13:50:05Z' );
121              
122             # 2002-07-01T13:50:05Z
123             print $f->format_datetime($dt);
124              
125              
126             =head1 DESCRIPTION
127              
128             This module understands the RFC3339 date/time format, an ISO 8601 profile,
129             defined at L<http://tools.ietf.org/html/rfc3339>.
130              
131             It can be used to parse these formats in order to create the appropriate
132             objects.
133              
134              
135             =head1 METHODS
136              
137             =over
138              
139             =item C<parse_datetime($string)>
140              
141             Given a RFC3339 datetime string, this method will return a new
142             L<DateTime> object.
143              
144             If given an improperly formatted string, this method will croak.
145              
146             For a more flexible parser, see L<DateTime::Format::ISO8601>.
147              
148             =item C<format_datetime($datetime)>
149              
150             Given a L<DateTime> object, this methods returns a RFC3339 datetime
151             string.
152              
153             =back
154              
155             =head1 SEE ALSO
156              
157             =over 4
158              
159             =item * L<DateTime>
160              
161             =item * L<DateTime::Format::ISO8601>
162              
163             =item * L<http://tools.ietf.org/html/rfc3339>, "Date and Time on the Internet: Timestamps"
164              
165              
166             =back
167              
168              
169             =head1 BUGS
170              
171             Please report any bugs or feature requests to C<bug-datetime-format-rfc3339 at rt.cpan.org>,
172             or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=DateTime-Format-RFC3339>.
173             I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
174              
175              
176             =head1 SUPPORT
177              
178             You can find documentation for this module with the perldoc command.
179              
180             perldoc DateTime::Format::RFC3339
181              
182             You can also look for information at:
183              
184             =over 4
185              
186             =item * Search CPAN
187              
188             L<http://search.cpan.org/dist/DateTime-Format-RFC3339>
189              
190             =item * RT: CPAN's request tracker
191              
192             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=DateTime-Format-RFC3339>
193              
194             =item * AnnoCPAN: Annotated CPAN documentation
195              
196             L<http://annocpan.org/dist/DateTime-Format-RFC3339>
197              
198             =item * CPAN Ratings
199              
200             L<http://cpanratings.perl.org/d/DateTime-Format-RFC3339>
201              
202             =back
203              
204              
205             =head1 AUTHOR
206              
207             Eric Brine, C<< <ikegami@adaelis.com> >>
208              
209              
210             =head1 COPYRIGHT & LICENSE
211              
212             No rights reserved.
213              
214             The author has dedicated the work to the Commons by waiving all of his
215             or her rights to the work worldwide under copyright law and all related or
216             neighboring legal rights he or she had in the work, to the extent allowable by
217             law.
218              
219             Works under CC0 do not require attribution. When citing the work, you should
220             not imply endorsement by the author.
221              
222              
223             =cut