File Coverage

blib/lib/Class/Date/Rel.pm
Criterion Covered Total %
statement 72 88 81.8
branch 30 40 75.0
condition 20 28 71.4
subroutine 17 25 68.0
pod 0 17 0.0
total 139 198 70.2


line stmt bran cond sub pod time code
1             package Class::Date::Rel;
2 7     7   36 use strict;
  7         15  
  7         225  
3 7     7   35 use warnings;
  7         15  
  7         240  
4              
5 7     7   39 use vars qw(@NEW_FROM_SCALAR);
  7         12  
  7         270  
6 7     7   69 use Class::Date::Const;
  7         13  
  7         1562  
7 7     7   44 use Scalar::Util qw(blessed);
  7         13  
  7         471  
8              
9             our $VERSION = '1.1.15';
10              
11 7     7   36 use constant SEC_PER_MONTH => 2_629_744;
  7         12  
  7         1544  
12              
13             # see the ClassDateRel const in package Class::Date
14 7     7   48 use constant ClassDate => "Class::Date";
  7         33  
  7         690  
15              
16             use overload
17 7         53 '0+' => "sec",
18             '""' => "sec",
19             '<=>' => "compare",
20             'cmp' => "compare",
21             '+' => "add",
22             'neg' => "neg",
23 7     7   16351 fallback => 1;
  7         10745  
24            
25 73     73 0 14689 sub new { my ($proto,$val)=@_;
26 73   66     253 my $class = ref($proto) || $proto;
27 73 50       189 return undef if !defined $val;
28 73 100 66     432 if (blessed($val) && $val->isa( __PACKAGE__ )) {
    100          
    100          
    50          
29 2         9 return $class->new_copy($val);
30             } elsif (ref($val) eq 'ARRAY') {
31 4         16 return $class->new_from_array($val);
32             } elsif (ref($val) eq 'HASH') {
33 8         30 return $class->new_from_hash($val);
34             } elsif (ref($val) eq 'SCALAR') {
35 0         0 return $class->new_from_scalar($$val);
36             } else {
37 59         188 return $class->new_from_scalar($val);
38             };
39             }
40              
41 2     2 0 6 sub new_copy { my ($s,$val)=@_;
42 2   33     19 return bless([@$val], ref($s)||$s);
43             }
44              
45 82     82 0 132 sub new_from_array { my ($s,$val) = @_;
46 82         175 my ($y,$m,$d,$hh,$mm,$ss) = @$val;
47 82   100     1408 return bless([ ($y || 0) * 12 + $m , ($ss || 0) +
      100        
      100        
      100        
      100        
      66        
48             60*(($mm || 0) + 60*(($hh || 0) + 24* ($d || 0))) ], ref($s)||$s);
49             }
50              
51 21     21 0 37 sub new_from_hash { my ($s,$val) = @_;
52 21         78 $s->new_from_array(Class::Date::_array_from_hash($val));
53             }
54              
55 59     59 0 94 sub new_from_scalar { my ($s,$val)=@_;
56 59         154 for (my $i=0;$i<@NEW_FROM_SCALAR;$i++) {
57 59         136 my $ret=$NEW_FROM_SCALAR[$i]->($s,$val);
58 59 50       392 return $ret if defined $ret;
59             }
60 0         0 return undef;
61             }
62              
63 59     59 0 85 sub new_from_scalar_internal { my ($s,$val)=@_;
64 59 50       107 return undef if !defined $val;
65 59 100 33     395 return bless([0,$1],ref($s) || $s)
66             if $val =~ / ^ \s* ( \-? \d+ ( \. \d* )? ) \s* $/x;
67              
68 57 100       195 if ($val =~ m{ ^\s* ( \d{1,4} ) - ( \d\d? ) - ( \d\d? )
69             ( \s+ ( \d\d? ) : ( \d\d? ) ( : ( \d\d? )? (\.\d+)? )? )? }x ) {
70             # ISO date
71 22         85 my ($y,$m,$d,$hh,$mm,$ss)=($1,$2,$3,$5,$6,$8);
72 22         103 return $s->new_from_array([$y,$m,$d,$hh,$mm,$ss]);
73             }
74              
75 35         140 my ($y,$m,$d,$hh,$mm,$ss)=(0,0,0,0,0,0);
76 35         983 $val =~ s{ \G \s* ( \-? \d+) \s* (Y|M|D|h|m|s) }{
77 67         141 my ($num,$cmd)=($1,$2);
78 67 100       232 if ($cmd eq 'Y') {
    100          
    100          
    100          
    100          
    50          
79 16         26 $y=$num;
80             } elsif ($cmd eq 'M') {
81 15         90 $m=$num;
82             } elsif ($cmd eq 'D') {
83 14         20 $d=$num;
84             } elsif ($cmd eq 'h') {
85 8         12 $hh=$num;
86             } elsif ($cmd eq 'm') {
87 8         12 $mm=$num;
88             } elsif ($cmd eq 's') {
89 6         9 $ss=$num;
90             }
91 67         196 "";
92             }gexi;
93 35         159 return $s->new_from_array([$y,$m,$d,$hh,$mm,$ss]);
94             }
95              
96             push @NEW_FROM_SCALAR,\&new_from_scalar_internal;
97              
98 32     32 0 3132 sub compare { my ($s,$val2,$reverse) = @_;
99 32 100       70 my $rev_multiply=$reverse ? -1 : 1;
100 32 100 66     137 if (blessed($val2) && $val2->isa( __PACKAGE__ )) {
101 2         11 return ($s->sec <=> $val2->sec) * $rev_multiply;
102             } else {
103 30         164 my $date_obj=$s->new($val2);
104 30 50       67 return ($s->sec <=> 0) * $rev_multiply if !defined $date_obj;
105 30         72 return ($s->sec <=> $date_obj->sec) * $rev_multiply;
106             }
107             }
108              
109 0     0 0 0 sub add { my ($s,$val2)=@_;
110 0 0       0 if (my $reldate=$s->new($val2)) {
111 0         0 my $months=$s->[cs_mon] + $reldate->[cs_mon];
112 0         0 my $secs =$s->[cs_sec] + $reldate->[cs_sec];
113 0 0       0 return $s->new_from_hash({ month => $months, sec => $secs }) if $months;
114 0         0 return $secs;
115             } else {
116 0         0 return $s;
117             }
118             }
119              
120 13     13 0 20 sub neg { my ($s)=@_;
121 13         78 return $s->new_from_hash({
122             month => -$s->[cs_mon],
123             sec => -$s->[cs_sec]
124             });
125             }
126              
127 0     0 0 0 sub year { shift->sec / (SEC_PER_MONTH*12) }
128 0     0 0 0 sub mon { shift->sec / SEC_PER_MONTH }
129             *month = *mon;
130 0     0 0 0 sub day { shift->sec / (60*60*24) }
131 0     0 0 0 sub hour { shift->sec / (60*60) }
132 0     0 0 0 sub min { shift->sec / 60 }
133             *minute = *min;
134 64     64 0 80 sub sec { my ($s)=@_; $s->[cs_sec] + SEC_PER_MONTH * $s->[cs_mon]; }
  64         436  
135             *second = *sec;
136              
137 0     0 0   sub sec_part { shift->[cs_sec] }
138             *second_part = *sec_part;
139 0     0 0   sub mon_part { shift->[cs_mon] }
140             *month_part = *mon_part;
141              
142             1;
143