File Coverage

blib/lib/Date/Holidays/PT.pm
Criterion Covered Total %
statement 46 46 100.0
branch 20 20 100.0
condition 3 3 100.0
subroutine 10 10 100.0
pod 4 4 100.0
total 83 83 100.0


line stmt bran cond sub pod time code
1             package Date::Holidays::PT;
2              
3 6     6   114656 use warnings;
  6         10  
  6         199  
4 6     6   24 use strict;
  6         7  
  6         120  
5              
6 6     6   1143 use utf8;
  6         26  
  6         26  
7 6     6   3035 use Date::Holidays::Super;
  6         886  
  6         149  
8 6     6   2869 use Date::Easter;
  6         14726  
  6         400  
9 6     6   2872 use Time::JulianDay;
  6         21717  
  6         2403  
10              
11             my @ISA = qw(Date::Holidays::Super);
12              
13             =encoding utf-8
14              
15             =head1 NAME
16              
17             Date::Holidays::PT - Determine Portuguese public holidays
18              
19             =cut
20              
21             our $VERSION = '0.03';
22              
23             =head1 SYNOPSIS
24              
25             use Date::Holidays::PT;
26             my ($year, $month, $day) = (localtime)[ 5, 4, 3 ];
27             $year += 1900;
28             $month += 1;
29             print "Woohoo" if is_pt_holiday( $year, $month, $day );
30              
31             my $h = pt_holidays($year);
32             printf "Jan. 1st is named '%s'\n", $h->{'0101'};
33              
34             =head1 FUNCTIONS
35              
36             =head2 new
37              
38             Creates a new Date::Holidays::PT object.
39              
40             my $mh = Date::Holidays::PT->new();
41              
42             =cut
43              
44             sub new {
45 5     5 1 61 my $self = shift;
46 5         17 bless \$self => $self;
47             }
48              
49             =head2 is_holiday
50              
51             Should at least take three arguments:
52              
53             year (four digits)
54             month (between 1-12)
55             day (between 1-31)
56              
57             The return value from is_holiday is either a 1 or a 0 (1 if the
58             specified date is a holiday, 0 otherwise).
59              
60             if ( $mh->is_holiday( $year, $month, $day ) ) {
61             # it's a holiday
62             }
63              
64             =cut
65              
66             sub is_holiday {
67 40     40 1 60 my $self = shift;
68 40         93 return $self->is_pt_holiday(@_);
69             }
70              
71             =head2 is_pt_holiday
72              
73             Similar to is_holiday, but instead of returning 1 if the date is a
74             holiday returns a string comprising the name of the holidays. In the
75             event of two or more holidays on the same day (hey, it happens), the
76             string will comprise the name of all those holidays separated by a
77             semicolon.
78              
79             my $todays_holiday = $mh->is_pt_holiday( $year, $month, $day );
80             if ( $todays_holiday ) {
81             print "Today is $todays_holiday.\nDon't bother getting up!\n";
82             }
83              
84             =cut
85              
86             sub is_pt_holiday {
87 1520     1520 1 2138 my $self = shift;
88 1520         2168 my ($year, $month, $day) = @_;
89 1520 100       3283 defined $year || return undef;
90 1516 100       2492 defined $month || return undef;
91 1512 100       2273 defined $day || return undef;
92              
93 1508         2899 my $holidays = $self->holidays($year);
94 1508 100 100     6427 if (defined $holidays->{$month} and defined $holidays->{$month}{$day}) {
95 97         758 return $holidays->{$month}{$day};
96             }
97             else {
98 1411         10411 return undef;
99             }
100              
101             }
102              
103             =head2 holidays
104              
105             Should take at least one argument:
106              
107             year (four digits)
108              
109             Returns a reference to a hash, where the keys are date represented as
110             four digits, the two first representing month (01-12) and the last two
111             representing day (01-31).
112              
113             The value for the key in question is the local name for the holiday
114             indicated by the day. In the event of two or more holidays on the same
115             day (yes, it happens!), the values will comprise the name of all those
116             holidays separated by a semicolon.
117              
118             my $years_holidays = holidays( $year );
119             for (keys %$years_holidays) {
120             my ($day, $month) = /(..)(..)/;
121             print "$day/$month - $years_holidays->$_\n";
122             }
123              
124             =cut
125              
126             sub holidays {
127 1517     1517 1 1499 my $self = shift;
128 1517         1393 my $year = shift;
129 1517 100       2394 defined $year || return undef;
130              
131 1516 100       19353 my %holidays = (
    100          
    100          
132             1 => {
133             1 => 'Ano Novo',
134             },
135             4 => {
136             25 => 'Dia da Liberdade',
137             },
138             5 => {
139             1 => 'Dia do Trabalhador',
140             },
141             6 => {
142             10 => 'Dia de Portugal, de Camões e das Comunidades',
143             },
144             8 => {
145             15 => 'Assunção de Nossa Senhora',
146             },
147             10 => {
148             ($year <= 2012) ? (5 => 'Dia da Implantação da República') : (),
149             },
150             11 => {
151             ($year <= 2012) ? (1 => 'Dia de Todos-os-Santos') : (),
152             },
153             12 => {
154             ($year <= 2012) ? (1 => 'Dia da Restauração da Independência') : (),
155             8 => 'Imaculada Conceição',
156             25 => 'Natal',
157             },
158             );
159              
160 1516         4029 my ($emonth, $eday) = gregorian_easter($year);
161 1516         20874 $holidays{$emonth}{$eday} = 'Páscoa';
162              
163 1516         3474 my $jd = julian_day($year, $emonth, $eday);
164              
165 1516 100       10321 if ($year <= 2012) {
166 1141         4682 my (undef, $cmonth, $cday) = inverse_julian_day($jd - 47);
167 1141         16052 $holidays{$cmonth}{$cday} = 'Entrudo';
168              
169 1141         2466 my (undef, $bmonth, $bday) = inverse_julian_day($jd + 60);
170             $holidays{$bmonth}{$bday} =
171             $holidays{$bmonth}{$bday} ?
172 1141 100       14511 $holidays{$bmonth}{$bday} . '; Corpo de Deus':
173             'Corpo de Deus';
174             }
175              
176 1516         3159 my (undef, $smonth, $sday) = inverse_julian_day($jd - 2);
177 1516         16483 $holidays{$smonth}{$sday} = 'Sexta-feira Santa';
178              
179 1516         3077 return \%holidays;
180             }
181              
182             =head1 NATIONAL HOLIDAYS
183              
184             The following Portuguese holidays have fixed dates:
185              
186             Jan 1 Ano Novo
187             Apr 25 Dia da Liberdade
188             May 1 Dia do Trabalhador
189             Jun 10 Dia de Portugal, de Camões e das Comunidades
190             Aug 15 Assunção da Virgem
191             Oct 5 Dia da Implantação da República
192             Nov 1 Dia de Todos-os-Santos
193             -- no longer holiday, maintained for completude
194             Dec 1 Dia da Restauração da Independência
195             -- no longer holiday, maintained for completude
196             Dec 8 Imaculada Conceição
197             Dec 25 Natal
198              
199             The following Portuguese holidays have mobile dates:
200              
201             Entrudo (47 days before Páscoa / Easter)
202             -- no longer holiday, maintained for completude
203             Sexta-feira Santa (Friday before Páscoa / Easter)
204             Páscoa (Easter)
205             Corpo de Deus (60 days after Páscoa / Easter)
206             -- no longer holiday, maintained for completude
207              
208             =head1 ACKNOWLEDGEMENTS
209              
210             Paulo Rocha, for all his knowledge about holidays and everything else.
211              
212             Jonas B. Nielsen, for his work regarding the standardization of
213             Date::Holidays modules.
214              
215             =head1 AUTHOR
216              
217             José Castro, C<< >>
218              
219             Maintained by Alberto Simões, C<< >>
220              
221             =head1 BUGS
222              
223             Please report any bugs or feature requests to
224             C, or through the web interface at
225             L. I will be notified, and then you'll
226             automatically be notified of progress on your bug as I make changes.
227              
228             =head1 COPYRIGHT & LICENSE
229              
230             Copyright 2004-2015 José Castro, All Rights Reserved.
231             Copyright 2005 Alberto Simões, All Rights Reserved.
232              
233             This program is free software; you can redistribute it and/or modify
234             it under the same terms as Perl itself.
235              
236             =cut
237              
238             1; # End of Date::Holidays::PT