File Coverage

blib/lib/Date/Lectionary/Time.pm
Criterion Covered Total %
statement 74 82 90.2
branch 20 24 83.3
condition 6 12 50.0
subroutine 16 20 80.0
pod 4 4 100.0
total 120 142 84.5


line stmt bran cond sub pod time code
1             package Date::Lectionary::Time;
2              
3 5     5   313568 use v5.22;
  5         13  
4 5     5   18 use strict;
  5         5  
  5         79  
5 5     5   16 use warnings;
  5         9  
  5         179  
6              
7 5     5   2108 use Exporter::Easy ( OK => [qw(nextSunday prevSunday closestSunday isSunday)], );
  5         5213  
  5         30  
8              
9 5     5   516 use Carp;
  5         6  
  5         266  
10 5     5   2080 use Try::Tiny;
  5         7585  
  5         238  
11 5     5   486 use Time::Piece;
  5         8480  
  5         26  
12 5     5   332 use Time::Seconds;
  5         8  
  5         2738  
13              
14             =head1 NAME
15              
16             Date::Lectionary::Time - Find your way in time relative to Sundays.
17              
18             =head1 VERSION
19              
20             Version 1.20170311
21              
22             =cut
23              
24             our $VERSION = '1.20170311';
25              
26             =head1 SYNOPSIS
27              
28             Working in the liturgical time of the lectionary means tracking time relative to Sundays. This is a quick utility to find the next, previous, or the closest Sunday to a given date. Further, it can determine if the date given is a Sunday or not.
29              
30             use Time::Piece;
31             use Date::Lectionary::Time qw(nextSunday prevSunday closestSunday isSunday);
32              
33             my $christmasDay = Time::Piece->strptime("2015-12-25", "%Y-%m-%d");
34              
35             if (isSunday($christmasDay)) {
36             say "Christmas is on a Sunday!";
37             }
38             else {
39             say "Christmas isn't on a Sunday.";
40             }
41              
42             my $sundayAfterChristmas = nextSunday($christmasDay);
43             my $sundayBeforeChristmas = prevSunday($christmasDay);
44             my $sundayClosestToChristmas = closestSunday($christmasDay);
45              
46             =head1 EXPORTS
47              
48             nextSunday
49              
50             prevSunday
51              
52             closestSunday
53              
54             isSunday
55              
56             use Date::Lectionary::Time qw(nextSunday prevSunday closestSunday isSunday);
57              
58             =head1 SUBROUTINES/METHODS
59              
60             =head2 nextSunday
61              
62             For a given Time::Piece date returns a Time::Piece object of the date of the Sunday immediately following the given date.
63              
64             =cut
65              
66             sub nextSunday {
67 11     11 1 3428 my ( $class, @params ) = @_;
68 11   66     91 my $date = $params[0] // $class;
69 11         122 my $nextSunday = undef;
70              
71 11 100       21 if ( !length $date ) {
72 1         8 croak
73             "Method [nextSunday] expects an input argument of type Time::Piece. The given type could not be determined.";
74             }
75              
76 10 100       103 if ( $date->isa('Time::Piece') ) {
77             try {
78 9     9   409 my $daysToAdd = 7 - $date->_wday;
79 9         31 my $secondsToAdd = $daysToAdd * ONE_DAY;
80 9         18 $nextSunday = $date + $secondsToAdd;
81             }
82             catch {
83 0     0   0 croak "Could not calculate the next Sunday after $date.";
84 9         48 };
85             }
86             else {
87 1         19 croak
88             "Method [nextSunday] expects an input argument of type Time::Piece.";
89             }
90              
91 9         546 return $nextSunday;
92             }
93              
94             =head2 prevSunday
95              
96             For a given Time::Piece date returns a Time::Piece object of the date of the Sunday immediately before the given date.
97              
98             =cut
99              
100             sub prevSunday {
101 11     11 1 3438 my ( $class, @params ) = @_;
102 11   66     86 my $date = $params[0] // $class;
103 11         120 my $prevSunday = undef;
104              
105 11 100       17 if ( !length $date ) {
106 1         8 croak
107             "Method [prevSunday] expects an input argument of type Time::Piece. The given type could not be determined.";
108             }
109              
110 10 100       106 if ( $date->isa('Time::Piece') ) {
111             try {
112 9     9   396 my $daysToSubtract = $date->_wday;
113 9 100       41 if ( $daysToSubtract == 0 ) { $daysToSubtract = 7; }
  2         3  
114 9         10 my $secondsToSubtract = $daysToSubtract * ONE_DAY;
115 9         21 $prevSunday = $date - $secondsToSubtract;
116             }
117             catch {
118 0     0   0 carp "Could not calculate the previous Sunday before $date.";
119 9         48 };
120             }
121             else {
122 1         18 croak
123             "Method [prevSunday] expects an input argument of type Time::Piece.";
124             }
125              
126 9         499 return $prevSunday;
127             }
128              
129             =head2 closestSunday
130              
131             For a given Time::Piece date returns a Time::Piece object of the date of the Sunday closest to the given date.
132              
133             =cut
134              
135             sub closestSunday {
136 4     4 1 2024 my ( $class, @params ) = @_;
137 4   33     63 my $date = $params[0] // $class;
138 4         55 my $closestSunday = undef;
139              
140 4 50       9 if ( !length $date ) {
141 0         0 croak
142             "Method [closestSunday] expects an input argument of type Time::Piece. The given type could not be determined.";
143             }
144              
145 4 50       46 if ( $date->isa('Time::Piece') ) {
146             try {
147 4     4   197 my $nextSunday = nextSunday($date);
148 4         9 my $prevSunday = prevSunday($date);
149              
150 4         5 my ( $dif1, $dif2 );
151              
152 4         6 $dif1 = abs( $date - $nextSunday );
153 4         174 $dif2 = abs( $prevSunday - $date );
154              
155 4 100       125 if ( $dif1 < $dif2 ) {
    100          
156 2         28 $closestSunday = $nextSunday;
157             }
158             elsif ( $dif1 == $dif2 ) {
159 1         20 $closestSunday = $date;
160             }
161             else {
162 1         19 $closestSunday = $prevSunday;
163             }
164             }
165             catch {
166 0     0   0 carp "Could not calculate the Sunday closest to $date.";
167 4         24 };
168             }
169             else {
170 0         0 croak
171             "Method [closestSunday] expects an input argument of type Time::Piece.";
172             }
173              
174 4         51 return $closestSunday;
175             }
176              
177             =head2 isSunday
178              
179             For a given Time::Piece date returns C<1> if the date is a Sunday or C<0> if the date isn't a Sunday.
180              
181             =cut
182              
183             sub isSunday {
184 3     3 1 696 my ( $class, @params ) = @_;
185 3   33     56 my $date = $params[0] // $class;
186 3         44 my $isSunday = 0;
187              
188 3 50       5 if ( !length $date ) {
189 0         0 croak
190             "Method [isSunday] expects an input argument of type Time::Piece. The given type could not be determined.";
191             }
192              
193 3 50       38 if ( $date->isa('Time::Piece') ) {
194             try {
195 3 100   3   155 if ($date->wday == 1) {
196 1         6 $isSunday = 1;
197             }
198             }
199             catch {
200 0     0   0 carp "Could not calculate the Sunday closest to $date.";
201 3         18 };
202             }
203             else {
204 0         0 croak
205             "Method [isSunday] expects an input argument of type Time::Piece.";
206             }
207              
208 3         53 return $isSunday;
209             }
210              
211             =head1 AUTHOR
212              
213             Michael Wayne Arnold, C<< >>
214              
215             =head1 BUGS
216              
217             Please report any bugs or feature requests to C, or through
218             the web interface at L. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
219              
220             =head1 SUPPORT
221              
222             You can find documentation for this module with the perldoc command.
223              
224             perldoc Date::Lectionary::Time
225              
226             The development of this module is hosted on GitHub -- L -- and tested via TravisCI.
227              
228             =for html
229              
230             =for html Coverage Status
231              
232             You can also look for information at:
233              
234             =over 4
235              
236             =item * RT: CPAN's request tracker (report bugs here)
237              
238             L
239              
240             =item * AnnoCPAN: Annotated CPAN documentation
241              
242             L
243              
244             =item * CPAN Ratings
245              
246             L
247              
248             =item * Search CPAN
249              
250             L
251              
252             =back
253              
254             =head1 ACKNOWLEDGEMENTS
255              
256             Many thanks to my beautiful wife, Jennifer, and my amazing daughter, Rosemary. But, above all, SOLI DEO GLORIA!
257              
258             =head1 LICENSE AND COPYRIGHT
259              
260             Copyright 2016 Michael Wayne Arnold.
261              
262             This program is free software; you can redistribute it and/or modify it
263             under the terms of either: the GNU General Public License as published
264             by the Free Software Foundation; or the Artistic License.
265              
266             See L for more information.
267              
268              
269             =cut
270              
271             1; # End of Date::Lectionary::Time