File Coverage

blib/lib/Date/Holidays/PL.pm
Criterion Covered Total %
statement 68 68 100.0
branch 4 4 100.0
condition n/a
subroutine 18 18 100.0
pod 4 4 100.0
total 94 94 100.0


line stmt bran cond sub pod time code
1             package Date::Holidays::PL;
2             BEGIN {
3 1     1   253546 $Date::Holidays::PL::AUTHORITY = 'cpan:AJGB';
4             }
5             BEGIN {
6 1     1   17 $Date::Holidays::PL::VERSION = '1.110050';
7             }
8             # ABSTRACT: Determine holidays for Poland
9              
10 1     1   9 use strict;
  1         2  
  1         35  
11 1     1   6 use warnings;
  1         2  
  1         30  
12 1     1   6 use utf8;
  1         1  
  1         8  
13              
14 1     1   24 use parent qw( Date::Holidays::Abstract );
  1         2  
  1         15  
15              
16 1     1   13059 use DateTime;
  1         3  
  1         28  
17 1     1   5 use Params::Validate qw( validate validate_pos SCALAR BOOLEAN OBJECT );
  1         18  
  1         91  
18 1     1   820 use Date::Easter qw( gregorian_easter );
  1         3968  
  1         59  
19 1     1   7 use Try::Tiny;
  1         3  
  1         73  
20              
21 1         10 use Sub::Exporter -setup => {
22             exports => [
23             qw( pl_holidays is_pl_holiday pl_holidays_dt is_pl_holiday_dt ),
24             ],
25 1     1   1042 };
  1         4730  
26              
27              
28             # holidays always present
29             my %SharedHolidays = map {
30             $_ => 1
31             } qw( 0101 0501 1101 1225 1226 );
32              
33             # law changes in 1951, 1960, 1989, 1990 and 2011
34             my %ChangesByYear = (
35             (
36             map {
37             $_ => {
38             %SharedHolidays,
39             map { $_ => 1 } qw( 0106 0722 0815 )
40             }
41             } (1951 .. 1959),
42             ),
43             (
44             map {
45             $_ => {
46             %SharedHolidays,
47             map { $_ => 1 } qw( 0722 )
48             }
49             } (1960 .. 1988),
50             ),
51             1989 => {
52             %SharedHolidays,
53             map { $_ => 1 } qw( 0722 0815 1111 )
54             },
55             # since 1990
56             1990 => {
57             %SharedHolidays,
58             map { $_ => 1 } qw( 0503 0815 1111 )
59             },
60             # since 2011
61             'CURRENT' => {
62             %SharedHolidays,
63             map { $_ => 1 } qw( 0106 0503 0815 1111 )
64             },
65             );
66             # always on those dates
67             my %FixedHolidays = (
68             # New Year's Day
69             '0101' => 'Nowy Rok',
70             # Epiphany (1951-1959 only)
71             '0106' => 'Trzech Króli',
72             # Labor Day
73             '0501' => 'Święto Państwowe',
74             # Constitution Day ( since 1990 )
75             '0503' => 'Święto Narodowe Trzeciego Maja',
76             # Polish Committee of National Liberation Manifesto (1951-1989 only)
77             '0722' => 'Święto Odrodzenia Polski',
78             # Assumption of the Blessed Virgin Mary ( 1951-1959, 1989+ )
79             '0815' => 'Wniebowzięcie Najświętszej Maryi Panny',
80             # All Saints' Day
81             '1101' => 'Wszystkich Świętych',
82             # Independence Day ( since 1989 )
83             '1111' => 'Narodowe Święto Niepodległości',
84             # Christmas Day
85             '1225' => 'pierwszy dzień Bożego Narodzenia',
86             # Boxing Day
87             '1226' => 'drugi dzień Bożego Narodzenia',
88             );
89              
90             # Params::Validate config
91             my $ValidateOpts = {
92             year => {
93             type => SCALAR,
94             regex => qr/^\d{4}$/,
95             callbacks => {
96             'between 1951 and 9999' => sub {
97             shift >= 1951
98             },
99             },
100             },
101             month => {
102             type => SCALAR,
103             },
104             day => {
105             type => SCALAR,
106             },
107             WEEKENDS => {
108             type => BOOLEAN,
109             default => 1,
110             optional => 1,
111             }
112             };
113              
114              
115             sub pl_holidays {
116 64     64 1 8309 my ($year) = validate_pos(@{[shift]},
  64         811  
117             $ValidateOpts->{year},
118             );
119 60         1450 my %args = validate(@_,
120             {
121             WEEKENDS => $ValidateOpts->{WEEKENDS},
122             }
123             );
124              
125 60 100       353 my $y = exists $ChangesByYear{$year} ? $year : 'CURRENT';
126              
127 468         1435 my $holidays = {
128             _compute_movablefeasts_for_year( $year ),
129             map {
130 60         124814 $_ => $FixedHolidays{$_}
131 60         157 } keys %{ $ChangesByYear{$y} },
132             };
133              
134 60 100       1183 unless ( $args{WEEKENDS} ) {
135 118         1109 my @weekend_holidays = grep {
136 10         44 my ($m, $d) = unpack "A2A2", $_;
137              
138 118         416 my $dt = DateTime->new(
139             year => $year,
140             month => $m,
141             day => $d
142             );
143              
144 118         22580 $dt->day_of_week >= 6;
145             } keys %$holidays;
146              
147 10         111 delete @{$holidays}{ @weekend_holidays };
  10         35  
148             }
149              
150 60         240 return $holidays;
151             };
152              
153              
154             sub pl_holidays_dt {
155 11     11 1 911 my $year = shift;
156 11         32 my $holidays = pl_holidays($year, @_);
157              
158             return +{
159 97         38054 map {
160 10         44 my ($m, $d) = unpack "A2A2", $_;
161 97         186 my $name = $holidays->{$_};
162              
163 97         337 $name => DateTime->new(
164             year => $year,
165             month => $m,
166             day => $d
167             );
168             } keys %$holidays
169             }
170             }
171              
172              
173             sub is_pl_holiday {
174 22         342 my ($year, $month, $day) = validate_pos(@_,
175 22     22 1 143395 @{$ValidateOpts}{qw(year month day)}
176             );
177              
178 21         402 my $dt;
179              
180             # let DateTime validate the date - no need to validate twice
181             try {
182 21     21   786 $dt = DateTime->new(
183             year => $year,
184             month => $month,
185             day => $day,
186             );
187             } catch {
188 1     1   469 die "Date $year-$month-$day is invalid: $_";
189 21         251 };
190              
191 20         4309 my $holidays = pl_holidays( $year );
192              
193 20         74 my $md = $dt->strftime('%m%d');
194 20         789 return $holidays->{$md};
195             }
196              
197              
198             sub is_pl_holiday_dt {
199 21     21 1 1263 my ($dt) = validate_pos(@_,
200             {
201             type => OBJECT,
202             isa => 'DateTime',
203             }
204             );
205              
206 21         666 my $holidays = pl_holidays( $dt->year );
207              
208 20         82 my $md = $dt->strftime('%m%d');
209 20         782 return $holidays->{$md};
210             }
211              
212             # calculate moveable feast for given year
213             sub _compute_movablefeasts_for_year {
214 60     60   122 my $year = shift;
215              
216             # already calculated
217              
218 60         265 my @easter_md = map { sprintf('%02d', $_ ) } gregorian_easter( $year );
  120         1565  
219              
220 60         275 my $easter = DateTime->new(
221             year => $year,
222             month => $easter_md[0],
223             day => $easter_md[1],
224             );
225              
226             return (
227             # Easter Sunday
228 60         12068 $easter->strftime('%m%d') =>
229             'pierwszy dzień Wielkanocy',
230             # Easter Monday
231             $easter->clone->add( days => 1)->strftime('%m%d') =>
232             'drugi dzień Wielkanocy',
233             # Pentecoste Sunday
234             $easter->clone->add( days => 49)->strftime('%m%d') =>
235             'pierwszy dzień Zielonych Świątek',
236             # Corpus Christi
237             $easter->clone->add( days => 60)->strftime('%m%d') =>
238             'dzień Bożego Ciała',
239             );
240             }
241              
242              
243              
244              
245             1;
246              
247             __END__