File Coverage

blib/lib/Date/Holidays/BQ.pm
Criterion Covered Total %
statement 73 74 98.6
branch 27 30 90.0
condition 13 20 65.0
subroutine 11 11 100.0
pod 3 3 100.0
total 127 138 92.0


line stmt bran cond sub pod time code
1             our $VERSION = '0.002';
2             use strict;
3 1     1   86949 use warnings;
  1         11  
  1         25  
4 1     1   4  
  1         1  
  1         24  
5             # ABSTRACT: Bonaire's official holidays
6              
7             use Exporter qw(import);
8 1     1   5  
  1         1  
  1         41  
9             our @EXPORT = qw(
10             holidays
11             is_holiday
12             is_holiday_dt
13             );
14              
15             use base qw(Date::Holidays::Abstract);
16 1     1   7 use DateTime::Event::Easter;
  1         1  
  1         378  
17 1     1   7195 use DateTime;
  1         492785  
  1         43  
18 1     1   7  
  1         2  
  1         832  
19             my %FIXED_DATES = (
20             newyears => {
21             m => 1,
22             d => 1,
23             pap => "A\x{00f1}a Nobo",
24             nl => 'Nieuwjaarsdag',
25             en => 'New years day',
26             },
27             rincon => {
28             m => 4,
29             d => 30,
30             pap => 'Dia di Rincon',
31             nl => 'Dag van Rincon',
32             en => 'Rincon day',
33             },
34             kingdom => {
35             m => 12,
36             d => 15,
37             pap => 'Dia di Reino',
38             nl => 'Dag van het koninkrijk',
39             en => 'Kingdom day',
40             },
41             flagday => {
42             m => 9,
43             d => 6,
44             pap => 'Dia di Boneiru',
45             nl => 'Bonairedag',
46             en => 'Bonaire Flag day',
47             },
48             wimlex => {
49             m => 4,
50             d => 27,
51             nl => 'Koningsdag',
52             en => 'Kings day',
53             pap => 'Dia di Rei',
54              
55             # change day of week if it falls on a sunday
56             dow => { 7 => -1 },
57             year_started => 2014,
58             },
59             'minna-princess' => {
60             m => 8,
61             d => 31,
62             nl => 'Prinsessedag',
63             en => "Princess's day",
64             pap => 'Dia di Prensesa',
65              
66             # change day of week if it falls on a sunday
67             dow => { 7 => 1 },
68             year_started => 1885,
69             year_ended => 1890,
70             },
71             'minna-queen' => {
72             m => 8,
73             d => 31,
74             nl => 'Koninginnedag',
75             en => "Queen's day",
76             pap => 'Dia di Reina',
77              
78             # change day of week if it falls on a sunday
79             dow => { 7 => 1 },
80             year_started => 1891,
81             year_ended => 1948,
82             },
83             'juliana-beatrix' => {
84             m => 4,
85             d => 30,
86             nl => 'Koninginnedag',
87             en => "Queen's day",
88             pap => 'Dia di Reina',
89              
90             # change day of week if it falls on a sunday
91             dow => { 7 => 1 },
92             year_started => 1949,
93             year_ended => 1979,
94             },
95             'juliana-beatrix-2' => {
96             m => 4,
97             d => 30,
98             nl => 'Koninginnedag',
99             en => "Queen's day",
100             pap => 'Dia di Reina',
101              
102             # change day of week if it falls on a sunday
103             dow => { 7 => -1 },
104             year_started => 1980,
105             year_ended => 2013,
106             },
107             # https://wetten.overheid.nl/BWBR0002448/2010-10-10
108             # This is a gov-only day
109             liberation => {
110             m => 5,
111             d => 5,
112             pap => 'Dia di liberation',
113             nl => 'Bevrijdingsdag',
114             en => 'Liberation day',
115             gov => 1,
116             },
117             labor => {
118             m => 5,
119             d => 1,
120             pap => 'Dia di Labor/Dia di Obrero',
121             nl => 'Dag van de arbeid',
122             en => 'Labor day',
123             },
124             xmas => {
125             m => 12,
126             d => 25,
127             pap => 'Pasco di Nacemento',
128             nl => 'Kerst',
129             en => 'Christmas',
130             },
131             boxing => {
132             m => 12,
133             d => 26,
134             pap => 'Di dos dia di Pasco di Nacemento',
135             nl => 'Tweede kerstdag',
136             en => 'Boxing day',
137             },
138             );
139              
140             my %EASTER_BASED = (
141             'carnaval' => {
142             d => -31 - 16 - 2, # 49
143             pap => 'Prome dia di Carnaval',
144             nl => 'Eerste carnavalsdag',
145             en => 'First day of carnaval',
146             },
147             goodfri => {
148             d => -2,
149             pap => 'Bierna Santo',
150             nl => 'Goede vrijdag',
151             en => 'Good friday',
152             },
153             easter => {
154             d => 0,
155             pap => 'Pasku Grandi',
156             nl => 'Pasen',
157             en => 'Easter',
158             },
159             easter2 => {
160             d => 1,
161             pap => 'Pasku Grandi',
162             nl => 'Tweede paasdag',
163             en => 'Second day of easter',
164             },
165             ascension => {
166             d => 40,
167             pap => 'Dia di asuncion',
168             nl => 'Hemelvaartsdag',
169             en => 'Ascension day',
170             },
171             pentecost => {
172             d => 49,
173             pap => "Pentek\x{00f2}ste",
174             nl => 'Pinksteren',
175             en => 'Pentecost',
176             },
177             pentecost2 => {
178             d => 50,
179             pap => "Dia dos di Pentek\x{00f2}ste",
180             nl => 'Tweede pinksterdag',
181             en => 'pentecost',
182             gov => 1,
183             },
184             );
185              
186             my %cache;
187              
188             my $year = shift;
189             my %args = @_;
190 21     21 1 924  
191 21         32 $year //= DateTime->now()->year;
192              
193 21   66     48 my $key = $year;
194             if ($args{gov}) {
195 21         269 $key .= 'gov';
196 21 100       40 }
197 3         7  
198             return $cache{$key} if $cache{$key};
199              
200 21 100       53 my %h;
201             foreach (keys %FIXED_DATES) {
202 9         11 my $holiday = $FIXED_DATES{$_};
203 9         36  
204 117         878 if (my $end = $holiday->{year_ended}) {
205             next if $year > $end;
206 117 100       193 }
207 36 100       62 if (my $start = $holiday->{year_started}) {
208             next if $year < $start;
209 87 100       141 }
210 15 100       25  
211             if (my $int = $holiday->{interval}) {
212             next if !$args{gov} && $year % $int != 0;
213 81 50 66     241 }
    100          
214 0 0 0     0 # Skip government only holidays
215             # This is due to "Algemene termijnwet" which is also valid on the BES
216             # islands: https://wetten.overheid.nl/BWBR0002448/2010-10-10
217             elsif (!$args{gov} && $holiday->{gov}) {
218             next;
219             }
220 8         14  
221             my $dt = _to_date($holiday->{d}, $holiday->{m}, $year);
222              
223 73         132 if (my $dow = $holiday->{dow}) {
224             my $cur = $dt->dow();
225 73 100       19375 foreach (keys %$dow) {
226 9         22 next unless $cur == $_;
227 9         36 $dt->add(days => $dow->{$_});
228 9 100       23 last;
229 3         16 }
230 3         2162 }
231              
232             _to_holidays(\%h, $dt, $holiday);
233             }
234 73         143  
235             my $dt = _to_date(1, 1, $year);
236             foreach (keys %EASTER_BASED) {
237 9         19 my $holiday = $EASTER_BASED{$_};
238 9         2268 next if !$args{gov} && $holiday->{gov};
239 63         700  
240 63 100 100     218 my $easter = DateTime::Event::Easter->new(
241             easter => 'western',
242             day => $holiday->{d}
243             );
244             my $dt = $easter->following($dt);
245 55         151 _to_holidays(\%h, $dt, $holiday);
246 55         7626 }
247 55         91806  
248             $cache{$key} = \%h;
249              
250 9         134 return \%h;
251             }
252 9         33  
253             my ($cache, $dt, $info) = @_;
254             $cache->{ sprintf("%02i", $dt->day) . sprintf("%02i", $dt->month) }
255             = [map { $info->{$_} } qw(pap nl en)];
256 128     128   223 }
257              
258 128         207 my ($day, $month, $year) = @_;
  384         843  
259             return DateTime->new(
260             day => $day,
261             month => $month,
262 99     99   143 year => $year,
263 99         241 hour => 0,
264             minute => 0,
265             second => 0,
266             time_zone => 'UTC',
267             );
268             }
269              
270             my $year = shift;
271             my $month = shift;
272             my $day = shift;
273              
274             my $dt = _to_date($day, $month, $year);
275 17     17 1 3454 return is_holiday_dt($dt, @_);
276 17         35 }
277 17         20  
278             my $dt = shift;
279 17         28  
280 17         4656 my %args = @_;
281              
282             my $holidays = holidays($dt->year, @_);
283             my $key = sprintf("%02i", $dt->day) . sprintf("%02i", $dt->month);
284 18     18 1 261  
285             if (exists $holidays->{$key}) {
286 18         29 my $lang = lc(delete $args{lang} // 'pap');
287             if ($lang eq 'nl' || $lang eq 'nld') {
288 18         39 return $holidays->{$key}[1];
289 18         42 }
290             if ($lang eq 'en' || $lang eq 'eng') {
291 18 100       162 return $holidays->{$key}[2];
292 16   100     53 }
293 16 100 66     51  
294 3         19 # default to pap
295             return $holidays->{$key}[0];
296 13 100 66     34 }
297 1         5 return;
298             }
299              
300             "Diver's paradise";
301 12         75  
302              
303 2         12 =pod
304              
305             =encoding UTF-8
306              
307             =head1 NAME
308              
309             Date::Holidays::BQ - Bonaire's official holidays
310              
311             =head1 VERSION
312              
313             version 0.002
314              
315             =head1 SYNOPSIS
316              
317             use Date::Holidays::BQ;
318              
319             if (my $thing = is_holiday(2020, 4, 30, lang => 'en')) {
320             print "It is $thing!", $/; # prints 'It is Bonaire Flag day!'
321             }
322              
323             =head1 DESCRIPTION
324              
325             A L<Date::Holidays> family member from Bonaire
326              
327             =head1 METHODS
328              
329             This module implements the C<is_holiday> and C<holiday> functions from
330             L<Date::Holidays::Abstract>.
331              
332             =head2 is_holiday(yyyy, mm, dd, %additional)
333              
334             is_holiday(
335             '2020', '4', '30',
336             gov => 1, # Important for government institutions
337             lang => 'en' # defaults to pap, alternatively nl/nld or en/eng can be used.
338             );
339              
340             =head2 is_holiday_dt(dt, %additional)
341              
342             is_holiday_dt(
343             DateTime->new(
344             year => 2020,
345             month => 4,
346             day => 30,
347             time_zone => 'America/Curacao',
348             ),
349             gov => 1, # Important for government institutions
350             lang => 'en' # defaults to pap, alternatively nl/nld or en/eng can be used.
351             );
352              
353             =head2 holidays(yyyy, gov => 1)
354              
355             holidays('2022', gov => 1);
356              
357             Similar API to the other functions, returns an hashref for the year.
358              
359             =head1 UTF-8
360              
361             Be aware that we return UTF-8 when Papiamento is chosen. So make sure you set
362             your enconding to UTF-8, otherwise you may see weird things.
363              
364             =head1 SEE ALSO
365              
366             =over
367              
368             =item https://wetten.overheid.nl/BWBR0002448/2010-10-10
369              
370             =back
371              
372             =head1 AUTHOR
373              
374             Wesley Schwengle <waterkip@cpan.org>
375              
376             =head1 COPYRIGHT AND LICENSE
377              
378             This software is Copyright (c) 2022 by Wesley Schwengle.
379              
380             This is free software, licensed under:
381              
382             The (three-clause) BSD License
383              
384             =cut