File Coverage

blib/lib/Pinwheel/Model/DateBase.pm
Criterion Covered Total %
statement 97 97 100.0
branch 56 56 100.0
condition 15 17 88.2
subroutine 36 36 100.0
pod 0 30 0.0
total 204 236 86.4


line stmt bran cond sub pod time code
1             package Pinwheel::Model::DateBase;
2              
3 8     8   24574 use strict;
  8         17  
  8         313  
4 8     8   46 use warnings;
  8         14  
  8         409  
5              
6 8     8   1067 use POSIX qw();
  8         8092  
  8         29107  
7              
8              
9             # Date/time values
10              
11 14     14 0 164 sub year { $_[0]->{t}[5] + 1900 }
12 18     18 0 119 sub month { $_[0]->{t}[4] + 1 }
13 82     82 0 870 sub day { $_[0]->{t}[3] }
14 4     4 0 66 sub mm { sprintf('%02d', $_[0]->{t}[4] + 1) }
15 4     4 0 34 sub dd { sprintf('%02d', $_[0]->{t}[3]) }
16 7     7 0 37 sub wday { $_[0]->{t}[6] }
17 3     3 0 19 sub yday { $_[0]->{t}[7] }
18              
19             sub bbc_year
20             {
21 82 100   82 0 569 $_[0]->_calculate_bbc_week if (!$_[0]->{bbc_week});
22 82         1155 return $_[0]->{bbc_year};
23             }
24              
25             sub bbc_week
26             {
27 82 100   82 0 223 $_[0]->_calculate_bbc_week if (!$_[0]->{bbc_week});
28 82         611 return $_[0]->{bbc_week};
29             }
30              
31             sub _calculate_bbc_week
32             {
33 78     78   328 my $adjust = 3 - (($_[0]->{t}[6] + 1) % 7);
34 78         474 my @t = gmtime($_[0]->{s} + ($adjust * 86400));
35 78         304 $_[0]->{bbc_year} = $t[5] + 1900;
36 78         269 $_[0]->{bbc_week} = int($t[7] / 7) + 1;
37             }
38              
39             sub iso_year
40             {
41 82 100   82 0 579 $_[0]->_calculate_iso_week if (!$_[0]->{iso_week});
42 82         274 return $_[0]->{iso_year};
43             }
44              
45             sub iso_week
46             {
47 82 100   82 0 238 $_[0]->_calculate_iso_week if (!$_[0]->{iso_week});
48 82         603 return $_[0]->{iso_week};
49             }
50              
51             sub iso_weekday
52             {
53 18   100 18 0 208 return $_[0]->{t}[6] || 7;
54             }
55              
56             sub _calculate_iso_week
57             {
58 78     78   220 my $adjust = 3 - (($_[0]->{t}[6] - 1) % 7);
59 78         341 my @t = gmtime($_[0]->{s} + ($adjust * 86400));
60 78         249 $_[0]->{iso_year} = $t[5] + 1900;
61 78         281 $_[0]->{iso_week} = int($t[7] / 7) + 1;
62             }
63              
64             sub days_in_month
65             {
66 30     30 0 12242 my ($y, $m);
67              
68 30         70 $y = $_[0]->{t}[5] + 1900;
69 30         52 $m = $_[0]->{t}[4];
70 30 100       169 return (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[$m] if ($m != 1);
71 8 100 66     97 return (!($y % 4) && (($y % 100) || !($y % 400))) ? 29 : 28;
72             }
73              
74              
75             # Formatting
76              
77             sub month_name
78             {
79 24     24 0 277 return qw(
80             January February March April May June July
81             August September October November December
82             )[$_[0]->{t}[4]];
83             }
84              
85             sub short_month_name
86             {
87 34     34 0 266 return qw(
88             Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
89             )[$_[0]->{t}[4]];
90             }
91              
92             sub day_name
93             {
94 14     14 0 217 return qw(
95             Sunday Monday Tuesday Wednesday Thursday Friday Saturday
96             )[$_[0]->{t}[6]];
97             }
98              
99             sub short_day_name
100             {
101 24     24 0 142 return qw(Sun Mon Tue Wed Thu Fri Sat)[$_[0]->{t}[6]];
102             }
103              
104             sub day_suffix
105             {
106 124     124 0 801 my $day = $_[0]->{t}[3];
107 124 100 100     725 return 'th' if ($day >= 10 && $day < 20);
108 84         470 return qw(th st nd rd th th th th th th)[$day % 10];
109             }
110              
111             sub day_ordinal
112             {
113 62     62 0 263 return $_[0]->day . $_[0]->day_suffix;
114             }
115              
116             sub strftime
117             {
118 6     6 0 43 return POSIX::strftime($_[1], @{$_[0]->{t}});
  6         434  
119             }
120              
121              
122             # Date/time adjustment
123              
124             sub replace
125             {
126 37     37 0 225 my ($self, %values) = @_;
127 37         50 my ($ss, $mm, $hh, $d, $m, $y) = @{$self->{t}};
  37         104  
128              
129 37 100       114 $ss = $values{sec} if exists($values{sec});
130 37 100       81 $ss = 0 if $ss < 0; $ss = 59 if $ss > 59;
  37 100       262  
131 37 100       80 $mm = $values{min} if exists($values{min});
132 37 100       74 $mm = 0 if $mm < 0; $mm = 59 if $mm > 59;
  37 100       74  
133 37 100       85 $hh = $values{hour} if exists($values{hour});
134 37 100       70 $hh = 0 if $hh < 0; $hh = 23 if $hh > 23;
  37 100       76  
135              
136 37 100       85 $d = $values{day} if exists($values{day});
137 37 100       80 $m = $values{month} - 1 if exists($values{month});
138 37 100       76 $m = 0 if $m < 0; $m = 11 if $m > 11;
  37 100       69  
139 37 100       94 $y = exists($values{year}) ? $values{year} : $y + 1900;
140 37         79 $d = _correct_day($y, $m, $d);
141              
142 37         130 return $self->_derived($y, $m, $d, $hh, $mm, $ss);
143             }
144              
145             sub offset
146             {
147 41     41 0 173 my ($self, %deltas) = @_;
148 41         60 my ($i, $ss, $mm, $hh, $d, $m, $y) = (undef, @{$self->{t}});
  41         109  
149              
150 41 100       192 if (exists($deltas{days})) {
151 23         58 $i = $self->{s} + ((12 - $hh) * 3600) + ($deltas{days} * 86400);
152 23         99 ($d, $m, $y) = (gmtime $i)[3 .. 5];
153             }
154 41 100       116 if (exists($deltas{months})) {
155 14         30 $i = $m + $deltas{months};
156 14         24 $m = $i % 12;
157 14         34 $y += ($i - $m) / 12;
158             }
159 41         60 $y += 1900;
160 41 100       95 $y += $deltas{years} if exists($deltas{years});
161 41         89 $d = _correct_day($y, $m, $d);
162 41         152 return $self->_derived($y, $m, $d, $hh, $mm, $ss);
163             }
164              
165             sub next_day
166             {
167 2     2 0 38 return $_[0]->offset(days => 1);
168             }
169              
170             sub previous_day
171             {
172 2     2 0 13 return $_[0]->offset(days => -1);
173             }
174              
175             sub next_week
176             {
177 2     2 0 8 return $_[0]->offset(days => 7);
178             }
179              
180             sub previous_week
181             {
182 2     2 0 9 return $_[0]->offset(days => -7);
183             }
184              
185             sub next_month
186             {
187 2     2 0 10 return $_[0]->offset(months => 1);
188             }
189              
190             sub previous_month
191             {
192 4     4 0 19 return $_[0]->offset(months => -1);
193             }
194              
195             sub last_of_month
196             {
197 4     4 0 15 return $_[0]->replace(day => 31);
198             }
199              
200             sub first_of_month
201             {
202 2     2 0 34 return $_[0]->replace(day => 1);
203             }
204              
205             sub _correct_day
206             {
207 94     94   161 my ($y, $m, $d) = @_;
208 94         115 my $i;
209              
210 94 100       209 return 1 if $d < 1;
211              
212 92         143 $i = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[$m];
213 92 100       181 if ($d > $i) {
214             # XXX No year divisible by 100 and not 400 with a 32-bit time_t
215 38 100 100     218 $i++ if ($m == 1 && !($y % 4) && (($y % 100) || !($y % 400)));
      100        
      66        
216 38 100       101 $d = $i if $d > $i;
217             }
218 92         203 return $d;
219             }
220              
221              
222             1;
223              
224             __DATA__