File Coverage

lib/Badger/Date.pm
Criterion Covered Total %
statement 30 51 58.8
branch 8 20 40.0
condition 2 6 33.3
subroutine 8 8 100.0
pod 5 6 83.3
total 53 91 58.2


line stmt bran cond sub pod time code
1             package Badger::Date;
2              
3             use Badger::Class
4 2         32 version => 0.03,
5             debug => 0,
6             import => 'class CLASS',
7             base => 'Badger::Period',
8             utils => 'numlike is_object',
9             accessors => 'uri',
10             constants => 'HASH',
11             constant => {
12             DATE => __PACKAGE__,
13             TYPE_NAME => 'date',
14             FIELD_NAMES => q{year month day},
15             split_regex => qr{(\d{4})\D(\d{1,2})\D(\d{1,2})},
16             join_format => q{%04d-%02d-%02d},
17             },
18             exports => {
19             any => 'DATE Date Today',
20 2     2   561 };
  2         5  
21              
22             our @YMD = qw( year month day );
23             our @CACHE = qw( date time etime longmonth longdate uri );
24              
25              
26             #-----------------------------------------------------------------------
27             # Method generator: year()/years(), month()/months(), day()/days()
28             #-----------------------------------------------------------------------
29              
30             class->methods(
31             map {
32             my $item = $_; # lexical copy for closure
33             my $items = $_ . 's'; # provide singular and plural versions
34             my $code = sub {
35 6 50   6   49 if (@_ > 1) {
36 0         0 $_[0]->{ $item } = $_[1];
37 0         0 $_[0]->join_uri;
38 0         0 return $_[0];
39             }
40 6         22 return $_[0]->{ $item };
41             };
42             $item => $code,
43             $items => $code
44             }
45             @YMD
46             );
47              
48              
49             #-----------------------------------------------------------------------
50             # Constructor subroutines
51             #-----------------------------------------------------------------------
52              
53             sub Date {
54             return @_
55 2 100   2 1 42 ? DATE->new(@_)
56             : DATE
57             }
58              
59             sub Today {
60 2     2 1 34 DATE->today;
61             }
62              
63              
64             #-----------------------------------------------------------------------
65             # Methods
66             #-----------------------------------------------------------------------
67              
68             sub today {
69 2     2 1 12 shift->new;
70             }
71              
72              
73             sub date {
74 1     1 1 7 shift->text;
75             }
76              
77              
78             sub adjust {
79 1     1 1 2 my $self = shift;
80 1         3 my ($args, $element, $dim);
81 1         1 my $fix_month = 0;
82              
83 1 50       4 if (@_ == 1) {
84             # single argument can be a reference to a hash: { days => 3, etc }
85             # or a number/string representing a duration: "3 days", "1 year"
86 0 0       0 $args = ref $_[0] eq HASH
87             ? shift
88             : { seconds => $self->duration(shift) };
89             }
90             else {
91             # multiple arguments are named parameters: days => 3, etc.
92 1         2 $args = { @_ };
93             }
94              
95             # If we're only adjusting by a month or a year, then we fix the day
96             # within the range of the number of days in the new month. For example:
97             # 2007-01-31 + 1 month = 2007-02-28. We must handle this for a year
98             # adjustment for the case: 2008-02-29 + 1 year = 2009-02-28
99 1 50 33     15 if ((scalar(keys %$args) == 1) &&
      33        
100             (defined $args->{ month } || defined $args->{ months } ||
101             defined $args->{ year } || defined $args->{ years })) {
102 0         0 $fix_month = 1;
103             }
104              
105 1         1 $self->debug("adjust: ", $self->dump_data($args)) if DEBUG;
106              
107             # allow each element to be singular or plural: day/days, etc.
108 1         4 foreach $element (@YMD) {
109             $args->{ $element } = $args->{ "${element}s" }
110 3 50       9 unless defined $args->{ $element };
111             }
112              
113             # adjust the time by the parameters specified
114 1         11 foreach $element (@YMD) {
115             $self->{ $element } += $args->{ $element }
116 3 100       9 if defined $args->{ $element };
117             }
118              
119             # Handle negative days/months/years
120 1         3 while ($self->{ day } <= 0) {
121 0         0 $self->{ month }--;
122 0 0       0 unless ($self->{ month } > 0) {
123 0         0 $self->{ month } += 12;
124 0         0 $self->{ year }--;
125             }
126 0         0 $self->{ day } += $self->days_in_month;
127             }
128 1         4 while ($self->{ month } <= 0) {
129 0         0 $self->{ month } += 12;
130 0         0 $self->{ year } --;
131             }
132 1         3 while ($self->{ month } > 12) {
133 0         0 $self->{ month } -= 12;
134 0         0 $self->{ year } ++;
135             }
136              
137             # handle day wrap-around
138 1         16 while ($self->{ day } > ($dim = $self->days_in_month)) {
139             # If we're adjusting by a single month or year and the day is
140             # greater than the number days in the new month, then we adjust
141             # the new day to be the last day in the month. Otherwise we
142             # increment the month and remove the number of days in the current
143             # month.
144 0 0       0 if ($fix_month) {
145 0         0 $self->{ day } = $dim;
146             }
147             else {
148 0         0 $self->{ day } -= $dim;
149 0 0       0 if ($self->{ month } == 12) {
150 0         0 $self->{ month } = 1;
151 0         0 $self->{ year }++;
152             }
153             else {
154 0         0 $self->{ month }++;
155             }
156             }
157             }
158              
159 1         5 $self->uncache;
160 1         4 $self->join_uri;
161              
162 1         4 return $self;
163             }
164              
165              
166             sub uncache {
167 1     1 0 1 my $self = shift;
168 1         5 delete @$self{@CACHE};
169 1         2 return $self;
170             }
171              
172              
173             1;
174             __END__