File Coverage

blib/lib/Date/Holidays/EnglandWales.pm
Criterion Covered Total %
statement 50 55 90.9
branch 42 52 80.7
condition 49 78 62.8
subroutine 8 9 88.8
pod 0 2 0.0
total 149 196 76.0


line stmt bran cond sub pod time code
1              
2             use 5.008000;
3 1     1   105977 use strict;
  1         4  
4 1     1   6 use warnings;
  1         2  
  1         22  
5 1     1   5  
  1         2  
  1         26  
6             use DateTime;
7 1     1   967 use DateTime::Event::Easter;
  1         560374  
  1         57  
8 1     1   737  
  1         55557  
  1         635  
9             require Exporter;
10             our @ISA = qw(Exporter);
11             our @EXPORT = qw( is_holiday is_uk_holiday );
12             our $VERSION = '0.11';
13              
14              
15             =head1 NAME
16              
17             Date::Holidays::EnglandWales - Determines bank holidays
18              
19             =head1 SYNOPSIS
20              
21             use Date::Holidays::EnglandWales;
22            
23             my ($year, $month, $day) = (localtime)[ 5, 4, 3 ];
24             $year += 1900;
25             $month += 1;
26              
27             my $isodate = "$year-$month-$day";
28              
29             print "It's a bank holiday" if is_holiday($year, $month, $day);
30             print "Sleep in late!" if Date::Holidays::EnglandWales->is_holiday($isodate);
31              
32             =head1 DESCRIPTION
33              
34             Date::Holidays::EnglandWales returns true is a given date is a bank
35             holiday in England and wales.
36              
37             The date can be passed as year, month, day or as an ISO formatted date.
38              
39             This module uses a simple set of rules to determine whether a date is a
40             holiday rather than a static list. This means it isn't limited to just
41             the next few years and wont require maintainance unless the rules are
42             changed.
43              
44             It knows about the proposed bank holiday for the Queen's Diamond Jubilee.
45              
46             =head2 EXPORT
47              
48             is_holiday
49             is_uk_holiday
50              
51             =head1 DEPENDANCIES
52              
53             This module uses the following modules which you can get from CPAN.
54              
55             Time::Piece
56             DateTime::Event::Easter
57              
58             =head1 SEE ALSO
59              
60             Bank Holidays in England and Wales are determined by the Banking and
61             Financial Dealings Act 1971 and by Royal Proclamation. This means that it
62             is possible that they may change from year to year although in practice
63             this does not happen.
64              
65             If you need to be absolutely sure about a date check with the DTI whose
66             website is http://www.dti.gov.uk/
67              
68             =head1 AUTHOR
69              
70             Jason Clifford, E<lt>jason@ukfsn.orgE<gt>
71              
72             =head1 COPYRIGHT AND LICENSE
73              
74             Copyright (C) 2010 by Jason Clifford
75              
76             This library is free software; you can redistribute it and/or modify
77             it under the same terms as Perl itself. That means either the Artistic
78             License or the GNU GPL version 2 or later.
79              
80             =cut
81              
82              
83 0     0 0 0 my ($year, $month, $day) = @_;
84             ($year, $month, $day) = split m{[-/]}, $year unless $month;
85            
86 21     21 0 185 my $dt = DateTime->new(year => $year, month => $month, day => $day)
87 21 100       103 or die "Failed to create DateTime object for $year-$month-$day"
88             . " - invalid date?";
89 21 50       92  
90             if ( $month == 1 ) {
91             return "New Years Day" if (
92             ( $day == 1 && $dt->day_of_week <= 5 ) ||
93 21 100       6520 ( $day == 2 && $dt->day_of_week == 1 ) ||
94 3 100 66     21 ( $day == 3 && $dt->day_of_week == 1 ) );
      66        
      33        
      66        
      33        
95             return undef;
96             }
97              
98 2         45 if ( $year == 2011 && $month == 4 ) {
99             return "Wedding of Prince William and Kate Middleton" if $day == 29;
100             }
101 18 100 100     66  
102 3 100       15 if ( $month == 5 ) {
103             return "Early May Bank Holiday" if (
104             ( $day >= 1 && $day <= 7 && $dt->day_of_week == 1 ) );
105 17 100       41  
106 4 100 66     24 return "Spring Bank Holiday" if (
      66        
107             $year != 2012 && $year != 2022 &&
108             ( $day >= 25 && $dt->day_of_week == 1 ) );
109 3 100 66     22 }
      66        
      100        
110              
111             if ( $year == 2012 && $month == 6 ) {
112             return "Spring Bank Holiday" if $day == 4;
113             return "Queen's Diamond Jubilee" if $day == 5; # Subject to Her Maj not dying first but I cannot be bothered to code for that.
114 15 50 33     39 return undef;
115 0 0       0 }
116 0 0       0  
117 0         0 if ( $year == 2022 && $month == 6) {
118             return "Spring Bank Holiday" if $day == 2;
119             return "Queen's Platinum Jubilee" if $day == 3; # She's still here
120 15 100 100     52 }
121 2 100       14  
122 1 50       10 if ( $year == 2022 && $month == 9 ) {
123             return "State Funeral of Queen Elizabeth II" if $day == 19; # May she rest in peace.
124             }
125 13 100 100     39  
126 2 50       18 if ( $year == 2023 && $month == 5 ) {
127             return "Coronation of King Charles III" if $day == 8; # Long live the King!
128             }
129 11 100 66     33  
130 1 50       10 if ( $month == 8 ) {
131             return "Summer Bank Holiday" if (
132             $day >= 25 && $dt->day_of_week == 1 );
133 10 100       21 return undef;
134 1 50 33     7 }
135              
136 0         0 if ( $month == 12 ) {
137             return "Christmas Day Bank Holiday" if (
138             ( $day == 25 && $dt->day_of_week <= 5 ) ||
139 9 100       23 ( $day == 26 && $dt->day_of_week == 1 ) ||
140 5 100 66     34 ( $day == 27 && $dt->day_of_week == 1 ) );
      66        
      33        
      66        
      66        
141              
142             return "Boxing Day" if (
143             ( $day == 26 && $dt->day_of_week <= 5 ) ||
144             ( $day == 27 && $dt->day_of_week <= 2 ) ||
145 4 100 66     51 ( $day == 28 && $dt->day_of_week <= 2 ) );
      33        
      33        
      66        
      66        
146              
147             return undef;
148             }
149              
150 3         94 return "Good Friday" if &_GoodFriday($year, $month, $day);
151              
152             # We need to check if the day before the day in question is Easter Sunday
153 4 100       15 my $e = $dt->clone->subtract(days => 1);
154             return "Easter Monday" if &_Easter($e->year, $e->month, $e->day);
155              
156 3         7650 }
157 3 100       3303  
158             my ($year, $month, $day) = @_;
159              
160             my $dt = DateTime->new( year => $year, month => $month, day => $day );
161             my $easter_sunday = DateTime::Event::Easter->new();
162 3     3   60  
163             return $easter_sunday->is($dt);
164 3         36 }
165 3         860  
166             my ($year, $month, $day) = @_;
167 3         471  
168             my $dt = DateTime->new( year => $year, month => $month, day => $day );
169             my $good_friday = DateTime::Event::Easter->new(day=>'Good Friday');
170              
171 4     4   12 return $good_friday->is($dt);
172             }
173 4         15  
174 4         1154 1;