File Coverage

blib/lib/DateTime/Format/Duration/XSD.pm
Criterion Covered Total %
statement 45 47 95.7
branch 17 28 60.7
condition 15 17 88.2
subroutine 10 10 100.0
pod 0 3 0.0
total 87 105 82.8


line stmt bran cond sub pod time code
1             package DateTime::Format::Duration::XSD;
2              
3 1     1   23894 use 5.008008;
  1         4  
  1         36  
4 1     1   5 use strict;
  1         2  
  1         34  
5 1     1   4 use warnings;
  1         14  
  1         39  
6              
7 1     1   4 use Carp;
  1         2  
  1         102  
8 1     1   3981 use DateTime;
  1         206504  
  1         49  
9 1     1   11 use DateTime::Duration;
  1         3  
  1         21  
10 1     1   1344 use DateTime::Format::Duration;
  1         6917  
  1         589  
11              
12             our $VERSION = 0.01;
13              
14             sub new {
15 2     2 0 472 my $class = shift;
16 2         12 return bless {
17             fmt => DateTime::Format::Duration->new(
18             pattern => '%PP%YY%mM%dDT%HH%MM%S.%NS',
19             normalize => 1,
20             ),
21             }, $class;
22             }
23              
24             sub parse_duration {
25 8     8 0 5563 my ($self, $xs_duration) = @_;
26 8         13 my ($neg, $year, $mounth, $day, $hour, $min, $sec, $fsec);
27 8 50       71 if ($xs_duration =~ /^(-)?
28             P
29             ((\d+)Y)?
30             ((\d+)M)?
31             ((\d+)D)?
32             (
33             T
34             ((\d+)H)?
35             ((\d+)M)?
36             (((\d+)(\.(\d+))?)S)?
37             )?
38             $/x)
39             {
40 8         48 ($neg, $year, $mounth, $day, $hour, $min, $sec, $fsec) =
41             ($1, $3, $5, $7, $10, $12, $15, $17);
42 8 50       12 unless (grep {defined} ($year, $mounth, $day, $hour, $min, $sec)) {
  48         78  
43 0         0 croak "duration contains no data '$xs_duration'";
44             }
45             } else {
46 0         0 croak "duration string does not match standart: '$xs_duration'";
47             }
48 8 100 100     139 my $dt = DateTime::Duration->new(
      100        
      100        
      100        
      100        
      100        
49             years => $year || 0,
50             months => $mounth || 0,
51             days => $day || 0,
52             hours => $hour || 0,
53             minutes => $min || 0,
54             seconds => $sec || 0,
55             nanoseconds => ($fsec ? "0.$fsec" * 1E9 : 0),
56             );
57 8 100       959 return defined $neg ? $dt->inverse : $dt;
58             }
59              
60              
61             sub format_duration {
62 4     4 0 13050 my ($self, $duration) = @_;
63 4         27 my %deltas = $self->{fmt}->normalize($duration);
64 4 50 33     620 if (exists $deltas{seconds} or exists $deltas{nanoseconds}) {
65 4 50 100     32 $deltas{seconds} = ($deltas{seconds} || 0)
66             + (exists $deltas{nanoseconds} ? $deltas{nanoseconds} / 1E9 : 0);
67             }
68 4 100       12 my $str = $deltas{negative} ? "-P" : "P";
69 4 50       17 $str .= "$deltas{years}Y" if exists $deltas{years};
70 4 50       14 $str .= "$deltas{months}M" if exists $deltas{months};
71 4 50       13 $str .= "$deltas{days}D" if exists $deltas{days};
72 4 50       8 $str .= "T" if grep {exists $deltas{$_}} qw(hours minutes seconds);
  12         25  
73 4 50       13 $str .= "$deltas{hours}H" if exists $deltas{hours};
74 4 50       12 $str .= "$deltas{minutes}M" if exists $deltas{minutes};
75 4 50       19 $str .= "$deltas{seconds}S" if exists $deltas{seconds};
76              
77 4         17 return $str;
78             }
79              
80             1;
81              
82             =head1 NAME
83              
84             DateTime::Format::Duration::XSD
85              
86             =head1 SYNOPSIS
87              
88             use DateTime::Format::Duration::XSD;
89             my $dfdx = DateTime::Format::Duration::XSD->new();
90             my $duration_object = $dfdx->parse_duration('-P1Y2M3DT1H2M3.33S');
91             my $xsd_duration = $dfdx->format_duration($duration_object);
92              
93             =head1 DESCRIPTION
94              
95             DateTime::Format::Duration::XSD - Formats and parses DateTime::Duration
96             according to xs:duration
97              
98             =head1 SEE ALSO
99              
100             L, L, L
101              
102             The XML Schema speficitation
103              
104             =head1 AUTHOR
105              
106             Smal D A, Emialinx@gmail.comE
107              
108             =head1 COPYRIGHT AND LICENSE
109              
110             Copyright (C) 2009 by Smal D A
111              
112             This library is free software; you can redistribute it and/or modify
113             it under the same terms as Perl itself, either Perl version 5.8.8 or,
114             at your option, any later version of Perl 5 you may have available.
115              
116             =cut
117