File Coverage

lib/Date/Holidays.pm
Criterion Covered Total %
statement 66 140 47.1
branch 10 50 20.0
condition 5 21 23.8
subroutine 17 24 70.8
pod 5 5 100.0
total 103 240 42.9


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