File Coverage

blib/lib/Date/Holidays/GB.pm
Criterion Covered Total %
statement 96 103 93.2
branch 40 46 86.9
condition 11 20 55.0
subroutine 13 17 76.4
pod 4 9 44.4
total 164 195 84.1


line stmt bran cond sub pod time code
1              
2             our $VERSION = '0.021';
3              
4             # ABSTRACT: Determine British holidays - Current UK public and bank holiday dates up to 2023
5              
6             use strict;
7 4     4   534523 use warnings;
  4         43  
  4         99  
8 4     4   18 use utf8;
  4         8  
  4         82  
9 4     4   554  
  4         17  
  4         21  
10             use DateTime;
11 4     4   3286  
  4         1815498  
  4         199  
12             use base qw( Date::Holidays::Super Exporter );
13 4     4   37 our @EXPORT_OK = qw(
  4         8  
  4         1930  
14             holidays
15             gb_holidays
16             holidays_ymd
17             is_holiday
18             is_gb_holiday
19             next_holiday
20             next_gb_holiday
21             );
22              
23             # See
24             # http://en.wikipedia.org/wiki/ISO_3166-2
25             # http://en.wikipedia.org/wiki/ISO_3166-2:GB
26              
27             use constant REGION_NAMES => {
28 4         294 EAW => 'England & Wales',
29             SCT => 'Scotland',
30             NIR => 'Northern Ireland',
31             };
32 4     4   1059 use constant REGIONS => [ sort keys %{ +REGION_NAMES } ];
  4         10  
33 4     4   21  
  4         8  
  4         6  
  4         4673  
34             our %holidays;
35             set_holidays(\*DATA);
36              
37             my $fh = shift;
38             while (<$fh>) {
39 7     7 0 29082 chomp;
40 7         122 my ( $date, $region, $name ) = split /\t/;
41 1416         1782 next unless $date && $region && $name;
42 1416         3252  
43 1416 50 66     4253 my ( $y, $m, $d ) = split /-/, $date;
      66        
44             $holidays{$y}->{$date}->{$region} = $name;
45 1413         3054 }
46 1413         4659  
47             # Define an 'all' if all three regions have a holiday on this day, taking
48             # EAW name as the canonical name
49             while ( my ( $year, $dates ) = each %holidays ) {
50             foreach my $holiday ( values %{$dates} ) {
51 7         58 $holiday->{all} = $holiday->{EAW}
52 84         99 if keys %{$holiday} == @{ +REGIONS };
  84         189  
53             }
54 1113 100       1054 }
  1113         1419  
  1113         1832  
55             }
56              
57              
58             my %args
59 0     0 0 0 = $_[0] =~ m/\D/
60             ? @_
61             : ( year => $_[0], regions => $_[1] );
62 7 100   7 1 3801  
63             unless ( exists $args{year} && defined $args{year} ) {
64             $args{year} = ( localtime(time) )[5];
65             $args{year} += 1900;
66             }
67 7 50 33     36  
68 0         0 unless ( $args{year} =~ /^\d{4}$/ ) {
69 0         0 die "Year must be numeric and four digits, eg '2004'";
70             }
71              
72 7 50       26 # return if empty regions list (undef gets full list)
73 0         0 my @region_codes = @{ $args{regions} || REGIONS }
74             or return {};
75              
76             my %return;
77 7 100       11  
  7 50       32  
78             while ( my ( $date, $holiday ) = each %{ $holidays{ $args{year} } } ) {
79             my $string = _holiday( $holiday, \@region_codes )
80 7         10 or next;
81              
82 7         10 if ( $args{ymd} ) {
  72         170  
83 65 100       90 $return{$date} = $string;
84             }
85             else {
86 51 100       74 my ( undef, $m, undef, $d ) = unpack( 'A5A2A1A2', $date );
87 13         23 $return{ $m . $d } = $string;
88             }
89             }
90 38         94  
91 38         95 return \%return;
92             }
93              
94             my %args
95 7         67 = $_[0] =~ m/\D/
96             ? @_
97             : ( year => $_[0], regions => $_[1] );
98              
99 1 50   1 0 9 return holidays( %args, ymd => 1 );
100             }
101              
102              
103             my %args
104 1         3 = $_[0] =~ m/[^0-9-]/
105             ? @_
106             : ( year => $_[0], month => $_[1], day => $_[2], regions => $_[3] );
107 0     0 0 0  
108             my ( $y, $m, $d );
109              
110 24 100   24 1 5476 if ( $args{date} ) {
111             ( $y, $m, $d ) = $args{date} =~ m{^([0-9]{4})-([0-9]{2})-([0-9]{2})$};
112             }
113             else {
114             ( $y, $m, $d ) = @args{qw( year month day )};
115 24         39 }
116              
117 24 100       41 die "Must specify either 'date' or 'year', 'month' and 'day'"
118 6         29 unless $y && $m && $d;
119              
120             my $date = sprintf( "%04d-%02d-%02d", $y, $m, $d );
121 18         37  
122             # return if empty regions list (undef gets full list)
123             my @region_codes = @{ $args{regions} || REGIONS }
124 24 50 33     104 or return;
      33        
125              
126             # return if no region has holiday
127 24         90 my $holiday = $holidays{$y}->{$date}
128             or return;
129              
130 24 100       26 return _holiday( $holiday, \@region_codes );
  24 100       95  
131             }
132              
133              
134 21 100       79 my @regions = @_;
135              
136             unless (@regions) {
137 13         33 @regions = ( 'all', @{ +REGIONS } );
138             }
139              
140 0     0 0 0 my $now = DateTime->now->set_time_zone("Europe/London");
141             my $year = $now->year;
142             my $today = $now->ymd;
143 4     4 1 1201  
144             my %next_holidays;
145 4 100       12  
146 2         4 foreach my $date ( sort keys %{ $holidays{$year} } ) {
  2         7  
147             next unless $date gt $today;
148              
149 4         17 my $holiday = $holidays{$year}->{$date};
150 4         14969  
151 4         22 foreach my $region (@regions) {
152             my $name = $holiday->{$region} or next;
153 4         48  
154             $next_holidays{$region} ||= { name => $name, date => $date };
155 4         5 }
  4         35  
156 36 100       59  
157             last if $next_holidays{all} or keys %next_holidays == @{ +REGIONS };
158 22         30 }
159              
160 22         31 return \%next_holidays;
161 43 100       76 }
162              
163 30   100     75 my ( $holiday, $region_codes ) = @_;
164              
165             # return canonical name (EAW) if all regions have holiday
166 22 100 66     42 return $holiday->{all} if $holiday->{all};
  20         44  
167              
168             my %region_codes = map { $_ => 1 } @{$region_codes};
169 4         41  
170             # return comma separated string of holidays with region(s) in
171             # parentheses
172             my %names;
173 78     78   91 foreach my $region ( sort keys %region_codes ) {
174             next unless $holiday->{$region};
175              
176 78 100       157 push @{ $names{ $holiday->{$region} } }, REGION_NAMES->{$region};
177             }
178 43         48  
  71         116  
  43         54  
179             return unless %names;
180              
181             my @strings;
182 43         59 foreach my $name ( sort keys %names ) {
183 43         85 push @strings, "$name (" . join( ', ', @{ $names{$name} } ) . ")";
184 71 100       109 }
185              
186 29         26 return join( ', ', @strings );
  29         87  
187             }
188              
189 43 100       122  
190             1;
191 25         27  
192 25         40 2012-01-02 EAW New Year’s Day
193 25         43 2012-01-02 NIR New Year’s Day
  25         83  
194             2012-01-02 SCT 2nd January
195             2012-01-03 SCT New Year’s Day
196 25         92 2012-03-19 NIR St Patrick’s Day
197             2012-04-06 EAW Good Friday
198             2012-04-06 NIR Good Friday
199 0     0 1   2012-04-06 SCT Good Friday
200             2012-04-09 EAW Easter Monday
201             2012-04-09 NIR Easter Monday
202             2012-05-07 EAW Early May bank holiday
203             2012-05-07 NIR Early May bank holiday
204             2012-05-07 SCT Early May bank holiday
205             2012-06-04 EAW Spring bank holiday
206             2012-06-04 NIR Spring bank holiday
207             2012-06-04 SCT Spring bank holiday
208             2012-06-05 EAW Queen’s Diamond Jubilee
209             2012-06-05 NIR Queen’s Diamond Jubilee
210             2012-06-05 SCT Queen’s Diamond Jubilee
211             2012-07-12 NIR Battle of the Boyne (Orangemen’s Day)
212             2012-08-06 SCT Summer bank holiday
213             2012-08-27 EAW Summer bank holiday
214             2012-08-27 NIR Summer bank holiday
215             2012-11-30 SCT St Andrew’s Day
216             2012-12-25 EAW Christmas Day
217             2012-12-25 NIR Christmas Day
218             2012-12-25 SCT Christmas Day
219             2012-12-26 EAW Boxing Day
220             2012-12-26 NIR Boxing Day
221             2012-12-26 SCT Boxing Day
222             2013-01-01 EAW New Year’s Day
223             2013-01-01 NIR New Year’s Day
224             2013-01-01 SCT New Year’s Day
225             2013-01-02 SCT 2nd January
226             2013-03-18 NIR St Patrick’s Day
227             2013-03-29 EAW Good Friday
228             2013-03-29 NIR Good Friday
229             2013-03-29 SCT Good Friday
230             2013-04-01 EAW Easter Monday
231             2013-04-01 NIR Easter Monday
232             2013-05-06 EAW Early May bank holiday
233             2013-05-06 NIR Early May bank holiday
234             2013-05-06 SCT Early May bank holiday
235             2013-05-27 EAW Spring bank holiday
236             2013-05-27 NIR Spring bank holiday
237             2013-05-27 SCT Spring bank holiday
238             2013-07-12 NIR Battle of the Boyne (Orangemen’s Day)
239             2013-08-05 SCT Summer bank holiday
240             2013-08-26 EAW Summer bank holiday
241             2013-08-26 NIR Summer bank holiday
242             2013-12-02 SCT St Andrew’s Day
243             2013-12-25 EAW Christmas Day
244             2013-12-25 NIR Christmas Day
245             2013-12-25 SCT Christmas Day
246             2013-12-26 EAW Boxing Day
247             2013-12-26 NIR Boxing Day
248             2013-12-26 SCT Boxing Day
249             2014-01-01 EAW New Year’s Day
250             2014-01-01 NIR New Year’s Day
251             2014-01-01 SCT New Year’s Day
252             2014-01-02 SCT 2nd January
253             2014-03-17 NIR St Patrick’s Day
254             2014-04-18 EAW Good Friday
255             2014-04-18 NIR Good Friday
256             2014-04-18 SCT Good Friday
257             2014-04-21 EAW Easter Monday
258             2014-04-21 NIR Easter Monday
259             2014-05-05 EAW Early May bank holiday
260             2014-05-05 NIR Early May bank holiday
261             2014-05-05 SCT Early May bank holiday
262             2014-05-26 EAW Spring bank holiday
263             2014-05-26 NIR Spring bank holiday
264             2014-05-26 SCT Spring bank holiday
265             2014-07-14 NIR Battle of the Boyne (Orangemen’s Day)
266             2014-08-04 SCT Summer bank holiday
267             2014-08-25 EAW Summer bank holiday
268             2014-08-25 NIR Summer bank holiday
269             2014-12-01 SCT St Andrew’s Day
270             2014-12-25 EAW Christmas Day
271             2014-12-25 NIR Christmas Day
272             2014-12-25 SCT Christmas Day
273             2014-12-26 EAW Boxing Day
274             2014-12-26 NIR Boxing Day
275             2014-12-26 SCT Boxing Day
276             2015-01-01 EAW New Year’s Day
277             2015-01-01 NIR New Year’s Day
278             2015-01-01 SCT New Year’s Day
279             2015-01-02 SCT 2nd January
280             2015-03-17 NIR St Patrick’s Day
281             2015-04-03 EAW Good Friday
282             2015-04-03 NIR Good Friday
283             2015-04-03 SCT Good Friday
284             2015-04-06 EAW Easter Monday
285             2015-04-06 NIR Easter Monday
286             2015-05-04 EAW Early May bank holiday
287             2015-05-04 NIR Early May bank holiday
288             2015-05-04 SCT Early May bank holiday
289             2015-05-25 EAW Spring bank holiday
290             2015-05-25 NIR Spring bank holiday
291             2015-05-25 SCT Spring bank holiday
292             2015-07-13 NIR Battle of the Boyne (Orangemen’s Day)
293             2015-08-03 SCT Summer bank holiday
294             2015-08-31 EAW Summer bank holiday
295             2015-08-31 NIR Summer bank holiday
296             2015-11-30 SCT St Andrew’s Day
297             2015-12-25 EAW Christmas Day
298             2015-12-25 NIR Christmas Day
299             2015-12-25 SCT Christmas Day
300             2015-12-28 EAW Boxing Day
301             2015-12-28 NIR Boxing Day
302             2015-12-28 SCT Boxing Day
303             2016-01-01 EAW New Year’s Day
304             2016-01-01 NIR New Year’s Day
305             2016-01-01 SCT New Year’s Day
306             2016-01-04 SCT 2nd January
307             2016-03-17 NIR St Patrick’s Day
308             2016-03-25 EAW Good Friday
309             2016-03-25 NIR Good Friday
310             2016-03-25 SCT Good Friday
311             2016-03-28 EAW Easter Monday
312             2016-03-28 NIR Easter Monday
313             2016-05-02 EAW Early May bank holiday
314             2016-05-02 NIR Early May bank holiday
315             2016-05-02 SCT Early May bank holiday
316             2016-05-30 EAW Spring bank holiday
317             2016-05-30 NIR Spring bank holiday
318             2016-05-30 SCT Spring bank holiday
319             2016-07-12 NIR Battle of the Boyne (Orangemen’s Day)
320             2016-08-01 SCT Summer bank holiday
321             2016-08-29 EAW Summer bank holiday
322             2016-08-29 NIR Summer bank holiday
323             2016-11-30 SCT St Andrew’s Day
324             2016-12-26 EAW Boxing Day
325             2016-12-26 NIR Boxing Day
326             2016-12-26 SCT Boxing Day
327             2016-12-27 EAW Christmas Day
328             2016-12-27 NIR Christmas Day
329             2016-12-27 SCT Christmas Day
330             2017-01-02 EAW New Year’s Day
331             2017-01-02 NIR New Year’s Day
332             2017-01-02 SCT 2nd January
333             2017-01-03 SCT New Year’s Day
334             2017-03-17 NIR St Patrick’s Day
335             2017-04-14 EAW Good Friday
336             2017-04-14 NIR Good Friday
337             2017-04-14 SCT Good Friday
338             2017-04-17 EAW Easter Monday
339             2017-04-17 NIR Easter Monday
340             2017-05-01 EAW Early May bank holiday
341             2017-05-01 NIR Early May bank holiday
342             2017-05-01 SCT Early May bank holiday
343             2017-05-29 EAW Spring bank holiday
344             2017-05-29 NIR Spring bank holiday
345             2017-05-29 SCT Spring bank holiday
346             2017-07-12 NIR Battle of the Boyne (Orangemen’s Day)
347             2017-08-07 SCT Summer bank holiday
348             2017-08-28 EAW Summer bank holiday
349             2017-08-28 NIR Summer bank holiday
350             2017-11-30 SCT St Andrew’s Day
351             2017-12-25 EAW Christmas Day
352             2017-12-25 NIR Christmas Day
353             2017-12-25 SCT Christmas Day
354             2017-12-26 EAW Boxing Day
355             2017-12-26 NIR Boxing Day
356             2017-12-26 SCT Boxing Day
357             2018-01-01 EAW New Year’s Day
358             2018-01-01 NIR New Year’s Day
359             2018-01-01 SCT New Year’s Day
360             2018-01-02 SCT 2nd January
361             2018-03-19 NIR St Patrick’s Day
362             2018-03-30 EAW Good Friday
363             2018-03-30 NIR Good Friday
364             2018-03-30 SCT Good Friday
365             2018-04-02 EAW Easter Monday
366             2018-04-02 NIR Easter Monday
367             2018-05-07 EAW Early May bank holiday
368             2018-05-07 NIR Early May bank holiday
369             2018-05-07 SCT Early May bank holiday
370             2018-05-28 EAW Spring bank holiday
371             2018-05-28 NIR Spring bank holiday
372             2018-05-28 SCT Spring bank holiday
373             2018-07-12 NIR Battle of the Boyne (Orangemen’s Day)
374             2018-08-06 SCT Summer bank holiday
375             2018-08-27 EAW Summer bank holiday
376             2018-08-27 NIR Summer bank holiday
377             2018-11-30 SCT St Andrew’s Day
378             2018-12-25 EAW Christmas Day
379             2018-12-25 NIR Christmas Day
380             2018-12-25 SCT Christmas Day
381             2018-12-26 EAW Boxing Day
382             2018-12-26 NIR Boxing Day
383             2018-12-26 SCT Boxing Day
384             2019-01-01 EAW New Year’s Day
385             2019-01-01 NIR New Year’s Day
386             2019-01-01 SCT New Year’s Day
387             2019-01-02 SCT 2nd January
388             2019-03-18 NIR St Patrick’s Day
389             2019-04-19 EAW Good Friday
390             2019-04-19 NIR Good Friday
391             2019-04-19 SCT Good Friday
392             2019-04-22 EAW Easter Monday
393             2019-04-22 NIR Easter Monday
394             2019-05-06 EAW Early May bank holiday
395             2019-05-06 NIR Early May bank holiday
396             2019-05-06 SCT Early May bank holiday
397             2019-05-27 EAW Spring bank holiday
398             2019-05-27 NIR Spring bank holiday
399             2019-05-27 SCT Spring bank holiday
400             2019-07-12 NIR Battle of the Boyne (Orangemen’s Day)
401             2019-08-05 SCT Summer bank holiday
402             2019-08-26 EAW Summer bank holiday
403             2019-08-26 NIR Summer bank holiday
404             2019-12-02 SCT St Andrew’s Day
405             2019-12-25 EAW Christmas Day
406             2019-12-25 NIR Christmas Day
407             2019-12-25 SCT Christmas Day
408             2019-12-26 EAW Boxing Day
409             2019-12-26 NIR Boxing Day
410             2019-12-26 SCT Boxing Day
411             2020-01-01 EAW New Year’s Day
412             2020-01-01 NIR New Year’s Day
413             2020-01-01 SCT New Year’s Day
414             2020-01-02 SCT 2nd January
415             2020-03-17 NIR St Patrick’s Day
416             2020-04-10 EAW Good Friday
417             2020-04-10 NIR Good Friday
418             2020-04-10 SCT Good Friday
419             2020-04-13 EAW Easter Monday
420             2020-04-13 NIR Easter Monday
421             2020-05-08 EAW Early May bank holiday (VE day)
422             2020-05-08 NIR Early May bank holiday (VE day)
423             2020-05-08 SCT Early May bank holiday (VE day)
424             2020-05-25 EAW Spring bank holiday
425             2020-05-25 NIR Spring bank holiday
426             2020-05-25 SCT Spring bank holiday
427             2020-07-13 NIR Battle of the Boyne (Orangemen’s Day)
428             2020-08-03 SCT Summer bank holiday
429             2020-08-31 EAW Summer bank holiday
430             2020-08-31 NIR Summer bank holiday
431             2020-11-30 SCT St Andrew’s Day
432             2020-12-25 EAW Christmas Day
433             2020-12-25 NIR Christmas Day
434             2020-12-25 SCT Christmas Day
435             2020-12-28 EAW Boxing Day
436             2020-12-28 NIR Boxing Day
437             2020-12-28 SCT Boxing Day
438             2021-01-01 EAW New Year’s Day
439             2021-01-01 NIR New Year’s Day
440             2021-01-01 SCT New Year’s Day
441             2021-01-04 SCT 2nd January
442             2021-03-17 NIR St Patrick’s Day
443             2021-04-02 EAW Good Friday
444             2021-04-02 NIR Good Friday
445             2021-04-02 SCT Good Friday
446             2021-04-05 EAW Easter Monday
447             2021-04-05 NIR Easter Monday
448             2021-05-03 EAW Early May bank holiday
449             2021-05-03 NIR Early May bank holiday
450             2021-05-03 SCT Early May bank holiday
451             2021-05-31 EAW Spring bank holiday
452             2021-05-31 NIR Spring bank holiday
453             2021-05-31 SCT Spring bank holiday
454             2021-07-12 NIR Battle of the Boyne (Orangemen’s Day)
455             2021-08-02 SCT Summer bank holiday
456             2021-08-30 EAW Summer bank holiday
457             2021-08-30 NIR Summer bank holiday
458             2021-11-30 SCT St Andrew’s Day
459             2021-12-27 EAW Christmas Day
460             2021-12-27 NIR Christmas Day
461             2021-12-27 SCT Christmas Day
462             2021-12-28 EAW Boxing Day
463             2021-12-28 NIR Boxing Day
464             2021-12-28 SCT Boxing Day
465             2022-01-03 EAW New Year’s Day
466             2022-01-03 NIR New Year’s Day
467             2022-01-03 SCT New Year’s Day
468             2022-01-04 SCT 2nd January
469             2022-03-17 NIR St Patrick’s Day
470             2022-04-15 EAW Good Friday
471             2022-04-15 NIR Good Friday
472             2022-04-15 SCT Good Friday
473             2022-04-18 EAW Easter Monday
474             2022-04-18 NIR Easter Monday
475             2022-05-02 EAW Early May bank holiday
476             2022-05-02 NIR Early May bank holiday
477             2022-05-02 SCT Early May bank holiday
478             2022-06-02 EAW Spring bank holiday
479             2022-06-02 NIR Spring bank holiday
480             2022-06-02 SCT Spring bank holiday
481             2022-06-03 EAW Platinum Jubilee bank holiday
482             2022-06-03 NIR Platinum Jubilee bank holiday
483             2022-06-03 SCT Platinum Jubilee bank holiday
484             2022-07-12 NIR Battle of the Boyne (Orangemen’s Day)
485             2022-08-01 SCT Summer bank holiday
486             2022-08-29 EAW Summer bank holiday
487             2022-08-29 NIR Summer bank holiday
488             2022-09-19 EAW Bank Holiday for the State Funeral of Queen Elizabeth II
489             2022-09-19 NIR Bank Holiday for the State Funeral of Queen Elizabeth II
490             2022-09-19 SCT Bank Holiday for the State Funeral of Queen Elizabeth II
491             2022-11-30 SCT St Andrew’s Day
492             2022-12-26 EAW Boxing Day
493             2022-12-26 NIR Boxing Day
494             2022-12-26 SCT Boxing Day
495             2022-12-27 EAW Christmas Day
496             2022-12-27 NIR Christmas Day
497             2022-12-27 SCT Christmas Day
498             2023-01-02 EAW New Year’s Day
499             2023-01-02 NIR New Year’s Day
500             2023-01-02 SCT New Year’s Day
501             2023-01-03 SCT 2nd January
502             2023-03-17 NIR St Patrick’s Day
503             2023-04-07 EAW Good Friday
504             2023-04-07 NIR Good Friday
505             2023-04-07 SCT Good Friday
506             2023-04-10 EAW Easter Monday
507             2023-04-10 NIR Easter Monday
508             2023-05-01 EAW Early May bank holiday
509             2023-05-01 NIR Early May bank holiday
510             2023-05-01 SCT Early May bank holiday
511             2023-05-29 EAW Spring bank holiday
512             2023-05-29 NIR Spring bank holiday
513             2023-05-29 SCT Spring bank holiday
514             2023-07-12 NIR Battle of the Boyne (Orangemen’s Day)
515             2023-08-07 SCT Summer bank holiday
516             2023-08-28 EAW Summer bank holiday
517             2023-08-28 NIR Summer bank holiday
518             2023-11-30 SCT St Andrew’s Day
519             2023-12-25 EAW Christmas Day
520             2023-12-25 NIR Christmas Day
521             2023-12-25 SCT Christmas Day
522             2023-12-26 EAW Boxing Day
523             2023-12-26 NIR Boxing Day
524             2023-12-26 SCT Boxing Day