File Coverage

blib/lib/Date/Holidays/AU.pm
Criterion Covered Total %
statement 672 672 100.0
branch 280 280 100.0
condition 39 39 100.0
subroutine 41 41 100.0
pod 2 2 100.0
total 1034 1034 100.0


line stmt bran cond sub pod time code
1             package Date::Holidays::AU;
2              
3 1     1   567 use strict;
  1         2  
  1         29  
4 1     1   5 use warnings;
  1         2  
  1         23  
5              
6 1     1   505 use Time::Local();
  1         2531  
  1         25  
7 1     1   475 use Date::Easter();
  1         716  
  1         24  
8 1     1   6 use Exporter();
  1         2  
  1         12  
9 1     1   5 use Carp();
  1         1  
  1         17  
10              
11 1     1   5 use base qw(Exporter);
  1         2  
  1         7267  
12             our @EXPORT_OK = qw(is_holiday holidays);
13             our $VERSION = '0.28';
14              
15 9     9   684 sub _DEFAULT_STATE { return 'VIC' }
16              
17             my %allowed_states = (
18             VIC => 1,
19             WA => 1,
20             NT => 1,
21             QLD => 1,
22             TAS => 1,
23             NSW => 1,
24             SA => 1,
25             ACT => 1,
26             );
27              
28             sub holidays {
29 156     156 1 2645 my (%params) = @_;
30 156 100 100     1083 if ( ( exists $params{year} ) && ( defined $params{year} ) ) {
31             }
32             else {
33 2         65 $params{year} = (localtime)[5];
34 2         9 $params{year} += 1900;
35             }
36 156 100       1384 if ( $params{year} !~ /^\d{1,4}$/smx ) {
37 2         241 Carp::croak(
38             q[Year must be numeric and from one to four digits, eg '2004']);
39             }
40 154         313 my $year = $params{year};
41 154 100       415 if ( !defined $params{state} ) {
42 4         12 Carp::carp( 'State not defined, setting state to default: '
43             . _DEFAULT_STATE() );
44 4         24 $params{state} = _DEFAULT_STATE();
45             }
46              
47 154         417 my $state = uc $params{state};
48 154 100       490 if ( !$allowed_states{$state} ) {
49 1         120 Carp::croak(
50             q[State must be one of 'VIC','WA','NT','QLD','TAS','NSW','SA','ACT']
51             );
52             }
53 153         252 my $concat = $state;
54 153         810 foreach my $key ( sort { $a cmp $b } keys %params ) {
  246         816  
55 355 100       776 next if ( $key eq 'year' );
56 202 100       440 next if ( $key eq 'state' );
57 49 100       152 next if ( !$params{$key} );
58 44 100       120 if ( ref $params{$key} ) {
59 32 100       95 if ( ( ref $params{$key} ) eq 'ARRAY' ) {
60 30         64 $concat .= '_' . $key;
61 30         49 foreach my $element ( @{ $params{$key} } ) {
  30         72  
62 34         75 $concat .= '_' . $element;
63             }
64             }
65             }
66             else {
67 12         35 $concat .= '_' . $key . '_' . $params{$key};
68             }
69 44         118 $concat = lc $concat;
70 44         629 $concat =~ s/\s*//smxg;
71             }
72 153         293 my %holidays;
73 153 100       381 if ( $state eq 'TAS' ) {
74 42 100       133 if ( exists $params{holidays} ) {
75 32 100 100     152 if ( ( ref $params{holidays} )
76             && ( ( ref $params{holidays} ) eq 'ARRAY' ) )
77             {
78 30         54 foreach my $allowed ( @{ $params{holidays} } ) {
  30         86  
79 34         66 $allowed = lc $allowed;
80 34         264 $allowed =~ s/\s*//smxg;
81 34 100       111 if ( $allowed eq 'devonportcup' ) {
82 6         26 foreach my $holiday ( _compute_devonport_cup($year) )
83             { # TAS devonport cup
84 6         25 $holidays{$holiday} = 'Devonport Cup';
85             }
86             }
87             }
88             }
89             else {
90 2         338 Carp::croak(
91             q[Holidays parameter must be a reference to an array]);
92             }
93             }
94             }
95 151         619 foreach my $holiday ( _compute( 1, 1, $year, { 'day_in_lieu' => 1 } ) )
96             { # new years day
97 225 100       532 if ( $holiday eq '0101' ) {
98 151         448 $holidays{$holiday} = 'New Years Day';
99             }
100             else {
101 74         256 $holidays{$holiday} = 'New Years Day Holiday';
102             }
103             }
104 151         596 foreach my $holiday ( _compute( 26, 1, $year, { 'day_in_lieu' => 1 } ) )
105             { # australia day
106 163 100       543 if ( $holiday eq '0126' ) {
107 151         482 $holidays{$holiday} = 'Australia Day';
108             }
109             else {
110 12         41 $holidays{$holiday} = 'Australia Day Holiday';
111             }
112             }
113 151 100       1034 if ( $state eq 'VIC' ) {
    100          
    100          
    100          
    100          
114 31         109 foreach my $holiday ( _compute_vic_labour_day($year) )
115             { # VIC labour day
116 31         120 $holidays{$holiday} = 'Labour Day';
117             }
118 31         108 foreach my $holiday ( _compute_vic_grand_final_eve_day($year) )
119             { # VIC grand final day
120 11         30 $holidays{$holiday} = 'Grand Final Eve';
121             }
122             }
123             elsif ( $state eq 'WA' ) {
124 29         120 foreach my $holiday ( _compute_wa_labour_day($year) ) { # WA labour day
125 29         143 $holidays{$holiday} = 'Labour Day';
126             }
127             }
128             elsif ( $state eq 'SA' ) {
129 6         31 foreach my $holiday ( _compute_sa_adelaide_cup_day($year) )
130             { # adelaide cup day
131 3         14 $holidays{$holiday} = 'Adelaide Cup Day';
132             }
133             }
134             elsif ( $state eq 'ACT' ) {
135 7         32 foreach my $holiday ( _compute_canberra_day($year) ) { # canberra day
136 7         26 $holidays{$holiday} = 'Canberra Day';
137             }
138             }
139             elsif ( $state eq 'TAS' ) {
140 40 100       122 if ( exists $params{holidays} ) {
141 30         62 foreach my $allowed ( @{ $params{holidays} } ) {
  30         83  
142 34         70 $allowed = lc $allowed;
143 34         327 $allowed =~ s/\s*//smxg;
144 34 100       222 if ( $allowed eq 'devonportcup' ) {
    100          
    100          
    100          
145 6         33 foreach my $holiday ( _compute_devonport_cup($year) )
146             { # TAS devonport cup
147 6         26 $holidays{$holiday} = 'Devonport Cup';
148             }
149             }
150             elsif ( $allowed eq 'hobartregatta' ) {
151 1         8 foreach my $holiday ( _compute_hobart_regatta($year) )
152             { # TAS hobart regatta
153 1         6 $holidays{$holiday} = 'Hobart Regatta';
154             }
155             }
156             elsif ( $allowed eq 'launcestoncup' ) {
157 4         14 foreach my $holiday ( _compute_launceston_cup($year) )
158             { # TAS launceston cup
159 4         16 $holidays{$holiday} = 'Launceston Cup';
160             }
161             }
162             elsif ( $allowed eq 'kingislandshow' ) {
163 1         6 foreach my $holiday ( _compute_king_island_show($year) )
164             { # TAS king island show
165 1         5 $holidays{$holiday} = 'King Island Show';
166             }
167             }
168             }
169             }
170 40         149 foreach my $holiday ( _compute_eight_hours_day($year) )
171             { # TAS eight hours day
172 40         157 $holidays{$holiday} = 'Eight Hours Day';
173             }
174             }
175 150         313 my $count = 0;
176 150         450 foreach my $holiday ( _compute_easter( $year, $state ) ) { # easter
177 640 100       1544 if ( $count == 0 ) {
    100          
    100          
    100          
178 150         484 $holidays{$holiday} = 'Good Friday';
179             }
180             elsif ( $count == 1 ) {
181 150         310 $holidays{$holiday} = 'Easter Saturday';
182             }
183             elsif ( $count == 2 ) {
184 150         324 $holidays{$holiday} = 'Easter Sunday';
185             }
186             elsif ( $count == 3 ) {
187 150         390 $holidays{$holiday} = 'Easter Monday';
188             }
189             else {
190 40         93 $holidays{$holiday} = 'Easter Tuesday';
191             }
192 640         1071 $count += 1;
193             }
194 150 100 100     915 if ( ( $state eq 'VIC' ) || ( $state eq 'TAS' ) || ( $state eq 'NSW' ) ) {
      100        
195 85         218 foreach my $holiday ( _compute( 25, 4, $year ) ) { # ANZAC day
196 85         335 $holidays{$holiday} = 'Anzac Day';
197             }
198             }
199             else {
200 65         261 foreach my $holiday ( _compute( 25, 4, $year, { 'day_in_lieu' => 1 } ) )
201             { # ANZAC day
202 80 100       202 if ( $holiday eq '0425' ) {
203 65         242 $holidays{$holiday} = 'Anzac Day';
204             }
205             else {
206 15         48 $holidays{$holiday} = 'Anzac Day Holiday';
207             }
208             }
209             }
210 150 100       766 if ( $state eq 'SA' ) {
    100          
    100          
211 6         28 foreach my $holiday ( _compute_sa_volunteers_day($year) )
212             { # SA Volunteers day
213 3         11 $holidays{$holiday} = 'Volunteers Day';
214             }
215             }
216             elsif ( $state eq 'NT' ) {
217 15         65 foreach my $holiday ( _compute_nt_may_day($year) ) { # NT May day
218 15         54 $holidays{$holiday} = 'May Day';
219             }
220             }
221             elsif ( $state eq 'TAS' ) {
222 40 100       136 if ( exists $params{holidays} ) {
223 30         46 foreach my $allowed ( @{ $params{holidays} } ) {
  30         84  
224 34         65 $allowed = lc $allowed;
225 34         352 $allowed =~ s/\s*//smxg;
226 34 100       101 if ( $allowed eq 'agfest' ) {
227 2         10 foreach my $holiday ( _compute_agfest($year) )
228             { # TAS Agfest
229 2         8 $holidays{$holiday} = 'Agfest';
230             }
231             }
232             }
233             }
234             }
235 150 100       357 if ( $state eq 'WA' ) {
236 29         101 foreach my $holiday ( _compute_wa_foundation_day($year) )
237             { # WA Foundation day
238 29         102 $holidays{$holiday} = 'Foundation Day';
239             }
240             }
241             else {
242 121         376 foreach my $holiday ( _compute_queens_bday($year) )
243             { # Queens Birthday day
244 121         449 $holidays{$holiday} = 'Queens Birthday';
245             }
246             }
247 150         275 my $holiday_hashref;
248 150 100       815 if ( $state eq 'VIC' ) {
    100          
    100          
    100          
    100          
    100          
    100          
249 30 100 100     155 if ( ( exists $params{no_melbourne_cup} )
250             && ( $params{no_melbourne_cup} ) )
251             {
252             }
253             else {
254 29         109 foreach my $holiday ( _compute_melbourne_cup_day($year) )
255             { # Melbourne Cup day
256 29         111 $holidays{$holiday} = 'Melbourne Cup Day';
257             }
258             }
259             }
260             elsif ( $state eq 'QLD' ) {
261 8 100 100     46 unless ( ( exists $params{no_show_day} )
262             && ( $params{no_show_day} ) )
263             {
264 7         29 foreach my $holiday ( _compute_qld_show_day($year) )
265             { # Queensland Show day
266 7         28 $holidays{$holiday} = 'Queensland Show Day';
267             }
268             }
269             }
270             elsif ( $state eq 'SA' ) {
271 6         30 foreach my $holiday ( _compute_nsw_sa_act_labour_day($year) )
272             { # SA labour day
273 6         22 $holidays{$holiday} = 'Labour Day';
274             }
275             }
276             elsif ( $state eq 'NT' ) {
277 15         55 foreach
278             my $holiday_hashref ( _compute_nt_show_day_hash( $year, \%params ) )
279             { # NT regional show days
280             $holidays{ $holiday_hashref->{date} } =
281 14         61 $holiday_hashref->{name};
282             }
283 14         67 foreach my $holiday ( _compute_nt_picnic_day($year) ) { # NT picnic day
284 14         51 $holidays{$holiday} = 'Picnic Day';
285             }
286             }
287             elsif ( $state eq 'WA' ) {
288 29         85 foreach my $holiday ( _compute_wa_queens_bday($year) )
289             { # WA Queens Birthday day
290 28         81 $holidays{$holiday} = 'Queens Birthday';
291             }
292             }
293             elsif ( $state eq 'ACT' ) {
294 7 100 100     31 if ( ( exists $params{include_bank_holiday} )
295             && ( $params{include_bank_holiday} ) )
296             {
297 1         7 foreach my $holiday ( _compute_nsw_act_bank_holiday($year) )
298             { # ACT bank holiday
299 1         6 $holidays{$holiday} = 'Bank Holiday';
300             }
301             }
302 7         36 foreach my $holiday ( _compute_nsw_sa_act_labour_day($year) )
303             { # ACT labour day
304 7         25 $holidays{$holiday} = 'Labour Day';
305             }
306             }
307             elsif ( $state eq 'TAS' ) {
308 40 100       101 if ( exists $params{holidays} ) {
309 30         52 foreach my $allowed ( @{ $params{holidays} } ) {
  30         93  
310 34         80 $allowed = lc $allowed;
311 34         684 $allowed =~ s/\s*//smxg;
312 34 100       203 if ( $allowed eq 'burnieshow' ) {
    100          
    100          
    100          
    100          
    100          
313 8         37 foreach my $holiday ( _compute_burnie_show($year) )
314             { # TAS burnie show day
315 8         45 $holidays{$holiday} = 'Burnie Show';
316             }
317             }
318             elsif ( $allowed eq 'launcestonshow' ) {
319 1         6 foreach my $holiday ( _compute_launceston_show($year) )
320             { # TAS launceston show day
321 1         4 $holidays{$holiday} = 'Launceston Show';
322             }
323             }
324             elsif ( $allowed eq 'flindersislandshow' ) {
325 1         7 foreach my $holiday ( _compute_flinders_island_show($year) )
326             { # TAS flinders island show day
327 1         6 $holidays{$holiday} = 'Flinders Island Show';
328             }
329             }
330             elsif ( $allowed eq 'hobartshow' ) {
331 3         15 foreach my $holiday ( _compute_hobart_show($year) )
332             { # TAS hobart show day
333 3         16 $holidays{$holiday} = 'Hobart Show';
334             }
335             }
336             elsif ( $allowed eq 'recreationday' ) {
337 3         17 foreach my $holiday ( _compute_recreation_day($year) )
338             { # TAS recreation day
339 3         14 $holidays{$holiday} = 'Recreation Day';
340             }
341             }
342             elsif ( $allowed eq 'devonportshow' ) {
343 4         19 foreach my $holiday ( _compute_devonport_show($year) )
344             { # TAS devonport show day
345 4         17 $holidays{$holiday} = 'Devonport Show';
346             }
347             }
348             }
349             }
350             }
351             else {
352 15 100 100     74 if ( ( exists $params{include_bank_holiday} )
353             && ( $params{include_bank_holiday} ) )
354             {
355 3         14 foreach my $holiday ( _compute_nsw_act_bank_holiday($year) )
356             { # NSW bank holiday
357 3         12 $holidays{$holiday} = 'Bank Holiday';
358             }
359             }
360 15         56 foreach my $holiday ( _compute_nsw_sa_act_labour_day($year) )
361             { # NSW labour day
362 15         59 $holidays{$holiday} = 'Labour Day';
363             }
364             }
365 148         485 foreach my $holiday_hashref ( _compute_christmas_hash( $year, $state ) )
366             { # christmas day + boxing day
367 460         1272 $holidays{ $holiday_hashref->{date} } = $holiday_hashref->{name};
368             }
369 148         987 return ( \%holidays );
370             }
371              
372             sub is_holiday {
373 148     148 1 3618 my ( $year, $month, $day, $state, $params ) = @_;
374 148 100       498 if ( !defined $state ) {
375 1         5 $state = _DEFAULT_STATE();
376             }
377 148         346 my $concat = $state;
378 148         346 foreach my $key ( sort { $a cmp $b } keys %{$params} ) {
  1         6  
  148         709  
379 49 100       181 next if ( !$params->{$key} );
380 44 100       168 if ( ref $params->{$key} ) {
381 32 100       110 if ( ( ref $params->{$key} ) eq 'ARRAY' ) {
382 30         74 $concat .= '_' . $key;
383 30         57 foreach my $element ( @{ $params->{$key} } ) {
  30         67  
384 34         84 $concat .= '_' . $element;
385             }
386             }
387             }
388             else {
389 12         51 $concat .= '_' . $key . '_' . $params->{$key};
390             }
391 44         127 $concat = lc $concat;
392 44         791 $concat =~ s/\s*//smxg;
393             }
394 148         357 my $holidays = holidays( 'year' => $year, 'state' => $state, %{$params} );
  148         456  
395 143         460 my $date = sprintf '%02d%02d', $month, $day;
396 143 100       425 if ( $holidays->{$date} ) {
397 108         1163 return 1;
398             }
399             else {
400 35         371 return 0;
401             }
402             }
403              
404             my @days_in_month = ( 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 )
405             ; # feb will be calculated locally
406              
407             sub _compute_christmas_hash {
408 148     148   391 my ( $year, $state ) = @_;
409 148         274 my $day = 25;
410 148         243 my $month = 12;
411 148         515 my $date = Time::Local::timelocal( 0, 0, 0, $day, ( $month - 1 ), $year );
412 148         10779 my ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
413             localtime $date;
414 148         452 my $boxing_day = 'Boxing Day';
415 148 100       484 if ( $state eq 'SA' ) {
416 6         14 $boxing_day = 'Proclamation Day';
417             }
418 148         281 my @holidays;
419 148         1067 push @holidays,
420             {
421             'name' => 'Christmas Day',
422             'date' => sprintf '%02d%02d',
423             $month, $day,
424             };
425 148         951 push @holidays,
426             {
427             'name' => $boxing_day,
428             'date' => sprintf '%02d%02d',
429             $month, ( $day + 1 ),
430             };
431 148 100       638 if ( $wday == 5 ) { # Christmas is on a Friday
    100          
    100          
432 8         50 push @holidays,
433             {
434             'name' => "$boxing_day Holiday",
435             'date' => sprintf '%02d%02d',
436             $month, ( $day + 2 ),
437             };
438 8 100 100     44 if ( ( $state eq 'NSW' ) && ( $year > 2011 ) ) {
439 1         5 push @holidays,
440             {
441             'name' => 'Additional Day',
442             'date' => sprintf '%02d%02d',
443             $month, ( $day + 3 ),
444             };
445             }
446             }
447             elsif ( $wday == 6 ) { # Christmas is on a Saturday
448 48         238 push @holidays,
449             {
450             'name' => 'Christmas Day Holiday',
451             'date' => sprintf '%02d%02d',
452             $month, ( $day + 2 ),
453             };
454 48         249 push @holidays,
455             {
456             'name' => "$boxing_day Holiday",
457             'date' => sprintf '%02d%02d',
458             $month, ( $day + 3 ),
459             };
460 48 100 100     190 if ( ( $state eq 'NSW' ) && ( $year > 2011 ) ) {
461 1         6 push @holidays,
462             {
463             'name' => 'Additional Day',
464             'date' => sprintf '%02d%02d',
465             $month, ( $day + 4 ),
466             };
467             }
468             }
469             elsif ( $wday == 0 ) { # Christmas is on a Sunday
470 57         292 push @holidays,
471             {
472             'name' => 'Christmas Day Holiday',
473             'date' => sprintf '%02d%02d',
474             $month, ( $day + 2 ),
475             };
476 57 100 100     242 if ( ( $state eq 'NSW' ) && ( $year > 2011 ) ) {
477 1         6 push @holidays,
478             {
479             'name' => 'Additional Day',
480             'date' => sprintf '%02d%02d',
481             $month, ( $day + 3 ),
482             };
483             }
484             }
485 148         551 return @holidays;
486             }
487              
488             sub _compute_nt_show_day_hash {
489 15     15   34 my ( $year, $params ) = @_;
490 15         210 my %nt_show_day = (
491             alicesprings =>
492             { name => 'Alice Springs Show Day', month => 6, num_fridays => 1 },
493             tennantcreek =>
494             { name => 'Tennant Creek Show Day', month => 6, num_fridays => 2 },
495             katherine =>
496             { name => 'Katherine Show Day', month => 6, num_fridays => 3 },
497             darwin => { name => 'Darwin Show Day', month => 6, num_fridays => 4 },
498             borroloola =>
499             { name => 'Borrolooda Show Day', month => 7, num_fridays => 4 },
500             );
501 15         39 my ( $month, $num_fridays, $name );
502 15 100 100     71 if ( ( exists $params->{region} ) && ( defined $params->{region} ) ) {
503 5         14 my $region = lc $params->{region};
504 5         50 $region =~ s/\s*//smxg;
505 5 100       19 if ( $nt_show_day{$region} ) {
506 4         7 $name = $nt_show_day{$region}{name};
507 4         8 $month = $nt_show_day{$region}{month};
508 4         11 $num_fridays = $nt_show_day{$region}{num_fridays};
509             }
510             else {
511 1         229 Carp::croak('Unknown region');
512             }
513             }
514             else {
515 10         29 $name = $nt_show_day{darwin}{name};
516 10         89 $month = $nt_show_day{darwin}{month};
517 10         23 $num_fridays = $nt_show_day{darwin}{num_fridays};
518             }
519 14         22 my $day = 1;
520 14         93 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
521 14         839 my $fridays = 0;
522 14         31 my ( $sec, $min, $hour, $wday, $yday, $isdst );
523 14         42 while ( $fridays < $num_fridays ) {
524 270         17019 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
525             localtime $date;
526 270 100       945 if ( $wday == 5 ) {
527 50         76 $fridays += 1;
528             }
529 270 100       532 if ( $fridays < $num_fridays ) {
530 256         341 $day += 1;
531 256         648 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
532             }
533             }
534 14         137 my @holidays = (
535             {
536             name => $name,
537             date => sprintf '%02d%02d',
538             ( $month + 1 ), $day,
539             }
540             );
541 14         116 return @holidays;
542             }
543              
544             sub _compute_qld_show_day
545             { # second wednesday in august, except when there are five wednesdays in august when it is the third wednesday
546 7     7   17 my ($year) = @_;
547 7         14 my $day = 1;
548 7         13 my $month = 7;
549 7         23 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
550 7         401 my $wednesdays = 0;
551 7         17 my ( $sec, $min, $hour, $wday, $yday, $isdst );
552 7         0 my $num_wednesdays;
553 7         114 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
554             localtime $date;
555              
556 7 100 100     60 if ( ( $wday >= 1 ) && ( $wday <= 3 ) ) {
557 5         15 $num_wednesdays = 3;
558             }
559             else {
560 2         5 $num_wednesdays = 2;
561             }
562 7         23 while ( $wednesdays < $num_wednesdays ) {
563 103         6560 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
564             localtime $date;
565 103 100       330 if ( $wday == 3 ) {
566 19         70 $wednesdays += 1;
567             }
568 103 100       199 if ( $wednesdays < $num_wednesdays ) {
569 96         128 $day += 1;
570 96         261 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
571             }
572             }
573 7         51 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
574             }
575              
576             sub _compute_devonport_show
577             { # friday nearest last day in november, but not later than first day in december
578 4     4   14 my ($year) = @_;
579 4         8 my $month = 10;
580 4         11 my $day = $days_in_month[$month];
581 4         13 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
582 4         227 my ( $sec, $min, $hour, $wday, $yday, $isdst );
583 4         65 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
584             localtime $date;
585 4 100       23 if ( $wday == 4 ) { # thursday
586 1         4 $day = 1;
587 1         3 $month = 11;
588             }
589             else {
590 3         28 my %adjustment = ( 0 => 2, 1 => 3, 2 => 4, 3 => 5, 5 => 0, 6 => 1 );
591 3         12 $day -= $adjustment{$wday};
592             }
593 4         27 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
594             }
595              
596             sub _compute_devonport_cup
597             { # wednesday not earlier than fifth and not later than the eleventh of January
598 12     12   28 my ($year) = @_;
599 12         19 my $day = 5;
600 12         20 my $month = 0;
601 12         51 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
602 12         742 my ( $sec, $min, $hour, $wday, $yday, $isdst );
603 12         193 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
604             localtime $date;
605 12         46 while ( $wday != 3 ) {
606 40         77 $day += 1;
607 40         101 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
608 40         2530 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
609             localtime $date;
610             }
611 12         84 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
612             }
613              
614             sub _compute_launceston_cup { # last wednesday in feb
615 4     4   9 my ($year) = @_;
616 4         6 my $month = 1;
617 4         7 my $day = 28;
618              
619 4 100       11 if ( $year % 4 ) {
620             }
621             else {
622 3 100       9 if ( $year % 100 ) {
623 1         2 $day = 29;
624             }
625             else {
626 2 100       7 if ( $year % 400 ) {
627             }
628             else {
629 1         2 $day = 29;
630             }
631             }
632             }
633 4         26 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
634 4         268 my $wednesdays = 0;
635 4         9 my ( $sec, $min, $hour, $wday, $yday, $isdst );
636 4         11 while ( $wednesdays < 1 ) {
637 15         798 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
638             localtime $date;
639 15 100       51 if ( $wday == 3 ) {
640 4         7 $wednesdays += 1;
641             }
642 15 100       32 if ( $wednesdays < 1 ) {
643 11         17 $day -= 1;
644 11         30 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
645             }
646             }
647 4         24 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
648             }
649              
650             sub _compute_eight_hours_day { # second monday in march
651 40     40   81 my ($year) = @_;
652 40         73 my $day = 1;
653 40         58 my $month = 2;
654 40         151 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
655 40         2178 my $mondays = 0;
656 40         84 my ( $sec, $min, $hour, $wday, $yday, $isdst );
657 40         112 while ( $mondays < 2 ) {
658 380         22658 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
659             localtime $date;
660 380 100       1185 if ( $wday == 1 ) {
661 80         163 $mondays += 1;
662             }
663 380 100       751 if ( $mondays < 2 ) {
664 340         450 $day += 1;
665 340         1004 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
666             }
667             }
668 40         272 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
669             }
670              
671             sub _compute_king_island_show { # first tuesday in march
672 1     1   3 my ($year) = @_;
673 1         3 my $day = 1;
674 1         3 my $month = 2;
675 1         5 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
676 1         58 my $tuesdays = 0;
677 1         3 my ( $sec, $min, $hour, $wday, $yday, $isdst );
678 1         5 while ( $tuesdays < 1 ) {
679 2         80 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
680             localtime $date;
681 2 100       10 if ( $wday == 2 ) {
682 1         3 $tuesdays += 1;
683             }
684 2 100       7 if ( $tuesdays < 1 ) {
685 1         3 $day += 1;
686 1         6 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
687             }
688             }
689 1         7 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
690             }
691              
692             sub _compute_hobart_regatta { # second monday in feb
693 1     1   5 my ($year) = @_;
694 1         2 my $day = 1;
695 1         2 my $month = 1;
696 1         5 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
697 1         70 my $mondays = 0;
698 1         3 my ( $sec, $min, $hour, $wday, $yday, $isdst );
699 1         5 while ( $mondays < 2 ) {
700 9         662 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
701             localtime $date;
702 9 100       31 if ( $wday == 1 ) {
703 2         4 $mondays += 1;
704             }
705 9 100       20 if ( $mondays < 2 ) {
706 8         13 $day += 1;
707 8         20 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
708             }
709             }
710 1         9 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
711             }
712              
713             sub _compute_canberra_day { # third monday in march
714 7     7   21 my ($year) = @_;
715 7         64 my $day = 1;
716 7         14 my $month = 2;
717 7         64 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
718 7         381 my $mondays = 0;
719 7         17 my ( $sec, $min, $hour, $wday, $yday, $isdst );
720 7         22 while ( $mondays < 3 ) {
721 135         8394 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
722             localtime $date;
723 135 100       433 if ( $wday == 1 ) {
724 21         32 $mondays += 1;
725             }
726 135 100       243 if ( $mondays < 3 ) {
727 128         209 $day += 1;
728 128         332 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
729             }
730             }
731 7         51 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
732             }
733              
734             sub _compute_recreation_day { # first monday in november
735 3     3   9 my ($year) = @_;
736 3         6 my $day = 1;
737 3         6 my $month = 10;
738 3         10 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
739 3         168 my $mondays = 0;
740 3         7 my ( $sec, $min, $hour, $wday, $yday, $isdst );
741 3         9 while ( $mondays < 1 ) {
742 8         392 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
743             localtime $date;
744 8 100       32 if ( $wday == 1 ) {
745 3         6 $mondays += 1;
746             }
747 8 100       20 if ( $mondays < 1 ) {
748 5         10 $day += 1;
749 5         15 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
750             }
751             }
752 3         21 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
753             }
754              
755             sub _compute_melbourne_cup_day { # first tuesday in november
756 29     29   69 my ($year) = @_;
757 29         47 my $day = 1;
758 29         64 my $month = 10;
759 29         88 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
760 29         1715 my $tuesdays = 0;
761 29         64 my ( $sec, $min, $hour, $wday, $yday, $isdst );
762 29         96 while ( $tuesdays < 1 ) {
763 67         3122 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
764             localtime $date;
765 67 100       262 if ( $wday == 2 ) {
766 29         62 $tuesdays += 1;
767             }
768 67 100       175 if ( $tuesdays < 1 ) {
769 38         84 $day += 1;
770 38         119 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
771             }
772             }
773 29         184 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
774             }
775              
776             sub _compute_wa_foundation_day { # first monday in june
777 29     29   59 my ($year) = @_;
778 29         47 my $day = 1;
779 29         39 my $month = 5;
780 29         128 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
781 29         1651 my $mondays = 0;
782 29         62 my ( $sec, $min, $hour, $wday, $yday, $isdst );
783 29         88 while ( $mondays < 1 ) {
784 142         7841 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
785             localtime $date;
786 142 100       465 if ( $wday == 1 ) {
787 29         50 $mondays += 1;
788             }
789 142 100       317 if ( $mondays < 1 ) {
790 113         172 $day += 1;
791 113         299 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
792             }
793             }
794 29         168 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
795             }
796              
797             sub _compute_queens_bday { # second monday in june
798 121     121   255 my ($year) = @_;
799 121         208 my $day = 1;
800 121         175 my $month = 5;
801 121         332 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
802 121         6690 my $mondays = 0;
803 121         247 my ( $sec, $min, $hour, $wday, $yday, $isdst );
804 121         382 while ( $mondays < 2 ) {
805 1548         95473 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
806             localtime $date;
807 1548 100       5314 if ( $wday == 1 ) {
808 242         382 $mondays += 1;
809             }
810 1548 100       2883 if ( $mondays < 2 ) {
811 1427         2025 $day += 1;
812 1427         3869 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
813             }
814             }
815 121         700 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
816             }
817              
818             sub _compute_sa_volunteers_day { # third monday in may up excluding 2006
819 6     6   15 my ($year) = @_;
820 6 100       20 if ( $year == 2006 ) {
821 3         11 return ();
822             }
823 3         8 my $day = 1;
824 3         6 my $month = 4;
825 3         11 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
826 3         168 my $mondays = 0;
827 3         8 my ( $sec, $min, $hour, $wday, $yday, $isdst );
828 3         11 while ( $mondays < 3 ) {
829 48         2964 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
830             localtime $date;
831 48 100       153 if ( $wday == 1 ) {
832 9         19 $mondays += 1;
833             }
834 48 100       98 if ( $mondays < 3 ) {
835 45         66 $day += 1;
836 45         125 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
837             }
838             }
839 3         20 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
840             }
841              
842             sub _compute_sa_adelaide_cup_day { # second monday in march in 2006
843 6     6   19 my ($year) = @_;
844 6 100       23 if ( $year != 2006 ) {
845 3         11 return ();
846             }
847 3         6 my $day = 1;
848 3         9 my $month = 2;
849 3         10 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
850 3         166 my $mondays = 0;
851 3         10 my ( $sec, $min, $hour, $wday, $yday, $isdst );
852 3         13 while ( $mondays < 2 ) {
853 39         2413 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
854             localtime $date;
855 39 100       139 if ( $wday == 1 ) {
856 6         14 $mondays += 1;
857             }
858 39 100       79 if ( $mondays < 2 ) {
859 36         52 $day += 1;
860 36         92 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
861             }
862             }
863 3         22 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
864             }
865              
866             sub _compute_vic_labour_day { # second monday in march
867 31     31   79 my ($year) = @_;
868 31         55 my $day = 1;
869 31         90 my $month = 2;
870 31         106 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
871 31         1703 my $mondays = 0;
872 31         83 my ( $sec, $min, $hour, $wday, $yday, $isdst );
873 31         129 while ( $mondays < 2 ) {
874 357         21737 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
875             localtime $date;
876 357 100       1171 if ( $wday == 1 ) {
877 62         94 $mondays += 1;
878             }
879 357 100       714 if ( $mondays < 2 ) {
880 326         418 $day += 1;
881 326         856 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
882             }
883             }
884 31         228 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
885             }
886              
887             sub _compute_vic_grand_final_eve_day { # i have no words ...
888 31     31   72 my ($year) = @_;
889 31         55 my ( $day, $month );
890 31         473 my %grand_final_eve_day = (
891             2015 => { day => 2, month => 9 },
892             2016 => { day => 30, month => 8 },
893             2017 => { day => 29, month => 8 },
894             2018 => { day => 28, month => 8 },
895             2019 => { day => 27, month => 8 },
896             2020 => { day => 23, month => 9 }, # Technically "Thank you" day.
897             2021 => { day => 24, month => 8 },
898             2022 => { day => 23, month => 8 },
899             );
900 31 100       112 if ( $year < 2015 ) {
    100          
901 19         119 return ();
902             }
903             elsif ( $grand_final_eve_day{$year} ) {
904 11         25 $day = $grand_final_eve_day{$year}{day};
905 11         24 $month = $grand_final_eve_day{$year}{month};
906             }
907             else {
908 1         313 Carp::croak(
909             q[Don't know how to calculate Grand Final Eve Day in VIC for this year]
910             );
911             }
912 11         79 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
913             }
914              
915             sub _compute_wa_labour_day { # first monday in march
916 29     29   61 my ($year) = @_;
917 29         51 my $day = 1;
918 29         54 my $month = 2;
919 29         93 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
920 29         1687 my $mondays = 0;
921 29         69 my ( $sec, $min, $hour, $wday, $yday, $isdst );
922 29         85 while ( $mondays < 1 ) {
923 122         6500 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
924             localtime $date;
925 122 100       426 if ( $wday == 1 ) {
926 29         44 $mondays += 1;
927             }
928 122 100       270 if ( $mondays < 1 ) {
929 93         131 $day += 1;
930 93         245 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
931             }
932             }
933 29         181 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
934             }
935              
936             sub _compute_nt_may_day { # first monday in may
937 15     15   37 my ($year) = @_;
938 15         33 my $day = 1;
939 15         21 my $month = 4;
940 15         46 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
941 15         1018 my $mondays = 0;
942 15         31 my ( $sec, $min, $hour, $wday, $yday, $isdst );
943 15         53 while ( $mondays < 1 ) {
944 34         1462 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
945             localtime $date;
946 34 100       127 if ( $wday == 1 ) {
947 15         25 $mondays += 1;
948             }
949 34 100       86 if ( $mondays < 1 ) {
950 19         29 $day += 1;
951 19         62 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
952             }
953             }
954 15         89 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
955             }
956              
957             sub _compute_agfest { # friday following first thursday in may
958 2     2   7 my ($year) = @_;
959 2         5 my $day = 1;
960 2         7 my $month = 4;
961 2         9 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
962 2         118 my $thursdays = 0;
963 2         7 my ( $sec, $min, $hour, $wday, $yday, $isdst );
964 2         9 while ( $thursdays < 1 ) {
965 12         737 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
966             localtime $date;
967 12 100       42 if ( $wday == 4 ) {
968 2         4 $thursdays += 1;
969             }
970 12 100       27 if ( $thursdays < 1 ) {
971 10         17 $day += 1;
972 10         33 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
973             }
974             }
975 2         16 return ( sprintf '%02d%02d', ( $month + 1 ), ( $day + 1 ) );
976             }
977              
978             sub _compute_burnie_show { # friday preceding first saturday in october
979 8     8   22 my ($year) = @_;
980 8         19 my $day = 1;
981 8         18 my $month = 9;
982 8         29 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
983 8         487 my $saturdays = 0;
984 8         22 my ( $sec, $min, $hour, $wday, $yday, $isdst );
985 8         30 while ( $saturdays < 1 ) {
986 15         593 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
987             localtime $date;
988 15 100       62 if ( $wday == 6 ) {
989 8         19 $saturdays += 1;
990             }
991 15 100       52 if ( $saturdays < 1 ) {
992 7         19 $day += 1;
993 7         23 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
994             }
995             }
996 8 100       30 if ( $day == 1 ) {
997 1         9 return ( sprintf '%02d%02d', $month, $days_in_month[ $month - 1 ] );
998             }
999             else {
1000 7         50 return ( sprintf '%02d%02d', ( $month + 1 ), ( $day - 1 ) );
1001             }
1002             }
1003              
1004             sub _compute_launceston_show { # thursday preceding second saturday in october
1005 1     1   3 my ($year) = @_;
1006 1         4 my $day = 1;
1007 1         3 my $month = 9;
1008 1         5 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1009 1         58 my $saturdays = 0;
1010 1         4 my ( $sec, $min, $hour, $wday, $yday, $isdst );
1011 1         7 while ( $saturdays < 2 ) {
1012 9         530 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
1013             localtime $date;
1014 9 100       31 if ( $wday == 6 ) {
1015 2         6 $saturdays += 1;
1016             }
1017 9 100       22 if ( $saturdays < 2 ) {
1018 8         11 $day += 1;
1019 8         23 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1020             }
1021             }
1022 1         9 return ( sprintf '%02d%02d', ( $month + 1 ), ( $day - 2 ) );
1023             }
1024              
1025             sub _compute_flinders_island_show { # friday preceding third saturday in october
1026 1     1   3 my ($year) = @_;
1027 1         2 my $day = 1;
1028 1         25 my $month = 9;
1029 1         8 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1030 1         59 my $saturdays = 0;
1031 1         4 my ( $sec, $min, $hour, $wday, $yday, $isdst );
1032 1         5 while ( $saturdays < 3 ) {
1033 16         1019 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
1034             localtime $date;
1035 16 100       52 if ( $wday == 6 ) {
1036 3         6 $saturdays += 1;
1037             }
1038 16 100       31 if ( $saturdays < 3 ) {
1039 15         20 $day += 1;
1040 15         39 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1041             }
1042             }
1043 1         25 return ( sprintf '%02d%02d', ( $month + 1 ), ( $day - 1 ) );
1044             }
1045              
1046             sub _compute_hobart_show { # thursday preceding fourth saturday in october
1047 3     3   9 my ($year) = @_;
1048 3         6 my $day = 1;
1049 3         6 my $month = 9;
1050 3         11 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1051 3         184 my $saturdays = 0;
1052 3         9 my ( $sec, $min, $hour, $wday, $yday, $isdst );
1053 3         10 while ( $saturdays < 4 ) {
1054 69         4466 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
1055             localtime $date;
1056 69 100       228 if ( $wday == 6 ) {
1057 12         58 $saturdays += 1;
1058             }
1059 69 100       132 if ( $saturdays < 4 ) {
1060 66         92 $day += 1;
1061 66         161 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1062             }
1063             }
1064 3         27 return ( sprintf '%02d%02d', ( $month + 1 ), ( $day - 2 ) );
1065             }
1066              
1067             sub _compute_nt_picnic_day { # first monday in august
1068 14     14   42 my ($year) = @_;
1069 14         24 my $day = 1;
1070 14         21 my $month = 7;
1071 14         44 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1072 14         828 my $mondays = 0;
1073 14         47 my ( $sec, $min, $hour, $wday, $yday, $isdst );
1074 14         45 while ( $mondays < 1 ) {
1075 18         483 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
1076             localtime $date;
1077 18 100       74 if ( $wday == 1 ) {
1078 14         30 $mondays += 1;
1079             }
1080 18 100       61 if ( $mondays < 1 ) {
1081 4         7 $day += 1;
1082 4         12 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1083             }
1084             }
1085 14         87 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
1086             }
1087              
1088             sub _compute_nsw_act_bank_holiday { # first monday in august
1089 4     4   15 my ($year) = @_;
1090 4         9 my $day = 1;
1091 4         11 my $month = 7;
1092 4         35 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1093 4         231 my $mondays = 0;
1094 4         13 my ( $sec, $min, $hour, $wday, $yday, $isdst );
1095 4         13 while ( $mondays < 1 ) {
1096 10         451 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
1097             localtime $date;
1098 10 100       37 if ( $wday == 1 ) {
1099 4         9 $mondays += 1;
1100             }
1101 10 100       27 if ( $mondays < 1 ) {
1102 6         18 $day += 1;
1103 6         19 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1104             }
1105             }
1106 4         30 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
1107             }
1108              
1109             sub _compute_nsw_sa_act_labour_day { # first monday in october
1110 28     28   73 my ($year) = @_;
1111 28         51 my $day = 1;
1112 28         49 my $month = 9;
1113 28         94 my $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1114 28         1737 my $mondays = 0;
1115 28         56 my ( $sec, $min, $hour, $wday, $yday, $isdst );
1116 28         82 while ( $mondays < 1 ) {
1117 87         4281 ( $sec, $min, $hour, undef, undef, undef, $wday, $yday, $isdst ) =
1118             localtime $date;
1119 87 100       292 if ( $wday == 1 ) {
1120 28         60 $mondays += 1;
1121             }
1122 87 100       204 if ( $mondays < 1 ) {
1123 59         87 $day += 1;
1124 59         158 $date = Time::Local::timelocal( 0, 0, 0, $day, $month, $year );
1125             }
1126             }
1127 28         165 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
1128             }
1129              
1130             sub _compute_wa_queens_bday
1131             { # monday closest to 30 september??? Formula unknown. Seems to have a 9 day spread???
1132 29     29   56 my ($year) = @_;
1133 29         54 my ( $day, $month );
1134 29         854 my %wa_queens_bday = (
1135             2004 => { day => 4, month => 9 },
1136             2005 => { day => 26, month => 8 },
1137             2006 => { day => 2, month => 9 },
1138             2007 => { day => 1, month => 9 },
1139             2008 => { day => 29, month => 8 },
1140             2009 => { day => 28, month => 8 },
1141             2010 => { day => 27, month => 8 },
1142             2011 => { day => 28, month => 8 },
1143             2012 => { day => 1, month => 9 },
1144             2013 => { day => 30, month => 8 },
1145             2014 => { day => 29, month => 8 },
1146             2015 => { day => 28, month => 8 },
1147             2016 => { day => 26, month => 8 },
1148             2017 => { day => 25, month => 8 },
1149             2018 => { day => 24, month => 8 },
1150             2019 => { day => 30, month => 8 },
1151             2020 => { day => 28, month => 8 },
1152             2021 => { day => 27, month => 8 },
1153             2022 => { day => 26, month => 8 },
1154             2023 => { day => 25, month => 8 },
1155             );
1156 29 100       89 if ( $wa_queens_bday{$year} ) {
1157 28         62 $day = $wa_queens_bday{$year}{day};
1158 28         50 $month = $wa_queens_bday{$year}{month};
1159             }
1160             else {
1161 1         220 Carp::croak(
1162             q[Don't know how to calculate Queen's Birthday in WA for this year]
1163             );
1164             }
1165 28         284 return ( sprintf '%02d%02d', ( $month + 1 ), $day );
1166             }
1167              
1168             sub _compute_easter {
1169 150     150   370 my ( $year, $state ) = @_;
1170 150         532 my ( $month, $day ) = Date::Easter::gregorian_easter($year);
1171 150         3391 my $date = Time::Local::timelocal( 0, 0, 0, $day, ( $month - 1 ), $year );
1172 150         8444 my ( $sec, $min, $hour, $wday, $yday, $isdst );
1173 150         2443 ( $sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst ) =
1174             localtime $date;
1175 150         420 my @holidays;
1176              
1177             # good friday + easter saturday
1178 150 100       498 if ( $month == 2 ) { # march
1179 58         331 push @holidays, sprintf '%02d%02d', ( $month + 1 ), ( $day - 2 );
1180 58         190 push @holidays, sprintf '%02d%02d', ( $month + 1 ), ( $day - 1 );
1181             }
1182             else { # april
1183 92 100       297 if ( $day == 2 ) {
    100          
1184 1         6 push @holidays,
1185             sprintf '%02d%02d', $month, $days_in_month[ $month - 1 ];
1186 1         5 push @holidays, sprintf '%02d%02d', ( $month + 1 ), 1;
1187             }
1188             elsif ( $day == 1 ) {
1189 2         13 push @holidays,
1190             sprintf '%02d%02d', $month, ( $days_in_month[ $month - 1 ] - 1 );
1191 2         9 push @holidays,
1192             sprintf '%02d%02d', $month, ( $days_in_month[ $month - 1 ] );
1193             }
1194             else {
1195 89         458 push @holidays, sprintf '%02d%02d', ( $month + 1 ), ( $day - 2 );
1196 89         359 push @holidays, sprintf '%02d%02d', ( $month + 1 ), ( $day - 1 );
1197             }
1198             }
1199              
1200             # easter sunday
1201 150         500 push @holidays, sprintf '%02d%02d', ( $month + 1 ), $day;
1202              
1203             # easter monday
1204 150 100       398 if ( $month == 2 ) { # march
1205 58 100       183 if ( $day == $days_in_month[$month] ) {
1206 2         8 push @holidays, sprintf '%02d%02d', ( $month + 2 ), 1;
1207             }
1208             else {
1209 56         173 push @holidays, sprintf '%02d%02d', ( $month + 1 ), ( $day + 1 );
1210             }
1211             }
1212             else {
1213 92         258 push @holidays, sprintf '%02d%02d', ( $month + 1 ), ( $day + 1 );
1214             }
1215 150 100       418 if ( $state eq 'TAS' ) {
1216 40 100       92 if ( $month == 2 ) { # march
1217 5 100       26 if ( $day == $days_in_month[$month] ) {
    100          
1218 1         4 push @holidays, sprintf '%02d%02d', ( $month + 2 ), 2;
1219             }
1220             elsif ( ( $day + 1 ) == $days_in_month[$month] ) {
1221 1         5 push @holidays, sprintf '%02d%02d', ( $month + 2 ), 1;
1222             }
1223             else {
1224 3         12 push @holidays,
1225             sprintf '%02d%02d', ( $month + 1 ), ( $day + 2 );
1226             }
1227             }
1228             else {
1229 35         94 push @holidays, sprintf '%02d%02d', ( $month + 1 ), ( $day + 1 );
1230             }
1231             }
1232 150         663 return @holidays;
1233             }
1234              
1235             sub _compute {
1236 452     452   954 my ( $day, $month, $year, $params ) = @_;
1237 452         1355 my $date = Time::Local::timelocal( 0, 0, 0, $day, ( $month - 1 ), $year );
1238 452         27340 my ( $sec, $min, $hour, $wday, $yday, $isdst );
1239 452         0 my @holidays;
1240 452         2018 push @holidays, sprintf '%02d%02d', $month, $day;
1241 452 100       1209 if ( $params->{day_in_lieu} ) {
1242 367         5811 ( $sec, $min, $hour, $day, $month, $year, $wday, $yday, $isdst ) =
1243             localtime $date;
1244 367 100       1777 if ( $wday == 0 ) {
    100          
1245 35         77 $day += 1;
1246 35         168 push @holidays, sprintf '%02d%02d', ( $month + 1 ), $day;
1247             }
1248             elsif ( $wday == 6 ) {
1249 66         128 $day += 2;
1250 66         308 push @holidays, sprintf '%02d%02d', ( $month + 1 ), $day;
1251             }
1252             }
1253 452         1774 return (@holidays);
1254             }
1255              
1256             1;
1257              
1258             __END__