File Coverage

lib/Date/Holidays.pm
Criterion Covered Total %
statement 106 138 76.8
branch 28 50 56.0
condition 8 21 38.1
subroutine 21 23 91.3
pod 5 5 100.0
total 168 237 70.8


line stmt bran cond sub pod time code
1              
2             use strict;
3 1     1   7149 use warnings;
  1         2  
  1         25  
4 1     1   4 use vars qw($VERSION);
  1         2  
  1         23  
5 1     1   4  
  1         2  
  1         37  
6             use Locale::Country qw(all_country_codes code2country);
7 1     1   4 use Module::Load qw(load);
  1         2  
  1         78  
8 1     1   442 use DateTime;
  1         969  
  1         6  
9 1     1   856 use Try::Tiny;
  1         441877  
  1         37  
10 1     1   7 use Scalar::Util qw(blessed);
  1         2  
  1         51  
11 1     1   5  
  1         2  
  1         38  
12             use base 'Date::Holidays::Adapter';
13 1     1   5  
  1         2  
  1         400  
14             our $VERSION = '1.33'; # VERSION: generated by DZP::OurPkgVersion
15              
16             my ( $class, %params ) = @_;
17              
18 257     257 1 52504 my $self = bless {
19             _inner_object => undef,
20 257   33     1254 _inner_class => undef,
21             _countrycode => undef,
22             },
23             ref $class || $class;
24              
25             if ( $params{'countrycode'} ) {
26             if ( code2country( $params{countrycode} ) ) {
27 257 50       521 $self->{'_countrycode'} = uc $params{countrycode};
28 257 100       632 }
29 250         9193 else {
30             $self->{'_countrycode'} = $params{countrycode};
31             }
32 7         270  
33             try {
34             $self->{'_inner_class'} = $self->_fetch(
35             { nocheck => $params{'nocheck'},
36             countrycode => $params{'countrycode'},
37             }
38 257     257   4990 );
39             };
40             }
41 257         1005 else {
42             die "No country code specified\n";
43             }
44 0         0  
45             if ( $self
46             && $self->{'_inner_class'}
47 257 50 33     4494 && $self->{'_inner_class'}->can('new') )
    0 33        
48             {
49             try {
50             my $adapter = $self->{'_inner_class'}->new(
51             countrycode => $self->{'_countrycode'},
52             nocheck => $params{'nocheck'},
53             );
54 257     257   9074  
55             if ($adapter) {
56             $self->{'_inner_object'} = $adapter;
57 256 50       449 }
58 256         578 else {
59             warn "Adapter not defined\n";
60             $self = undef;
61 0         0 }
62 0         0 } catch {
63             warn "Unable to initialize adapter: $_\n";
64             $self = undef;
65 1     1   46 };
66 1         9  
67 257         1405 }
68             elsif ( !$self->{'_inner_class'} ) {
69             warn "No inner class instantiated\n";
70             $self = undef;
71 0         0 }
72 0         0  
73             return $self;
74             }
75 257         2942  
76             my ( $self, %params ) = @_;
77              
78             # Our result
79 4     4 1 1031 my $r;
80              
81             # Did we get a country list
82 4         6 if ( not $params{'countries'} ) {
83              
84             #No countries - so we create a list
85 4 50       11 my @countries = all_country_codes(); # From Locale::Country
86             @countries = sort @countries;
87              
88 4         16 # We stick the complete list of countries to the parameters
89 4         631 $params{'countries'} = \@countries;
90             }
91              
92 4         14 $r = $self->{'_inner_object'}->holidays(%params);
93              
94             return $r;
95 4         16 }
96              
97 4         82 my ( $self, %params ) = @_;
98              
99             # Our result
100             my $r;
101 254     254 1 121892  
102             if ( not $params{'countries'} ) {
103             if ( blessed $self) {
104 254         290 $r = $self->{'_inner_object'}->is_holiday(%params);
105             }
106 254 100       480 else {
107 253 100       749 my @countries = all_country_codes(); # From Locale::Country
108 252         719 @countries = sort @countries;
109             $params{'countries'} = \@countries;
110              
111 1         3 $r = __PACKAGE__->_check_countries(%params);
112 1         170 }
113 1         4  
114             }
115 1         5 else {
116             if ( blessed $self) {
117             $r = $self->_check_countries(%params);
118              
119             }
120 1 50       5 else {
121 0         0 $r = __PACKAGE__->_check_countries(%params);
122             }
123             }
124              
125 1         3 return $r;
126             }
127              
128             my ( $self, %params ) = @_;
129 13         144  
130             my $hashref = $self->holidays( year => $params{'year'} );
131             my %dts;
132              
133 0     0 1 0 foreach my $h ( keys %{$hashref} ) {
134             my ( $month, $day ) = $h =~ m{
135 0         0 \A # Beginning of string
136 0         0 (\d{2}) # 2 digits indicating the month
137             (\d{2}) # 2 digits indicating the day
138 0         0 \Z # End of string
  0         0  
139 0         0 }xsm;
140             my $dt = DateTime->new(
141             year => $params{'year'},
142             month => $month,
143             day => $day,
144             );
145             $dts{ $hashref->{$h} } = $dt;
146 0         0 }
147              
148             return \%dts;
149             }
150 0         0  
151             my ( $self, %params ) = @_;
152              
153 0         0 my $result = {};
154             my $precedent_calendar = q{};
155              
156             foreach my $country ( @{ $params{'countries'} } ) {
157 2     2   8  
158             #The list of countries is ordered
159 2         3 if ( $country =~ m/\A[+](\w+)/xism ) {
160 2         4 $country = $1;
161             $precedent_calendar = $country;
162 2         2 }
  2         5  
163              
164             try {
165 250 50       1096 my $dh = $self->new(
166 0         0 countrycode => $country,
167 0         0 nocheck => $params{nocheck}
168             );
169              
170             if ( !$dh ) {
171             my $countryname = code2country($country);
172             my $countrycode = $country;
173              
174 250     250   9162 die
175             "Unable to initialize Date::Holidays for country: $countrycode - $countryname\n";
176 250 100       550 }
177 1         4  
178 1         36 my %prepared_parameters = (
179             year => $params{'year'},
180 1         6 month => $params{'month'},
181             day => $params{'day'},
182             );
183              
184             if ( $params{gov} ) {
185             $prepared_parameters{gov} = $params{gov};
186             }
187 249         848  
188             if ( $params{lang} ) {
189             $prepared_parameters{lang} = $params{lang};
190 249 50       471 }
191 0         0  
192             # did we receive special regions parameter?
193             if ( $params{regions} ) {
194 249 50       414 $prepared_parameters{regions} = $params{regions};
195 0         0 }
196              
197             # did we receive special state parameter?
198             if ( $params{state} ) {
199 249 50       360 $prepared_parameters{state} = $params{state};
200 0         0 }
201              
202             my $r = $dh->is_holiday(%prepared_parameters);
203              
204 249 50       391 if ( $precedent_calendar eq $country ) {
205 0         0 $self->{precedent_calendar} = $dh;
206             }
207              
208 249         951 # handling precedent calendar
209             if ( $precedent_calendar
210 8 50       17 and $precedent_calendar ne $country )
211 0         0 {
212              
213             my $holiday = $self->{precedent_calendar}
214             ->is_holiday(%prepared_parameters);
215 8 50 33     17  
216             # our precedent calendar dictates overwrite or nullification
217             if ( defined $holiday ) {
218             $r = $holiday;
219             }
220 0         0 }
221              
222             if ( defined $r ) {
223 0 0       0 $result->{$country} = $r;
224 0         0 }
225             }
226             catch {
227             warn "$_\n";
228 8 50       60 }
229 0         0 }
230              
231             return $result;
232             }
233 242     242   20458  
234             my $self = shift;
235 250         1801 my $dt = shift;
236              
237 2         25 return $self->is_holiday(
238             year => $dt->year,
239             month => $dt->month,
240             day => $dt->day,
241 0     0 1 0 @_,
242 0         0 );
243             }
244 0         0  
245             my ( $self, $params ) = @_;
246              
247             # Do we have a country code?
248             if ( not $self->{'_countrycode'} and not $params->{countrycode} ) {
249             die "No country code specified\n";
250             }
251              
252             my $countrycode = $params->{countrycode} || $self->{'_countrycode'};
253 257     257   402  
254             # Do we do country code assertion?
255             if ( !$params->{'nocheck'} ) {
256 257 0 33     494  
257 0         0 # Is our country code valid or local?
258             if ( $countrycode !~ m/\Alocal\Z/xism
259             and not code2country($countrycode) )
260 257   33     457 { #from Locale::Country
261             die "$countrycode is not a valid country code\n";
262             }
263 257 100       412 }
264              
265             # Trying to load adapter module for country code
266 254 50 66     629 my $module;
267              
268             try {
269 0         0 # We load an adapter implementation
270             if ( $countrycode =~ m/\Alocal\Z/xism ) {
271             $module = 'Date::Holidays::Adapter::Local';
272             }
273             elsif ( code2country($countrycode) ) {
274 257         7784 $module = 'Date::Holidays::Adapter::' . uc $countrycode;
275             }
276             else {
277             $module = 'Date::Holidays::Adapter::' . $countrycode;
278 257 100   257   7768 }
    100          
279 4         8  
280             $module = $self->_load($module);
281              
282 250         7449 }
283             catch {
284             warn "Unable to load module: $module - $_\n";
285 3         85  
286             try {
287              
288 257         717 # We load an adapter implementation
289             $module = 'Date::Holidays::Adapter::' . $countrycode;
290              
291             if ( $module = $self->_load($module) ) {
292 224     224   9500 warn "we got a module and we return\n";
293             }
294              
295             }
296             catch {
297 224         8099 warn "Unable to load module: $module - $_\n";
298              
299 224 0       610 $module = 'Date::Holidays::Adapter';
300 0         0 $module = $self->_load($module);
301             };
302             };
303              
304             # Returning name of loaded module upon success
305 224         9280 return $module;
306             }
307 224         1026  
308 224         759 1;
309 224         2375  
310 257         1213  
311             =pod
312              
313 257         3006 =encoding UTF-8
314              
315             =begin markdown
316              
317             # Date::Holidays
318              
319             [![CPAN version](https://badge.fury.io/pl/Date-Holidays.svg)](http://badge.fury.io/pl/Date-Holidays)
320             ![stability-stable](https://img.shields.io/badge/stability-stable-green.svg)
321             [![Build Status](https://travis-ci.org/jonasbn/perl-date-holidays.svg?branch=master)](https://travis-ci.org/jonasbn/perl-date-holidays)
322             [![Coverage Status](https://coveralls.io/repos/github/jonasbn/perl-date-holidays/badge.svg?branch=master)](https://coveralls.io/github/jonasbn/perl-date-holidays?branch=master)
323             [![License: Artistic-2.0](https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg)](https://opensource.org/licenses/Artistic-2.0)
324              
325             <!-- MarkdownTOC autoanchor=false -->
326              
327             <!-- /MarkdownTOC -->
328              
329             =end markdown
330              
331             =head1 NAME
332              
333             Date::Holidays - Date::Holidays::* adapter and aggregator for all your holiday needs
334              
335             =head1 VERSION
336              
337             The documentation describes version 1.33 of Date::Holidays
338              
339             =head1 FEATURES
340              
341             =over
342              
343             =item * Exposes a uniform interface towards modules in the Date::Holidays::* namespace
344              
345             =item * Inquire whether a certain date is a holiday in a specific country or a set of countries
346              
347             =item * Inquire for a holidays for a given year for a specific country or a set of countries
348              
349             =item * Overwrite/rename/suppress national holidays with your own calendar
350              
351             =back
352              
353             =head1 SYNOPSIS
354              
355             use Date::Holidays;
356              
357             # Initialize a national holidays using the ISO 3361 country code
358             my $dh = Date::Holidays->new(
359             countrycode => 'dk'
360             );
361              
362             # Inquire and get a local name for a holiday if it is a national holiday
363             my $holidayname = $dh->is_holiday(
364             year => 2004,
365             month => 12,
366             day => 25
367             );
368              
369             # Inquire and get a set of local names for national holiday in a given country
370             my $hashref = $dh->holidays(
371             year => 2004
372             );
373              
374             # Inquire and get local names for a set of countries, where the specific date is a
375             # national holiday
376             $holidays_hashref = Date::Holidays->is_holiday(
377             year => 2004,
378             month => 12,
379             day => 25,
380             countries => ['se', 'dk', 'no'],
381             );
382              
383             foreach my $country (keys %{$holidays_hashref}) {
384             print $holidays_hashref->{$country}."\n";
385             }
386              
387             # Example of a module with additional parameters
388             # Australia is divided into states with local holidays
389             # using ISO-3166-2 codes
390             my $dh = Date::Holidays->new(
391             countrycode => 'au'
392             );
393              
394             $holidayname = $dh->is_holiday(
395             year => 2004,
396             month => 12,
397             day => 25,
398             state => 'TAS',
399             );
400              
401             $hashref = $dh->holidays(
402             year => 2004
403             state => 'TAS',
404             );
405              
406             # Another example of a module with additional parameters
407             # Great Britain is divided into regions with local holidays
408             # using ISO-3166-2 codes
409             my $dh = Date::Holidays->new(
410             countrycode => 'gb'
411             );
412              
413             $holidayname = $dh->is_holiday(
414             year => 2014,
415             month => 12,
416             day => 25,
417             regions => ['EAW'],
418             );
419              
420             $hashref = $dh->holidays(
421             year => 2014
422             regions => ['EAW'],
423             );
424              
425             =head1 DESCRIPTION
426              
427             Date::Holidays is an adapters exposing a uniform API to a set of distributions
428             in the Date::Holidays::* namespace. All of these modules deliver methods and
429             information on national calendars, but no standardized API exist.
430              
431             The distributions more or less follow a I<de> I<facto> standard (see: also the generic
432             adapter L<Date::Holidays::Adapter|https://metacpan.org/pod/Date::Holidays::Adapter>), but the adapters are implemented to uniform
433             this and Date::Holidays exposes a more readable API and at the same time it
434             provides an OO interface, to these diverse implementations, which primarily
435             holds a are procedural.
436              
437             As described below it is recommended that a certain API is implemented (SEE:
438             B<holidays> and B<is_holiday> below), but taking the adapter strategy into
439             consideration this does not matter, or we attempt to do what we can with what is
440             available on CPAN.
441              
442             If you are an module author/CPAN contributor who wants to comply to the suggested,
443             either look at some of the other modules in the Date::Holidays::* namespace to get an
444             idea of the I<de> I<facto> standard or have a look at L<Date::Holidays::Abstract|https://metacpan.org/pod/Date::Holidays::Abstract> and
445             L<Date::Holidays::Super|https://metacpan.org/pod/Date::Holidays::Super> - or write me.
446              
447             In addition to the adapter feature, Date::Holidays also do aggregation, so you
448             can combine calendars and you can overwrite and redefined existing calendars.
449              
450             =head2 DEFINING YOUR OWN CALENDAR
451              
452             As mentioned in the FEATURES section it is possible to create your own local calendar.
453              
454             This can be done using a L<JSON|https://metacpan.org/pod/JSON> file with your local definitions:
455              
456             {
457             "1501" : "jonasbn's birthday"
458             }
459              
460             This also mean you can overwrite your national calendar:
461              
462             {
463             "1225" : ""
464             }
465              
466              
467             You can specify either month plus day for a recurring holiday. If you you want to define
468             a holiday for a specific year, simply extend the date with year:
469              
470             {
471             "201.1625" : ""
472             }
473              
474             In order for the calendar to be picked up by Date::Holidays, set the environment variable:
475              
476             $HOLIDAYS_FILE
477              
478             This should point to the JSON file.
479              
480             =head1 SUBROUTINES/METHODS
481              
482             =head2 new
483              
484             This is the constructor. It takes the following parameters:
485              
486             =over
487              
488             =item countrycode (MANDATORY, see below), unique two letter code representing a country name. Please refer to ISO3166 (or L<Locale::Country|https://metacpan.org/pod/Locale::Country>)
489              
490             =item nocheck (optional), if set to true the countrycode specified will not be validated against a list of known country codes for existence, so you can build fake holidays for fake countries, I currently use this for test. This parameter might disappear in the future.
491              
492             =back
493              
494             The constructor loads the module from Date::Holidays::*, which matches the
495             country code and returns a Date::Holidays module with the specified module
496             loaded and ready to answer to any of the following methods described below, if
497             these are implemented - of course.
498              
499             If no countrycode is provided or the class is not able to load a module, nothing
500             is returned.
501              
502             my $dh = Date::Holidays->new(countrycode => 'dk')
503             or die "No holidays this year, get back to work!\n";
504              
505             =head2 holidays
506              
507             This is a wrapper around the loaded module's B<holidays> method if this is
508             implemented. If this method is not implemented it tries <countrycode>_holidays.
509              
510             Takes 3 optional named arguments:
511              
512             =over
513              
514             =item * year, four digit parameter representing year
515              
516             =item * state, ISO-3166-2 code for a state
517              
518             Not all countries support this parameter
519              
520             =item * regions, pointing to a reference to an array of ISO-3166-2 code for regions
521              
522             Not all countries support this parameter
523              
524             =back
525              
526             $hashref = $dh->holidays(year => 2007);
527              
528             =head2 holidays_dt
529              
530             This method is similar to holidays. It takes one named argument b<year>.
531              
532             The result is a hashref just as for B<holidays>, but instead the names
533             of the holidays are used as keys and the values are DateTime objects.
534              
535             =head2 is_holiday
536              
537             This is yet another wrapper around the loaded module's B<is_holiday>
538             method if this is implemented. Also if this method is not implemented
539             it tries is_<countrycode>_holiday.
540              
541             Takes 6 optional named arguments:
542              
543             =over
544              
545             =item * year, four digit parameter representing year
546              
547             =item * month, 1-12, representing month
548              
549             =item * day, 1-31, representing day
550              
551             =item * countries (OPTIONAL), a list of ISO3166 country codes
552              
553             =item * state, ISO-3166-2 code for a state. Not all countries support this parameter
554              
555             =item * regions, pointing to a reference to an array of ISO-3166-2 code for regions. Not all countries support this parameter
556              
557             =back
558              
559             is_holiday returns the name of a holiday is present in the country specified by
560             the country code provided to the Date::Holidays constructor.
561              
562             $name = $dh->is_holiday(year => 2007, day => 24, month => 12);
563              
564             If this method is called using the class name B<Date::Holidays>, all known
565             countries are tested for a holiday on the specified date, unless the countries
566             parameter specifies a subset of countries to test.
567              
568             $hashref = Date::Holidays->is_holiday(year => 2007, day => 24, month => 12);
569              
570             In the case where a set of countries are tested the return value from the method
571             is a hashref with the country codes as keys and the values as the result.
572              
573             =over
574              
575             =item C<undef> if the country has no module or the data could not be obtained
576              
577             =item a name of the holiday if a holiday is present
578              
579             =item an empty string if the a module was located but the day is not a holiday
580              
581             =back
582              
583             =head2 is_holiday_dt
584              
585             This method is similar to is_holiday, but instead of 3 separate arguments it
586             only takes a single argument, a DateTime object.
587              
588             Return 1 for true if the object is a holiday and 0 for false if not.
589              
590             =head1 DEVELOPING A DATE::HOLIDAYS::* MODULE
591              
592             There is no control of the Date::Holidays::* namespace at all, so I am by no
593             means an authority, but this is recommendations on order to make the modules
594             in the Date::Holidays more uniform and thereby more usable.
595              
596             If you want to participate in the effort to make the Date::Holidays::* namespace
597             even more usable, feel free to do so, your feedback and suggestions will be
598             more than welcome.
599              
600             If you want to add your country to the Date::Holidays::* namespace, please feel
601             free to do so. If a module for you country is already present, I am sure the
602             author would not mind patches, suggestions or even help.
603              
604             If however you country does not seem to be represented in the namespace, you
605             are more than welcome to become the author of the module in question.
606              
607             Please note that the country code is expected to be a two letter code based on
608             ISO3166 (or L<Locale::Country|https://metacpan.org/pod/Locale::Country>).
609              
610             As an experiment I have added two modules to the namespace,
611             L<Date::Holidays::Abstract|https://metacpan.org/pod/Date::Holidays::Abstract> and L<Date::Holidays::Super|https://metacpan.org/pod/Date::Holidays::Super>, abstract is attempt
612             to make sure that the module implements some, by me, expected methods.
613              
614             So by using abstract your module will not work until it follows the the abstract
615             laid out for a Date::Holidays::* module. Unfortunately the module will only
616             check for the presence of the methods not their prototypes.
617              
618             L<Date::Holidays::Super|https://metacpan.org/pod/Date::Holidays::Super> is for the lazy programmer, it implements the necessary
619             methods as stubs and there for do not have to implement anything, but your
620             module will not return anything of value. So the methods need to be overwritten
621             in order to comply with the expected output of a Date::Holidays::* method.
622              
623             The methods which are currently interesting in a Date::Holidays::* module are:
624              
625             =over
626              
627             =item is_holiday
628              
629             Takes 3 arguments: year, month, day and returns the name of the holiday as a
630             scalar in the national language of the module context in question. Returns
631             undef if the requested day is not a holiday.
632              
633             Modified example taken from: L<Date::Holidays::DK|https://metacpan.org/pod/Date::Holidays::DK>
634              
635             use Date::Holidays::DK;
636             my ($year, $month, $day) = (localtime)[ 5, 4, 3 ];
637              
638             $year += 1900;
639             $month += 1;
640             print "Woohoo" if is_holiday( $year, $month, $day );
641              
642             #The actual method might not be implemented at this time in the
643             #example module.
644              
645             =item is_<countrycode>_holiday
646              
647             Same as above.
648              
649             This method however should be a wrapper of the above method (or the other way
650             around).
651              
652             =item holidays
653              
654             Takes 1 argument: year and returns a hashref containing all of the holidays in
655             specified for the country, in the national language of the module context in
656             question.
657              
658             The keys are the dates, month + day in two digits each concatenated.
659              
660             Modified example taken from: L<Date::Holidays::PT|https://metacpan.org/pod/Date::Holidays::PT>
661              
662             my $h = holidays($year);
663             printf "Jan. 1st is named '%s'\n", $h->{'0101'};
664              
665             #The actual method might not be implemented at this time in the
666             #example module.
667              
668             =item <countrycode>_holidays
669              
670             This method however should be a wrapper of the above method (or the other way
671             around).
672              
673             =back
674              
675             B<Only> B<is_holiday> and B<holidays> are implemented in
676             L<Date::Holidays::Super|https://metacpan.org/pod/Date::Holidays::Super> and are required by L<Date::Holidays::Abstract|https://metacpan.org/pod/Date::Holidays::Abstract>.
677              
678             =head2 ADDITIONAL PARAMETERS
679              
680             Some countries are divided into regions or similar and might require additional
681             parameters in order to give more exact holiday data.
682              
683             This is handled by adding additional parameters to B<is_holiday> and
684             B<holidays>.
685              
686             These parameters are left to the module authors discretion and the actual
687             Date::Holidays::* module should be consulted.
688              
689             Example Date::Holidays::AU
690              
691             use Date::Holidays::AU qw( is_holiday );
692              
693             my ($year, $month, $day) = (localtime)[ 5, 4, 3 ];
694             $year += 1900;
695             $month += 1;
696              
697             my ($state) = 'VIC';
698             print "Excellent\n" if is_holiday( $year, $month, $day, $state );
699              
700             =head1 DEVELOPING A DATE::HOLIDAYS::ADAPTER CLASS
701              
702             If you want to contribute with an adapter, please refer to the documentation in
703             L<Date::Holidays::Adapter|https://metacpan.org/pod/Date::Holidays::Adapter>.
704              
705             =head1 DEVELOPING ON DATE::HOLIDAYS
706              
707             Date::Holidays is distributed and maintained using L<Dist::Zilla|https://metacpan.org/pod/Dist::Zilla>
708              
709             =head2 RUNNING THE TEST SUITE
710              
711             The test suite can be executed using
712              
713             $ dzil test
714              
715             The test suite, which attempts lots scenarios does emit a lot of warnings, so it is recommended to suppress C<STDERR> by redirecting it to C</dev/null>
716              
717             $ dzil test 2> /dev/null
718              
719             To enable author tests aimed at asserting distribution and code quality in addition to functionality, use the C<--author> flag
720              
721             $ dzil test --author 2> /dev/null
722              
723             If you are working on a release, use the C<--release> flag
724              
725             $ dzil test --release 2> /dev/null
726              
727             The release flag is implicit for the L<Dist::Zilla|https://metacpan.org/pod/Dist::Zilla> release command.
728              
729             =head1 DIAGNOSTICS
730              
731             =over
732              
733             =item * No country code specified
734              
735             No country code has been specified.
736              
737             =item * Unable to initialize Date::Holidays for country: <countrycode>
738              
739             This message is emitted if a given country code cannot be loaded.
740              
741             =back
742              
743             =head1 CONFIGURATION AND ENVIRONMENT
744              
745             As mentioned in the section on defining your own calendar. You have to
746             set the environment variable:
747              
748             $HOLIDAYS_FILE
749              
750             This environment variable should point to a JSON file containing holiday definitions
751             to be used by L<Date::Holidays::Adapter::Local|https://metacpan.org/pod/Date::Holidays::Local>.
752              
753             =head1 DEPENDENCIES
754              
755             =over
756              
757             =item * L<Carp|https://metacpan.org/pod/Carp>
758              
759             =item * L<DateTime|https://metacpan.org/pod/DateTime>
760              
761             =item * L<Locale::Country|https://metacpan.org/pod/Locale::Country>
762              
763             =item * L<Module::Load|https://metacpan.org/pod/Module::Load>
764              
765             =item * L<Try::Tiny|https://metacpan.org/pod/Try::Tiny>
766              
767             =item * L<Scalar::Util|https://metacpan.org/pod/Scalar::Util>
768              
769             =item * L<JSON|https://metacpan.org/pod/JSON>
770              
771             =item * L<File::Slurp|https://metacpan.org/pod/File::Slurp>
772              
773             =back
774              
775             =head2 FOR TESTING
776              
777             =over
778              
779             =item * L<Test::Class|https://metacpan.org/pod/Test::Class>
780              
781             =item * L<Test::More|https://metacpan.org/pod/Test::More>
782              
783             =item * L<FindBin|https://metacpan.org/pod/FindBin>
784              
785             =back
786              
787             Please see the F<cpanfile> included in the distribution for a complete listing.
788              
789             =head1 INCOMPATIBILITIES
790              
791             Currently the following CPAN Date::Holidays distributions are unsupported:
792              
793             =over
794              
795             =item * L<Date::Holidays::UK|https://metacpan.org/pod/Date::Holidays::UK> only supports bank holidays until 2007
796              
797             =item * L<Date::Holidays::UK::EnglandAndWales|https://metacpan.org/pod/Date::Holidays::UK::EnglandAndWales> only supports bank holidays until 2014
798              
799             =back
800              
801             Additional issues might be described the specific adapter classes or their respective adaptees.
802              
803             =head1 BUGS AND LIMITATIONS
804              
805             Currently we have an exception for the L<Date::Holidays::AU|https://metacpan.org/pod/Date::Holidays::AU> module, so the
806             additional parameter of state is defaulting to 'VIC', please refer to the POD
807             for L<Date::Holidays::AU|https://metacpan.org/pod/Date::Holidays::AU> for documentation on this.
808              
809             L<Date::Holidays::DE|https://metacpan.org/pod/Date::Holidays::DE> and L<Date::Holidays::UK|https://metacpan.org/pod/Date::Holidays::UK> does not implement the
810             B<holidays> methods
811              
812             The adaptee module for L<Date::Holidays::Adapter::JP|https://metacpan.org/pod/Date::Holidays::Adapter::JP> is named:
813             L<Date::Japanese::Holiday|https://metacpan.org/pod/Date::Japanese::Holiday>, but the adapter class is following the general
814             adapter naming of Date::Holidays::Adapter::<countrycode>.
815              
816             The adapter for L<Date::Holidays::PT|https://metacpan.org/pod/Date::Holidays::PT>, L<Date::Holidays::Adapter::PT|https://metacpan.org/pod/Date::Holidays::Adapter::PT> does not
817             implement the B<is_pt_holiday> method. The pattern used is an object adapter
818             pattern and inheritance is therefor not used, it is my hope that I can
819             make this work with some Perl magic.
820              
821             =head1 ISSUE REPORTING
822              
823             Please report any bugs or feature requests using B<GitHub>.
824              
825             =over
826              
827             =item * L<GitHub Issues|https://github.com/jonasbn/perl-date-holidays/issues>
828              
829             =back
830              
831             =head1 TEST COVERAGE
832              
833             Coverage reports are available via L<Coveralls.io|https://coveralls.io/github/jonasbn/perl-date-holidays?branch=master>
834              
835             =begin markdown
836              
837             [![Coverage Status](https://coveralls.io/repos/github/jonasbn/perl-date-holidays/badge.svg?branch=master)](https://coveralls.io/github/jonasbn/perl-date-holidays?branch=master)
838              
839             =end markdown
840              
841             Without the actual holiday implementations installed/available coverage will be very low.
842              
843             Please see L<Task::Date::Holidays|https://metacpan.org/pod/Task::Date::Holidays>, which is a distribution, which can help in installing all the wrapped (adapted and aggregated) distributions.
844              
845             =head1 SEE ALSO
846              
847             =over
848              
849             =item * L<Date::Holidays::AT|https://metacpan.org/pod/Date::Holidays::AT>
850              
851             =item * L<Date::Holidays::Adapter::AT|https://metacpan.org/pod/Date::Holidays::Adapter::AT>
852              
853             =item * L<Date::Holidays::AU|https://metacpan.org/pod/Date::Holidays::AU>
854              
855             =item * L<Date::Holidays::Adapter::AU|https://metacpan.org/pod/Date::Holidays::Adapter::AU>
856              
857             =item * L<Date::Holidays::BR|https://metacpan.org/pod/Date::Holidays::BR>
858              
859             =item * L<Date::Holidays::Adapter::BR|https://metacpan.org/pod/Date::Holidays::Adapter::BR>
860              
861             =item * L<Date::Holidays::AW|https://metacpan.org/pod/Date::Holidays::AW>
862              
863             =item * L<Date::Holidays::Adapter::AW|https://metacpan.org/pod/Date::Holidays::Adapter::AW>
864              
865             =item * L<Date::Holidays::BY|https://metacpan.org/pod/Date::Holidays::BY>
866              
867             =item * L<Date::Holidays::Adapter::BY|https://metacpan.org/pod/Date::Holidays::Adapter::BY>
868              
869             =item * L<Date::Holidays::BQ|https://metacpan.org/pod/Date::Holidays::BQ>
870              
871             =item * L<Date::Holidays::Adapter::BQ|https://metacpan.org/pod/Date::Holidays::Adapter::BQ>
872              
873             =item * L<Date::Holidays::CA|https://metacpan.org/pod/Date::Holidays::CA>
874              
875             =item * L<Date::Holidays::CA_ES|https://metacpan.org/pod/Date::Holidays::CA_ES>
876              
877             =item * L<Date::Holidays::Adapter::CA_ES|https://metacpan.org/pod/Date::Holidays::Adapter::CA_ES>
878              
879             =item * L<Date::Holidays::CN|https://metacpan.org/pod/Date::Holidays::CN>
880              
881             =item * L<Date::Holidays::Adapter::CN|https://metacpan.org/pod/Date::Holidays::Adapter::CN>
882              
883             =item * L<Date::Holidays::CZ|https://metacpan.org/pod/Date::Holidays::CZ>
884              
885             =item * L<Date::Holidays::Adapter::CZ|https://metacpan.org/pod/Date::Holidays::Adapter::CZ>
886              
887             =item * L<Date::Holidays::DE|https://metacpan.org/pod/Date::Holidays::DE>
888              
889             =item * L<Date::Holidays::Adapter::DE|https://metacpan.org/pod/Date::Holidays::Adapter::DE>
890              
891             =item * L<Date::Holidays::DK|https://metacpan.org/pod/Date::Holidays::DK>
892              
893             =item * L<Date::Holidays::Adapter::DK|https://metacpan.org/pod/Date::Holidays::Adapter::DK>
894              
895             =item * L<Date::Holidays::ES|https://metacpan.org/pod/Date::Holidays::ES>
896              
897             =item * L<Date::Holidays::Adapter::ES|https://metacpan.org/pod/Date::Holidays::Adapter::ES>
898              
899             =item * L<Date::Holidays::FR|https://metacpan.org/pod/Date::Holidays::FR>
900              
901             =item * L<Date::Holidays::Adapter::FR|https://metacpan.org/pod/Date::Holidays::Adapter::FR>
902              
903             =item * L<Date::Holidays::GB|https://metacpan.org/pod/Date::Holidays::GB>
904              
905             =item * L<Date::Holidays::Adapter::GB|https://metacpan.org/pod/Date::Holidays::Adapter::GB>
906              
907             =item * L<Date::Holidays::KR|https://metacpan.org/pod/Date::Holidays::KR>
908              
909             =item * L<Date::Holidays::Adapter::KR|https://metacpan.org/pod/Date::Holidays::Adapter::KR>
910              
911             =item * L<Date::Holidays::KZ|https://metacpan.org/pod/Date::Holidays::KZ>
912              
913             =item * L<Date::Holidays::Adapter::KZ|https://metacpan.org/pod/Date::Holidays::Adapter::KZ>
914              
915             =item * L<Date::Holidays::NL|https://metacpan.org/pod/Date::Holidays::NL>
916              
917             =item * L<Date::Holidays::Adapter::NL|https://metacpan.org/pod/Date::Holidays::Adapter::NL>
918              
919             =item * L<Date::Holidays::NO|https://metacpan.org/pod/Date::Holidays::NO>
920              
921             =item * L<Date::Holidays::Adapter::NO|https://metacpan.org/pod/Date::Holidays::Adapter::NO>
922              
923             =item * L<Date::Holidays::NZ|https://metacpan.org/pod/Date::Holidays::NZ>
924              
925             =item * L<Date::Holidays::Adapter::NZ|https://metacpan.org/pod/Date::Holidays::Adapter::NZ>
926              
927             =item * L<Date::Holidays::PL|https://metacpan.org/pod/Date::Holidays::PL>
928              
929             =item * L<Date::Holidays::Adapter::PL|https://metacpan.org/pod/Date::Holidays::Adapter::PL>
930              
931             =item * L<Date::Holidays::PT|https://metacpan.org/pod/Date::Holidays::PT>
932              
933             =item * L<Date::Holidays::Adapter::PT|https://metacpan.org/pod/Date::Holidays::Adapter::PT>
934              
935             =item * L<Date::Holidays::RU|https://metacpan.org/pod/Date::Holidays::RU>
936              
937             =item * L<Date::Holidays::Adapter::RU|https://metacpan.org/pod/Date::Holidays::Adapter::RU>
938              
939             =item * L<Date::Holidays::SK|https://metacpan.org/pod/Date::Holidays::SK>
940              
941             =item * L<Date::Holidays::Adapter::SK|https://metacpan.org/pod/Date::Holidays::Adapter::SK>
942              
943             =item * L<Date::Holidays::UK|https://metacpan.org/pod/Date::Holidays::UK>
944              
945             =item * L<Date::Holidays::Adapter::UK|https://metacpan.org/pod/Date::Holidays::Adapter::UK>
946              
947             =item * L<Date::Holidays::USFederal|https://metacpan.org/pod/Date::Holidays::USFederal>
948              
949             =item * L<Date::Holidays::Adapter::USFederal|https://metacpan.org/pod/Date::Holidays::Adapter::USFederal>
950              
951             =item * L<Date::Japanese::Holiday|https://metacpan.org/pod/Date::Japanese::Holiday>
952              
953             =item * L<Date::Holidays::Adapter::JP|https://metacpan.org/pod/Date::Holidays::Adapter::JP>
954              
955             =item * L<Date::Holidays::UA|https://metacpan.org/pod/Date::Holidays::UA>
956              
957             =item * L<Date::Holidays::Adapter::UA|https://metacpan.org/pod/Date::Holidays::Adapter::UA>
958              
959             =item * L<Date::Holidays::Adapter|https://metacpan.org/pod/Date::Holidays::Adapter>
960              
961             =item * L<Date::Holidays::Abstract|https://metacpan.org/pod/Date::Holidays::Abstract>
962              
963             =item * L<Date::Holidays::Super|https://metacpan.org/pod/Date::Holidays::Super>
964              
965             =back
966              
967             =head1 ACKNOWLEDGEMENTS
968              
969             =over
970              
971             =item * @qorron for PR patching the US adapter, resulting in 1.33
972              
973             =item * Wesley Schwengle (WATERKIP) author of Date::Holidays::NL and Date::Holidays::AW for reaching out and letting me know of their existence
974              
975             =item * Karen Etheridge (ETHER)
976              
977             =item * Neil Bowers (NEILB)
978              
979             =item * Miquel Ruiz, PR fixing a bug with regions for ES, supporting Data::Holidays::CA_ES resulting in 1.22
980              
981             =item * Denis Boyun, PR introducing Date::Holidays::UA resulting in 1.19
982              
983             =item * Mario Minati, for telling me about the states in Date::Holidays::DE resulting in 1.17
984              
985             =item * Vladimir Varlamov, PR introducing Date::Holidays::KZ resulting in 1.07
986              
987             =item * CHORNY (Alexandr Ciornii), Github issue #10, letting me know I included local/ by accident, resulting in release 1.05
988              
989             =item * Vladimir Varlamov, PR introducing Date::Holidays::BY resulting in 1.04
990              
991             =item * Joseph M. Orost, bug report resulting in 1.03
992              
993             =item * Alexander Nalobin, patch for using of Date::Holidays::RU, 1.01
994              
995             =item * Gabor Szabo, patch assisting META data generation
996              
997             =item * Florian Merges for feedback and pointing out a bug in Date::Holidays, author of Date::Holidays::ES
998              
999             =item * COG (Jose Castro), Date::Holidays::PT author
1000              
1001             =item * RJBS (Ricardo Signes), POD formatting
1002              
1003             =item * MRAMBERG (Marcus Ramberg), Date::Holidays::NO author
1004              
1005             =item * BORUP (Christian Borup), DateTime suggestions
1006              
1007             =item * LTHEGLER (Lars Thegler), Date::Holidays::DK author
1008              
1009             =item * shild on L<use.perl.org|http://use.perl.org/comments.pl?sid=28993&cid=43889>, CPAN tester
1010              
1011             =item * CPAN testers in general, their work is invaluable
1012              
1013             =item * All of the authors/contributors of Date::Holidays::* modules
1014              
1015             =back
1016              
1017             =head1 AUTHOR
1018              
1019             Jonas B., (jonasbn) - C<< <jonasbn@cpan.org> >>
1020              
1021             =head1 LICENSE AND COPYRIGHT
1022              
1023             Date-Holidays and related modules are (C) by Jonas B., (jonasbn)
1024             2004-2022
1025              
1026             Date-Holidays and related modules are released under the Artistic License 2.0
1027              
1028             Image used on L<website|https://jonasbn.github.io/perl-date-holidays/> is under copyright by L<Tim Mossholder|https://unsplash.com/photos/C8jNJslQM3A>
1029              
1030             =cut