view release on metacpan or search on metacpan
EXAMPLES.txt view on Meta::CPAN
Example applications:
---------------------
You will find some example programs (several in Perl, one in C)
in the "examples" subdirectory of this distribution:
                        examples/age_in_days_eu.pl
                        examples/age_in_days_us.pl
                        examples/anniversaries.pl
                        examples/cal.c
                        examples/calendar.pl
                        examples/datecalc.pl
                        examples/delta.pl
                        examples/holidays.pl
                        examples/income.pl
                        examples/linearcal.pl
                        examples/nth_weekday.pl
                        examples/time.pl
                        examples/vacation.pl
                        examples/weiberfastnacht.pl
EXAMPLES.txt view on Meta::CPAN
If the system call "time()" (and hence, "localtime()") is not available
on your system, the program will also ask you to enter today's date.
Otherwise the program will automatically use the system-supplied current
date.
anniversaries.pl:
-----------------
This script demonstrates how one can use the Date::Pcalendar module to
get a list of anniversaries for the next couple of weeks.
If you run this program from the login script of your shell, you will
always get this list when you log in, and you will never ever forget
a birthday or anniversary again! (At least you won't have an excuse
anymore. :-) )
Your dear loving wife or husband will appreciate it! ;-)
Example output (on October 3rd, 2001):
EXAMPLES.txt view on Meta::CPAN
  +18 days :  Sun 21-Oct-2001  (28)  Sister Catherine
  +88 days :  Sun 30-Dec-2001  (30)  Spouse
cal.c:
------
This little program is a substitute for the UNIX "cal" command.
In contrast to the UNIX "cal" command, however, this program allows you
to choose a language which will be used for generating the calendar for
the chosen month and year.
(Also in contrast to the UNIX "cal" command, this program will NOT
generate a tiled overview of ALL the months for a given year, however.)
Moreover, you can (at your option) either enter the number of the desired
language, or any uniquely identifying abbreviation of its name (or the name
in full length).
For the month you can also (at your option) either enter the corresponding
EXAMPLES.txt view on Meta::CPAN
                    % cal Portug Mar 1998 | iso2pc [-dos]
(for older versions of MS-DOS and the PC-UNIX console) or
                    % cal Portug Mar 1998 | iso2pc -win
(for newer versions of MS-DOS and the Win32 DOS box).
calendar.pl:
------------
This CGI script demonstrates the capabilities of the new "Pcalendar::*"
modules.
See http://www.engelschall.com/u/sb/calendar/ for a "live" example of
this script and play around with it at leisure!
The script allows you to select a language, a calendar profile, a start
"Year and Month" or start "Week and Year" and displays a calendar for the
chosen month, or for 4 consecutive weeks starting with the chosen week,
for the chosen location (calendar profile) and in the chosen language.
(The language setting only affects the names of months and days of week,
though! The language of the names of the holidays and commemorative days
is determined by the calendar profiles themselves.)
Alternately, you can choose to display a whole year, either only the
true holidays (i.e., the days on which you get a day off, that is, all
official holidays which do not fall on a Saturday or Sunday), or all
the days for which the corresponding profile has names stored in it
(official holidays as well as commemorative days).
Choosing one of these two options (radio buttons) overrides the "Year
and Month" or "Week and Year" mode of operation, but nevertheless takes
its year argument from the selected entry field (and simply drops the
EXAMPLES.txt view on Meta::CPAN
Saturdays, Sundays and official holidays will be marked in red, "half"
holidays will be marked in purple. Workdays are printed in black.
Optionally, the days of week which form the "weekend" (default: Saturday
and Sunday) can be configured using the corresponding checkboxes.
All the names associated with each day (the names of official holidays
as well as purely commemorative days) are displayed to the right of
each day.
Please report any errors you find in the calendar profiles (or in this
script) back to me!
There is a "mailto:" hyperlink at the bottom of the generated page for
this purpose.
Thank you very much in advance!
datecalc.pl:
------------
EXAMPLES.txt view on Meta::CPAN
See http://www.engelschall.com/u/sb/datecalc/ for a "live" example
of this script to play around with!
delta.pl:
---------
This is a little program which contains a routine to determine the
number of business days between two dates. It is not of much practical
value, because it doesn't take legal holidays into account (use the
method "delta_weekdays()" in the module Date::Pcalendar[::Year] if you
want to do that, or see the examples "income.pl" and "vacation.pl"
below).
Moreover, it assumes that counting includes the earlier of the two
dates, but not the later one. I.e., if you determine the number of
business days between, for example, two consecutive days, like for
instance a Friday and a Saturday, the routine will return a difference
of one business day as the result. If you take a Sunday and Monday, on
the other hand, however, it will give you a difference of zero business
days.
EXAMPLES.txt view on Meta::CPAN
                    Mon Tue Wed Thu Fri Sat Sun
                                          1   2
                      3   4   5   6   7   8   9
                     10  11  12  13  14  15  16
                     17  18  19  20  21  22  23
                     24  25  26  27  28  29  30
                     31
                    Difference: 11 Business Days.
(The program prints the calendars of the respective months so that you
can verify its results.)
holidays.pl:
------------
This utility generates a list of all holidays and commemorative
days for a given year and location.
It also shows how to temporarily change the language and date
string format, produce some output, and restore the old values.
Given a year number, the name of a language and the name of one
of the predefined calendar profiles, this subroutine prints a list
of all holidays in the given year, such as in the following example:
:> perl holidays.pl 2001 de sdm-MUC
Mon 01-Jan-2001 + Neujahr
Sam 06-Jan-2001 + Dreikönigstag
Don 22-Feb-2001 - Fettdonnerstag, Weiberfastnacht
Mon 26-Feb-2001 - Rosenmontag
Die 27-Feb-2001 - Karnevalsdienstag
Mit 28-Feb-2001 - Aschermittwoch
EXAMPLES.txt view on Meta::CPAN
Holidays and weekends are marked with "+", "half" holidays are
marked with "#", and commemorative days (days which aren't legal
holidays but which have a special name) or normal weekdays are
marked with "-".
income.pl:
----------
This little program demonstrates what you can do using the Date::Pcalendar,
Date::Pcalendar::Year and Date::Pcalendar::Profiles modules, which allow you
to perform calculations which take (legal and any other you want) holidays
into account.
It expects four parameters on the command line: Your year of birth, the
number of days of (paid) vacation your employer concedes you (per year),
the number of hours per week that you work, and your brut annual income.
If called without or with a wrong number of parameters, the program prints
a usage and stops.
Otherwise, it prints a summary of your input, a list of years, followed
by the number of workdays in that year, some statistics, and your average
net wage per hour (assuming 50% taxes on income and an age of 65 for
retirement).
Note that you may have to adjust the holidays profile used in this script
before you can get any meaningful results for your location. The currently
used profile is for the federal state of Nordrhein-Westfalen in Germany.
See the manual page (and code) of the Date::Pcalendar::Profiles module
for more information.
Sample run:
:> perl income.pl 1964 30 40 100000
Year of birth      = 1964
Current year       = 2001
Year of retirement = 2029
Vacation days/year = 30
EXAMPLES.txt view on Meta::CPAN
Quotient = 0.606684290030212
Net hourly wages (assuming 50% taxes on income) = 28.2057267351385
linearcal.pl:
-------------
This program illustrates how to use the various new methods
available through the new object-oriented date and calendar modules
(Date::Pcalc::Object, Date::Pcalendar, Date::Pcalendar::Profiles).
It also shows how to temporarily change the language and date
string format, produce some output, and restore the old values.
Given two dates (start and stop date), the name of a language
and the name of one of the predefined calendar profiles, this
little subroutine prints a linear calendar, such as in the
following two examples:
:> perl linearcal.pl 1999 12 18 2000 1 9 de DE-BY
Sam 18-Dez-1999 +
Son 19-Dez-1999 + 4. Advent
Mon 20-Dez-1999 -
Die 21-Dez-1999 -
Mit 22-Dez-1999 -
Don 23-Dez-1999 -
EXAMPLES.txt view on Meta::CPAN
:> perl vacation.pl
23
weiberfastnacht.pl:
-------------------
This little script demonstrates how you can search for dates by name,
and how you can poll all the names associated with any particular date.
Moreover, it shows how the cache of Date::Pcalendar objects works, and
how it can be manipulated.
Please see the script's code for more details.
Sample run:
:> perl weiberfastnacht.pl
Donnerstag, den 2. März 2000 (Donnerstag Fettdonnerstag Weiberfastnacht)
Donnerstag, den 22. Februar 2001 (Donnerstag Fettdonnerstag Weiberfastnacht)
Donnerstag, den 7. Februar 2002 (Donnerstag Fettdonnerstag Weiberfastnacht)
INSTALL.txt view on Meta::CPAN
Prerequisites:
--------------
Perl version 5.000 or higher.
Module "Carp::Clan" version 5.3 or higher.
Optionally, module "Bit::Vector" version 7.1 or newer.
If you plan to use the modules "Date::Pcalendar" or
"Date::Pcalendar::Year" from this package, you will
also need the module "Bit::Vector" version 7.1 or
newer (which needs an ANSI C compiler, however!).
Otherwise you may safely ignore the warning message
"Warning: prerequisite Bit::Vector 7.1 not found at ..."
when running "perl Makefile.PL".
Anyway, you can always install "Bit::Vector" later
at any time if you change your mind.
Artistic.txt
CHANGES.txt
CREDITS.txt
EXAMPLES.txt
GNU_GPL.txt
GNU_LGPL.txt
INSTALL.txt
MANIFEST
Makefile.PL
Pcalc.pod
Pcalendar.pm
Pcalendar.pod
README.htm
README.txt
TOOLS.txt
examples/age_in_days_eu.pl
examples/age_in_days_us.pl
examples/anniversaries.pl
examples/bug.pl
examples/cal.c
examples/calendar.pl
examples/datecalc.pl
examples/delta.pl
examples/holidays.pl
examples/income.pl
examples/linearcal.pl
examples/nth_weekday.pl
examples/time.pl
examples/vacation.pl
examples/weiberfastnacht.pl
lib/Date/Pcalc/Object.pm
lib/Date/Pcalc/Object.pod
lib/Date/Pcalendar/Profiles.pm
lib/Date/Pcalendar/Profiles.pod
lib/Date/Pcalendar/Year.pm
lib/Date/Pcalendar/Year.pod
src/C_XS/DatePcalc.c
src/C_XS/DatePcalc.h
src/C_XS/Pcalc.pm
src/C_XS/Pcalc.xs
src/C_XS/ToolBox.h
src/C_XS/typemap
src/Perl/Pcalc.pm
t/f000.t
t/f001.t
t/f002.t
Makefile.PL view on Meta::CPAN
my %Parameters =
(
    'NAME'              => 'Date::Pcalc',
    'VERSION_FROM'      => 'Pcalc.pm',
    'PREREQ_PM'         =>
                              {
                                  'Carp::Clan'  => 5.3,
                                  'Bit::Vector' => 7.1
                              },
#   ($] >= 5.005 ?
#       ('ABSTRACT'     => 'Gregorian calendar date calculations',
#        'AUTHOR'       => 'Steffen Beyer <STBEY@cpan.org>') : ()),
#   ($] >= 5.005 && $^O eq 'MSWin32' && $Config::Config{'archname'} =~ /-object\b/i ?
#       ('CAPI'         => 'TRUE') : ()),
    'dist'              => { COMPRESS => "gzip -9", SUFFIX => "gz" },
    'clean'             => { FILES => join(' ', @Clean) }
);
sub Check_CC
{
    my($cmd) = $_[0];
=head1 NAME
Date::Pcalc - Gregorian calendar date calculations
=head1 MOTTO
Keep it small, fast and simple
=head1 PREFACE
This package consists of a library written in pure Perl providing
all sorts of date calculations based on the Gregorian calendar
(the one used in all western countries today), thereby complying
with all relevant norms and standards: S<ISO/R 2015-1971>,
S<DIN 1355> and, to some extent, S<ISO 8601> (where applicable).
(See also http://www.engelschall.com/u/sb/download/Date-Calc/DIN1355/
for a scan of part of the "S<DIN 1355>" document (in German)).
This package is meant as a drop-in replacement for L<Date::Calc(3)>,
the latter of which is written in C and XS and therefore needs a
C compiler in order to build and install (which this one doesn't).
This is not true, however, for the import/export functions in this
package which are an interface to the internal POSIX date and time
functions of your system, which can only cover dates in the following
ranges:
 01-Jan-1970 00:00:00 GMT .. 19-Jan-2038 03:14:07 GMT [Unix etc.]
 01-Jan-1904 00:00:00 LT  .. 06-Feb-2040 06:28:15 LT  [MacOS Classic]
 (LT = local time)
Note that this package projects the Gregorian calendar back until the
year S<1 A.D.> -- even though the Gregorian calendar was only adopted
in 1582, mostly by the Catholic European countries, in obedience to the
corresponding decree of Pope S<Gregory XIII> in that year.
Some (mainly protestant) countries continued to use the Julian calendar
(used until then) until as late as the beginning of the 20th century.
Finally, note that this package is not intended to do everything you could
ever imagine automagically for you; it is rather intended to serve as a
toolbox (in the best of UNIX spirit and traditions) which should, however,
always get you where you want to go.
See the section "RECIPES" at the bottom of this document for solutions
to common problems!
"Year 2000" ("Y2K") compliance
The upper limit for any year number in this module is only given
by the size of the largest positive integer that can be represented
in a scalar variable on your system, which is at least 32767,
according to the ANSI C standard, on which Perl is based
(exceptions see below).
In order to simplify calculations, this module projects the gregorian
calendar back until the year S<1 A.D.> -- i.e., back B<BEYOND> the
year 1582 when this calendar was first decreed by the Catholic Pope
S<Gregory XIII>!
Therefore, B<BE SURE TO ALWAYS SPECIFY "1998" WHEN YOU MEAN "1998">,
for instance, and B<DO NOT WRITE "98" INSTEAD>, because this will
in fact perform a calculation based on the year "98" A.D. and
B<NOT> "1998"!
An exception from this rule are the functions which contain the
word "compress" in their names (which can only handle years between
1970 and 2069 and also accept the abbreviations "00" to "99"), and
C<$doy = Day_of_Year($year,$month,$day);>
This function returns the (relative) number of the day of the given date
in the given year.
E.g., "C<Day_of_Year($year,1,1)>" returns "C<1>",
"C<Day_of_Year($year,2,1)>" returns "C<32>", and
"C<Day_of_Year($year,12,31)>" returns either "C<365>" or "C<366>".
The day of year is sometimes also referred to as the Julian day (or date),
although it has nothing to do with the Julian calendar, the calendar which
was used before the Gregorian calendar.
In order to convert the number returned by this function back into a
date, use the function "C<Add_Delta_Days()>" (described further below),
as follows:
  $doy = Day_of_Year($year,$month,$day);
  ($year,$month,$day) = Add_Delta_Days($year,1,1, $doy - 1);
=item *
where counting starts at the 1st of January of the year S<1 A.D.>
I.e., "C<Date_to_Days(1,1,1)>" returns "C<1>", "C<Date_to_Days(1,12,31)>"
returns "C<365>", "C<Date_to_Days(2,1,1)>" returns "C<366>",
"C<Date_to_Days(1998,5,1)>" returns "C<729510>", and so on.
This is sometimes also referred to (not quite correctly) as the Julian
date (or day). This may cause confusion, because also the number of the
day in a year (from 1 to 365 or 366) is frequently called the "Julian day".
More confusing still, this has nothing to do with the Julian calendar,
which was used B<BEFORE> the Gregorian calendar.
The Julian calendar was named after famous Julius Caesar, who had
instituted it in Roman times. The Julian calendar is less precise than
the Gregorian calendar because it has too many leap years compared to
the true mean length of a year (but the Gregorian calendar also still
has one day too much every 5000 years). Anyway, the Julian calendar was
better than what existed before, because rulers had often changed the
calendar used until then in arbitrary ways, in order to lengthen their
own reign, for instance.
In order to convert the number returned by this function back into
a date, use the function "C<Add_Delta_Days()>" (described further
below), as follows:
  $days = Date_to_Days($year,$month,$day);
  ($year,$month,$day) = Add_Delta_Days(1,1,1, $days - 1);
=item *
C<$dow = Day_of_Week($year,$month,$day);>
This function returns the number of the day of week of the given date.
The function returns "C<1>" for Monday, "C<2>" for Tuesday and so on
until "C<7>" for Sunday.
Note that in the Hebrew calendar (on which the Christian calendar is based),
the week starts with Sunday and ends with the Sabbath or Saturday (where
according to the Genesis (as described in the Bible) the Lord rested from
creating the world).
In medieval times, Catholic Popes have decreed the Sunday to be the official
day of rest, in order to dissociate the Christian from the Hebrew belief.
It appears that this actually happened with the Emperor Constantin, who
converted to Christianity but still worshipped the Sun god and therefore
moved the Christian sabbath to the day of the Sun.
    7  =>  '7th'    17  =>  '17th'    27  =>  '27th'
    8  =>  '8th'    18  =>  '18th'    28  =>  '28th'
    9  =>  '9th'    19  =>  '19th'    29  =>  '29th'
etc.
=item *
C<$string = Calendar($year,$month[,$orthodox[,$lang]]);>
This function returns a calendar of the given month in the given year
(somewhat similar to the UNIX "C<cal>" command), in the given or currently
selected language (see further below for details about the multi-language
support of this package).
Example:
  print Calendar(1998,5);
This will print:
           May 1998
  Mon Tue Wed Thu Fri Sat Sun
                    1   2   3
    4   5   6   7   8   9  10
   11  12  13  14  15  16  17
   18  19  20  21  22  23  24
   25  26  27  28  29  30  31
If the optional boolean parameter "C<$orthodox>" is given and true,
the calendar starts on Sunday instead of Monday.
=item *
C<$string = Month_to_Text($month[,$lang]);>
This function returns the name of the given month in the given or currently
selected language (see further below for details about the multi-language
support of this package).
If the given month lies outside of the valid range from "C<1>" to "C<12>",
      $dow = Day_of_Week($year,$month,$day);
      if ($dow > 5)
      {
          ($year,$month,$day) =
              Add_Delta_Days($year,$month,$day, 5-$dow);
      }
      else { last; }
  }
Solution #3 (holidays taken into account, more comfortable,
but requires Date::Pcalendar(3) and Date::Pcalc::Object(3)):
  use Date::Pcalc::Object qw( Today Add_Delta_YM Date_to_Text_Long );
  use Date::Pcalendar::Profiles qw($Profiles);
  use Date::Pcalendar;
  $calendar = Date::Pcalendar->new( $Profiles->{'DE-BW'} );
  @today = Today();
  @nextmonth = Add_Delta_YM(@today[0,1],1, 0,1);
  $workaround = $calendar->add_delta_workdays(@nextmonth,+1);
  $payday     = $calendar->add_delta_workdays($workaround,-2);
  print "Pay day = ", Date_to_Text_Long($payday->date()), "\n";
The "workaround" is necessary due to a bug in the method
"add_delta_workdays()" when adding a negative number of
workdays.
=item 11)
How do I convert a MS Visual Basic "DATETIME" value into its date
              $result -= ($temp << 1);
          }
      }
      if ($minus) { return -$result; }
      else        { return  $result; }
  }
This solution is probably of little practical value, however,
because it doesn't take legal holidays into account.
See L<Date::Pcalendar(3)> for how to do that.
=item 17)
How can I "normalize" the output of the "Delta_YMDHMS()" (or "Delta_YMD()")
function so that it contains only positive values?
I.e., how can I show a difference in date (and time) in a more human-readable
form, for example in order to show how much time until (or since) the expiration
of something (e.g. an account, a domain, a credit card, etc.) is left (has passed)?
Note that for normalizing just a time vector, you can use the built-in
function "Normalize_DHMS()". However, this will yield either all positive
B<OR> all negative values, B<NOT> all positive values as above.
=back
=head1 SEE ALSO
Date::Calc(3),
Date::Calc::Util(3), Date::Pcalc::Object(3),
Date::Pcalendar(3), Date::Pcalendar::Year(3),
Date::Pcalendar::Profiles(3).
  "The Calendar FAQ":
  http://www.tondering.dk/claus/calendar.html
  by Claus Tondering <claus@tondering.dk>
=head1 BEWARE
When you are using the (deprecated) function "Language()", the language
setting is stored in a global variable.
This may cause conflicts between threads or modules running concurrently.
Therefore, in order to avoid such conflicts, NEVER use the function
Pcalendar.pm view on Meta::CPAN
###############################################################################
##                                                                           ##
##    Copyright (c) 2000 - 2009 by Steffen Beyer.                            ##
##    All rights reserved.                                                   ##
##                                                                           ##
##    This package is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
package Date::Pcalendar;
BEGIN { eval { require bytes; }; }
use strict;
use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION );
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw();
$VERSION = '6.1';
use Carp::Clan qw(^Date::);
use Date::Pcalc::Object qw(:ALL);
use Date::Pcalendar::Year qw( check_year empty_period );
sub new
{
    my($class)    = shift;
    my($profile)  = shift;
    my($language) = shift || 0;
    my($self);
    $self = [ ];
    $class = ref($class) || $class || 'Date::Pcalendar';
    bless($self, $class);
    $self->[0] = { };
    $self->[1] = $profile;
    $self->[2] = $language;
    $self->[3] = [@_];
    return $self;
}
sub year
{
Pcalendar.pm view on Meta::CPAN
    my($year) = shift_year(\@_);
    &check_year($year);
    if (defined $self->[0]{$year})
    {
        return $self->[0]{$year};
    }
    else
    {
        return $self->[0]{$year} =
            Date::Pcalendar::Year->new( $year, $self->[1], $self->[2], @{$self->[3]} );
    }
}
sub cache_keys
{
    my($self) = shift;
    return( sort {$a<=>$b} keys(%{$self->[0]}) );
}
Pcalendar.pod view on Meta::CPAN
=head1 NAME
Date::Pcalendar - Calendar objects for different holiday schemes
=head1 MOTTO
There is more than one way to do it - this is just one of them!
=head1 PREFACE
Basically, Date::Pcalendar is just a caching proxy class for
Date::Pcalendar::Year objects, which are embedded in each
Date::Pcalendar object.
However, and in contrast to Date::Pcalendar::Year methods, Date::Pcalendar
methods permit calculations spanning an arbitrary number of years, without
loss of efficiency.
So you should usually use Date::Pcalendar and not Date::Pcalendar::Year,
since that way you don't have to worry about calculations crossing year
boundaries.
Note however that Date::Pcalendar and Date::Pcalendar::Year can only deal
with years lying within the range [1583..2299].
=head1 SYNOPSIS
  use Date::Pcalendar::Profiles qw( $Profiles );
  use Date::Pcalendar;
  $calendar_US_AZ  = Date::Pcalendar->new( $Profiles->{'US-AZ'} [,LANG[,WEEKEND]] );
  $calendar_DE_SN  = Date::Pcalendar->new( $Profiles->{'DE-SN'} [,LANG[,WEEKEND]] );
  $year_2000_US_AZ = $calendar_US_AZ->year( 2000 );
  $year_2001_DE_SN = $calendar_DE_SN->year( 2001 );
  @years = $calendar->cache_keys(); # returns list of year numbers
  @years = $calendar->cache_vals(); # returns list of year objects
  $calendar->cache_clr();
  $calendar->cache_add(YEAR|DATE,...);
  $calendar->cache_del(YEAR|DATE,...);
  $index        = $calendar->date2index(YEAR,MONTH,DAY|DATE);
  @names        = $calendar->labels(YEAR,MONTH,DAY|DATE);
  @holidays     = $calendar->labels();
  $holidays     = $calendar->labels();
  @dates        = $calendar->search(PATTERN);
  $dates        = $calendar->search(PATTERN);
  $hashref      = $calendar->tags(YEAR,MONTH,DAY|DATE);
  $days         = $calendar->delta_workdays(YEAR1,MONTH1,DAY1|DATE1
                                           ,YEAR2,MONTH2,DAY2|DATE2
                                           ,FLAG1,FLAG2);
  ($date,$rest) = $calendar->add_delta_workdays(YEAR,MONTH,DAY|DATE
                                               ,DELTA);
  $date         = $calendar->add_delta_workdays(YEAR,MONTH,DAY|DATE
                                               ,DELTA);
  $flag         = $calendar->is_full(YEAR,MONTH,DAY|DATE);
  $flag         = $calendar->is_half(YEAR,MONTH,DAY|DATE);
  $flag         = $calendar->is_work(YEAR,MONTH,DAY|DATE);
=head1 INTERFACE
Note that whenever a year number, a date, a time or a combined
date and time are expected as input parameters by one of the
methods of this class, you can always pass a Date::Pcalc[::Object]
date object or an array reference (of an array of appropriate
length) instead!
See L<Date::Pcalc::Object(3)> for more details.
Pcalendar.pod view on Meta::CPAN
And similarly if a time or a combined date and time are expected.
If you substitute an expected year number by an anonymous array
(this is the recommended way of writing date constants, for
increased readability of your programs), it must contain three
values, nevertheless (otherwise the use of an anonymous array
would be pointless).
Don't confuse year numbers and their substitutes (a date object
or an array reference) with Date::Pcalendar::Year objects, which
are a totally different thing!
But incidentally C<:-)>, you may also pass a Date::Pcalendar::Year
object whenever a year number is expected. However, and perhaps
against your expectations at times, especially in conjunction
with the method "cache_add()", only the year number from that
object will be used, not the year object itself (the year
object in question might be using the wrong profile!).
Moreover, whenever a method of this class returns a date, it
does so by returning a Date::Pcalc[::Object] date object.
=head1 DESCRIPTION
=over 2
=item *
C<$calendar = Date::Pcalendar-E<gt>new(PROFILE[,LANG[,WEEKEND]]);>
The first argument must be the reference of a hash,
which contains a holiday scheme or "profile" to be used
in all calculations involving the new calendar object.
The second argument is optional, and must consist of
the valid name or number of a language as provided by
the Date::Pcalc(3) module if given.
After the second argument, a list of day numbers which
will constitute the "weekend" can optionally be specified,
where 1=Monday, 2=Tuesday, 3=Wednesday, 4=Thursday,
5=Friday, 6=Saturday and 7=Sunday.
If no values are given, 6 and 7 (Saturday and Sunday)
are automatically taken as default.
If values outside of the range C<1..7> are given,
they will be ignored.
This can be used to switch off this feature and to
have no regularly recurring holidays at all when
for instance a zero is given.
See L<Date::Pcalendar::Profiles(3)> and L<Date::Pcalendar::Year(3)>
for more details about these arguments and about how
to roll your own calendar profiles.
The method creates a new calendar object for a given profile,
i.e., a given location and its scheme of holidays (or a scheme
of your own).
This calendar object is a caching proxy object; it stores the
reference of the given profile and contains a hash (the cache)
of Date::Pcalendar::Year objects.
=item *
C<$year = $calendar-E<gt>year(YEAR|DATE);>
This method returns a Date::Pcalendar::Year object for the given
year and the profile that was associated with the given calendar
object.
If the cache in the given calendar object already contains an
object for the requested year, the corresponding object reference
is simply returned.
If not, a new Date::Pcalendar::Year object is created using the
profile that has been associated with the given calendar object.
The new Date::Pcalendar::Year object is then stored in the calendar
object's cache and its object reference is returned.
A fatal "given year out of range" error will occur if the given
year number lies outside the valid range of [1583..2299].
=item *
C<@years = $calendar-E<gt>cache_keys();>
This method returns the list of B<YEAR NUMBERS> of the
Date::Pcalendar::Year objects contained in the given
calendar object's cache.
=item *
C<@years = $calendar-E<gt>cache_vals();>
This method returns the list of B<OBJECT REFERENCES> of
the Date::Pcalendar::Year objects contained in the given
calendar object's cache.
=item *
C<$calendar-E<gt>cache_clr();>
This method clears the entire cache of the given calendar
object (by destroying the cache hash and creating a new one).
=item *
C<$calendar-E<gt>cache_add(YEAR|DATE,...);>
Roughly, this method is a shortcut for
  for $year (@list)
  {
      $calendar->year($year);
  }
=item *
C<$calendar-E<gt>cache_del(YEAR|DATE,...);>
This method removes the Date::Pcalendar::Year objects whose
year numbers are given from the cache of the given calendar
object.
Year numbers for which the calendar object's cache doesn't
contain an entry are simply ignored.
=item *
C<$index = $calendar-E<gt>date2index(YEAR,MONTH,DAY|DATE);>
This method converts a given date into the number of the day in
that year (this is sometimes also referred to as the "julian"
date), i.e., a number between 0 (for January 1st) and the number
of days in the given year minus one, i.e., 364 or 365 (for
December 31st).
You may need this in order to access the bit vectors returned
by the Date::Pcalendar::Year methods "vec_full()", "vec_half()"
and "vec_work()".
If the Date::Pcalendar::Year object for the given YEAR is not in
the C<$calendar>'s cache yet, it will be created and added.
An exception ("invalid date") is thrown if the given arguments
do not constitute a valid date, or ("given year out of range
[1583..2299]") if the given year lies outside of the permitted
range.
=item *
C<@names = $calendar-E<gt>labels(YEAR,MONTH,DAY|DATE);>
C<@holidays = $calendar-E<gt>labels();>
C<$holidays = $calendar-E<gt>labels();>
If any arguments are given, they are supposed to represent a
date. In that case, a list of all labels (= names of holidays)
associated with that date are returned. The first item returned
is always the name of the day of week for that date. The
corresponding year object for the given date's year is
added to the calendar's cache first if necessary.
If no arguments are given, the list of all available labels in
all years that have previously been accessed in the given calendar
(i.e., the years which are already in the given calendar's cache)
is constructed. Note that this means that the returned list will
be empty if there are no year objects in the given calendar's
cache yet (!). The returned list does B<NOT> include any names
of the days of week (which would be pointless in this case).
Multiple labels are reported only once.
Usually all years have the same set of labels, so it may seem
superfluous to scan all the years in the cache instead of just
one. But there may be exceptions, because it is possible to
define calendar profiles which do not contain all possible
holidays in every year. See L<Date::Pcalendar::Profiles(3)>
and L<Date::Pcalendar::Year(3)> for more details.
In list context, the resulting list itself is returned. In scalar
context, the number of items in the resulting list is returned.
=item *
C<@dates = $calendar-E<gt>search(PATTERN);>
C<$dates = $calendar-E<gt>search(PATTERN);>
This method searches through all the labels in all years that
have previously been accessed in the given calendar (i.e., the
years which are already in the given calendar's cache) and
returns a list of date objects with all dates whose labels
match the given pattern.
(Use the methods "cache_clr()", "cache_add()" and "cache_del()"
in order to put the year numbers you want into the calendar
object's cache, or to make sure it only contains the year
numbers you want to search.)
Note that this is a simple, case-insensitive substring search,
B<NOT> a full-fledged regular expression search!
The result is guaranteed to be sorted chronologically.
In scalar context, only the number of items in the resulting list
is returned, instead of the resulting list itself (as in list context).
=item *
C<$hashref = $calendar-E<gt>tags(YEAR,MONTH,DAY|DATE);>
This method returns a hash reference for the given calendar and
date. The hash it refers to is a copy of the calendar profile's
internal hash which contains the names for the given date as keys
and 0, 1, 2, or 3 as their corresponding values meaning the following:
    0    =>    commemorative day
    1    =>    "half" holiday
    2    =>    "full" holiday
    3    =>    both a "half" and a "full" holiday
The value "3" should only occur if a date has been redefined by the
underlying profile using the same key (i.e., the same name) but with
a different type of holiday.
=item *
C<$days = $calendar-E<gt>delta_workdays(YEAR1,MONTH1,DAY1, YEAR2,MONTH2,DAY2, FLAG1,FLAG2);>
C<$days = $calendar-E<gt>delta_workdays(DATE1,DATE2,FLAG1,FLAG2);>
This method calculates the number of work days (i.e., the number
of days, but excluding all holidays) between two dates.
In other words, this method is equivalent to the "Delta_Days()"
function of the Date::Pcalc module, except that it disregards
holidays in its counting.
The two flags indicate whether the start and end dates should be
included in the counting (that is, of course, only in case they
Pcalendar.pod view on Meta::CPAN
The parameter FLAG1 is associated with the first given date,
the parameter FLAG2 with the second given date (regardless
of whether the dates are in chronological order or not).
An exception ("invalid date") is raised if either of the two
date arguments does not constitute a valid date.
=item *
C<($date,$rest) = $calendar-E<gt>add_delta_workdays(YEAR,MONTH,DAY, DELTA);>
C<($date,$rest) = $calendar-E<gt>add_delta_workdays(DATE,DELTA);>
C<$date = $calendar-E<gt>add_delta_workdays(YEAR,MONTH,DAY, DELTA);>
C<$date = $calendar-E<gt>add_delta_workdays(DATE,DELTA);>
This method is the equivalent of the "Add_Delta_Days()" function
from the Date::Pcalc module, except that it adds work days and
skips holidays.
In other words, you can add or subtract a number of work days
"DELTA" to/from a given date and get a new date as the result
(as a Date::Pcalc object).
You add days (i.e., you go forward in time) with a positive
Pcalendar.pod view on Meta::CPAN
as "the resulting date at 12:00 o'clock", instead of as "the
resulting date at 0:00 o'clock".
The rest is always positive (or zero) if the offset "DELTA"
is positive (or zero), and always negative (or zero) if the
offset is negative (or zero).
Example:
  #!perl
  use Date::Pcalendar;
  use Date::Pcalendar::Profiles qw( $Profiles );
  $year = shift;
  $cal = Date::Pcalendar->new( $Profiles->{'sdm-MUC'} );
  ($date,$rest) = $cal->add_delta_workdays($year,1,3, -3);
  $date->date_format(1);
  print "\$date = $date, \$rest = $rest.\n";
  __END__
This program calculates "January 3rd of the given year minus
3 work days":
  > perl test.pl 2001
  $date = 28-Dec-2000, $rest = 0.
  > perl test.pl 2002
  $date = 28-Dec-2001, $rest = -0.5.
Note that December 31st is a "half" holiday in 2001 for the
calendar profile used in this example.
You can easily verify the results above with the help of the
"calendar.cgi" CGI script or the "linearcal.pl" script from
the "examples" subdirectory in the Date::Pcalc distribution.
B<BEWARE> that this method may currently return unexpected
(i.e., contradicting the above documentation) or plain wrong
results when going back in time (this is a bug!).
However, it works correctly and as documented above when
going forward in time.
=item *
C<$flag = $calendar-E<gt>is_full(YEAR,MONTH,DAY|DATE);>
This method returns "true" ("1") if the bit corresponding to
the given date is set in the bit vector representing "full"
holidays, and "false" ("0") otherwise.
I.e., the method returns "true" if the given date is a (full)
holiday (according to the calendar profile associated with the
given calendar object).
The corresponding Date::Pcalendar::Year object is created first
and stored in the calendar object's cache if necessary (if it's
not already there).
Note that you can get a reference to this bit vector (in order
to use this bit vector in bit vector operations) as follows:
  $vec_full = $calendar->year($year)->vec_full();
The number of bits in this bit vector is the same as the number
of days in the given year "C<$year>", which you can retrieve
through either "C<$days = $vec_full-E<gt>Size();>" or
"C<$days = $year-E<gt>val_days();>".
See L<Date::Pcalendar::Year(3)> and L<Bit::Vector(3)> for more
details.
=item *
C<$flag = $calendar-E<gt>is_half(YEAR,MONTH,DAY|DATE);>
This method returns "true" ("1") if the bit corresponding to
the given date is set in the bit vector representing "half"
holidays, and "false" ("0") otherwise.
I.e., the method returns "true" if the given date is a half
holiday (according to the calendar profile associated with the
given calendar object).
Note that if a date is a "full" holiday, the "half" bit is
never set, even if you try to do so in your calendar profile,
on purpose or by accident.
The corresponding Date::Pcalendar::Year object is created first
and stored in the calendar object's cache if necessary (if it's
not already there).
Note that you can get a reference to this bit vector (in order
to use this bit vector in bit vector operations) as follows:
  $vec_half = $calendar->year($year)->vec_half();
The number of bits in this bit vector is the same as the number
of days in the given year "C<$year>", which you can retrieve
through either "C<$days = $vec_half-E<gt>Size();>" or
"C<$days = $year-E<gt>val_days();>".
See L<Date::Pcalendar::Year(3)> and L<Bit::Vector(3)> for more
details.
=item *
C<$flag = $calendar-E<gt>is_work(YEAR,MONTH,DAY|DATE);>
This method returns "true" ("1") if the bit corresponding to
the given date is set in the bit vector used to perform all
sorts of calculations, and "false" ("0") otherwise.
The corresponding Date::Pcalendar::Year object is created first
and stored in the calendar object's cache if necessary (if it's
not already there).
B<BEWARE> that the "work" in this method's name does B<NOT>
come from "work days"!
It comes from the fact that the corresponding bit vector can
be used for any "work" that you need to do. In other words,
it's a "work space".
Therefore, this bit vector might contain about everything you
could imagine - including a bit pattern which marks all "work
days" with set bits, if it so happens!
But you better don't rely on it, unless you put the bit pattern
there yourself in the first place.
Note that you can get a reference to this bit vector (in order
to fill it with any bit pattern you like) as follows:
  $vec_work = $calendar->year($year)->vec_work();
The number of bits in this bit vector is the same as the number
of days in the given year "C<$year>", which you can retrieve
through either "C<$days = $vec_work-E<gt>Size();>" or
"C<$days = $year-E<gt>val_days();>".
See L<Date::Pcalendar::Year(3)> and L<Bit::Vector(3)> for more
details.
=back
=head1 SEE ALSO
Date::Pcalendar::Year(3), Date::Pcalendar::Profiles(3),
Date::Pcalc::Object(3), Date::Pcalc(3), Date::Calc::Util(3),
Bit::Vector(3).
=head1 LIMITATIONS
The calendar profiles included in L<Date::Pcalendar::Profiles(3)>
usually do not take historical irregularities into account
(even though some do in order to show how this can be done),
they only provide means for calculating B<regularly> recurring
events (B<the profiles should therefore not be relied upon
for historical faithfulness>).
=head1 KNOWN BUGS
The method "add_delta_workdays()" is known to produce results
which are sometimes off by one working day when a negative
offset is used. As a workaround, try to add one working day
first and then subtract one working day more than initially
intended. See also the file "examples/bug.pl" for how to do
this.
=head1 VERSION
This man page documents "Date::Pcalendar" version 6.1.
=head1 AUTHOR
  Steffen Beyer
  mailto:STBEY@cpan.org
  http://www.engelschall.com/u/sb/download/
=head1 COPYRIGHT
Copyright (c) 2000 - 2009 by Steffen Beyer. All rights reserved.
    <LI>Calculating the nth day-of-week of a month and year (e.g. the first Tuesday of July 2004 = 06-Jul-2004)
    <LI>Calculating differences between dates (and/or times)
    <LI>Calculating Easter Sunday and holidays depending on it
    <LI>...
</UL>
based on
<UL>
    <LI>the Gregorian calendar (decreed in 1582 by pope Gregor I)
    <LI><A HREF="http://www.engelschall.com/u/sb/download/Date-Calc/DIN1355/">DIN 1355</A>
    <LI><A HREF="http://www.iso.ch/iso/en/prods-services/popstds/datesandtime.html">ISO 8601</A> (to some extent, where applicable)
    <BR>(See also <A HREF="http://www.w3.org/TR/NOTE-datetime">W3C</A>, <A HREF="http://www.mcs.vuw.ac.nz/technical/software/SGML/doc/iso8601/ISO8601.html">Victoria University of Wellington</A> or <A HREF="http://en.wikipedia.org/wiki/ISO_8601">Wikip...
</UL>
<H3>Philosophy</H3>
<UL>
    <LI>Toolbox, not a (heavy) ready-made application
    <LI>A module <B><U>primarily</U></B> for performing <B><U>calculations</U></B> with dates (nomen est omen)
    <LI>A module intended to be <B><U>small</B></U> (low memory footprint) and <B><U>fast</B></U> (for heavy-duty applications)
</UL>
<P>
<H3>Features</H3>
<UL>
    <LI>Extrapolates the Gregorian calendar back beyond 1582 until 1 A.D.
    <BR>(historically <B><U>not</B></U> meaningful, but may nevertheless be useful)
    <LI>Numerical range extends as far as "int" data type permits, i.e., at least until the year 32767
    <LI>Basic date parsing (input) and formatting (output)
    <LI>Support for various languages (input and output)
    <BR>(Currently 14 as of version 6.1; English, French, German, Spanish, Portuguese, Dutch, Italian, Norwegian, Swedish, Danish, Finnish, Hungarian, Polish and Romanian)
    <LI>Calculations on dates, with and without time (including timezone offsets)
    <LI>Interface to localtime(), gmtime(), mktime() plus own conversion routines (with more predictable results)
    <LI><B>Internally written in C for smaller memory usage, faster execution and possibility to use in C applications</B>
    <LI>The <A HREF="http://search.cpan.org/search?module=Date::Pcalc">documentation</A> of "Date::Pcalc" gives model solutions to common problems in its "<A HREF="http://search.cpan.org/~stbey/Date-Pcalc-6.1/Pcalc.pod#RECIPES">RECIPES...
    <LI>Optionally provides date objects (i.e., an OO interface) for greater ease of use (Perl only) (<A HREF="http://search.cpan.org/search?module=Date::Pcalc::Object">Date::Pcalc::Object</A>)
    <LI>Comprises a module for date calculations taking legal holidays into account (Perl only) (<A HREF="http://search.cpan.org/search?module=Date::Pcalendar">Date::Pcalendar</A>)
    <LI>Provides a rich set of holiday profiles for numerous countries (Perl only) (<A HREF="http://search.cpan.org/search?module=Date::Pcalendar::Profiles">Date::Pcalendar::Profiles</A>)
</UL>
<H3>Limitations</H3>
<UL>
    <LI>The language setting in "Date::Pcalc" is a global variable (= BEWARE when using threads!)
    <LI>The modules "Date::Pcalendar" and "Date::Pcalendar::Year" only operate on years between 1583 and 2299
    <LI>Uses the ISO-Latin-1 character set, even for languages (such as Polish) not entirely representable in that character set (uses the "plain" characters instead in such cases)
    <LI><FONT COLOR="#FF0000"><B>The calendar profiles included in this module usually do not take historical irregularities into account</B></FONT> (even though some do in order to show how this can be done),<BR>
        <FONT COLOR="#FF0000"><B>they only provide means for calculating <U>regularly</U> recurring events (<U>the profiles should therefore not be relied upon for historical faithfulness</U>)</B></FONT>
</UL>
<P>
<H3>See also</H3>
<UL>
    <LI>The <A HREF="http://www.engelschall.com/u/sb/calendar/">International Eternal Gregorian Calendar</A> showing a calendar with holidays in selectable languages and countries
    <LI>The <A HREF="http://www.engelschall.com/u/sb/demo/">Sports Club Events Calendar</A> showing how this module can be used to manage people attending events in a calendar
    <LI>The <A HREF="http://www.engelschall.com/u/sb/datecalc/">Simple Date Calculator</A> for determining the difference between two dates / a new date based on a date plus a difference
    <LI>"<A HREF="http://www.tondering.dk/claus/calendar.html">The Calendar FAQ</A>" by <A HREF="mailto:claus@tondering.dk">Claus Tøndering</A>
</UL>
<P>
<HR NOSHADE SIZE="2">
<P>
<CENTER>
If you are looking for information on <A HREF="CHANGES.txt">what is new</A> in this version, prerequisites and <A HREF="INSTALL.txt">installation instructions</A>, you will find it either in the <A HREF="README.txt">README</A> file included in this d...
</CENTER>
or from any CPAN (= "Comprehensive Perl Archive Network") mirror server:
               http://www.perl.com/CPAN/authors/id/S/ST/STBEY/
Abstract:
---------
This package consists of a library written in pure Perl providing all sorts
of date calculations based on the Gregorian calendar (the one used in all
western countries today), thereby complying with all relevant norms and
standards: ISO/R 2015-1971, DIN 1355 and, to some extent, ISO 8601
(where applicable).
The package is designed as an efficient toolbox, not a bulky ready-made
application. It provides extensive documentation and examples of use,
multi-language support and special functions for business needs.
This package also features date objects (in addition to the functional
interface) with overloaded operators, and a set of modules for calculations
which take local holidays into account.
This package is meant as a drop-in replacement for "Date::Calc",
the latter of which is written in C and XS and therefore needs a
C compiler in order to build and install (which this one doesn't).
You will have to rename all references to "Date::Calc[::Object]"
and "Date::Calendar[::Year|::Profiles]" to "Date::Pcalc[::Object]"
and "Date::Pcalendar[::Year|::Profiles]", respectively, though.
Note that the modules "Date::Pcalendar[::Year|::Profiles]" depend
on "Bit::Vector", so if you wish to use these, you will need a C
compiler anyway, since "Bit::Vector" is also written in C and XS.
They are included here anyway for the sake of completeness, for
allowing to test the transcription of this module from C more
intensively (with the original and unmodified test suite from
"Date::Calc") and to facilitate the "upgrade" with "Bit::Vector",
not requiring you to install "Date::Calc" first.
Prerequisites:
--------------
Perl version 5.000 or higher.
Module "Carp::Clan" version 5.3 or higher.
Optionally, module "Bit::Vector" version 7.1 or newer.
If you plan to use the modules "Date::Pcalendar" or
"Date::Pcalendar::Year" from this package, you will
also need the module "Bit::Vector" version 7.1 or
newer (which needs an ANSI C compiler, however!).
Otherwise you may safely ignore the warning message
"Warning: prerequisite Bit::Vector 7.1 not found at ..."
when running "perl Makefile.PL".
Anyway, you can always install "Bit::Vector" later
at any time if you change your mind.
converted into man pages, which will automatically be installed in
your Perl tree for further reference through the installation process,
where they can be accessed by the commands "man Date::Pcalc" (Unix)
and "perldoc Date::Pcalc" (Unix and Win32 alike), for example.
Available man pages:
    Carp::Clan(3)
    Date::Pcalc(3)
    Date::Pcalc::Object(3)
    Date::Pcalendar(3)
    Date::Pcalendar::Profiles(3)
    Date::Pcalendar::Year(3)
If Perl is not available on your system, you can also read the ".pod"
files
    ./Pcalc.pod
    ./Pcalendar.pod
    ./lib/Carp/Clan.pod
    ./lib/Date/Pcalc/Object.pod
    ./lib/Date/Pcalendar/Profiles.pod
    ./lib/Date/Pcalendar/Year.pod
directly.
What does it do:
----------------
This package performs date calculations based on the Gregorian calendar
(the one used in all western countries today), thereby complying with
all relevant norms and standards: ISO/R 2015-1971, DIN 1355 and, to
some extent, ISO 8601 (where applicable).
See also http://www.engelschall.com/u/sb/download/Date-Calc/DIN1355/
for a scan of part of the "DIN 1355" document (in German).
The module of course handles year numbers of 2000 and above correctly
("Year 2000" or "Y2K" compliance) -- actually all year numbers from 1
to the largest positive integer representable on your system (which
is at least 32767) can be dealt with.
Note that this package projects the Gregorian calendar back until the
year 1 A.D. -- even though the Gregorian calendar was only adopted
in 1582, mostly by the Catholic European countries, in obedience to
the corresponding decree of Pope Gregory XIII in that year.
Some (mainly protestant) countries continued to use the Julian calendar
(used until then) until as late as the beginning of the 20th century.
Therefore, do *NEVER* write something like "99" when you really mean
"1999" - or you may get wrong results!
Finally, note that this package is not intended to do everything you could
ever imagine automagically :-) for you; it is rather intended to serve as a
toolbox (in the best of UNIX spirit and tradition) which should, however,
always get you where you need and want to go.
If nevertheless you can't figure out how to solve a particular problem,
please let me know! (See e-mail address at the bottom of this file.)
The new module "Date::Pcalc::Object" adds date objects to the (functional)
"Date::Pcalc" module (just "use Date::Pcalc::Object qw(...);" INSTEAD of
"use Date::Pcalc qw(...);"), plus built-in operators like +,+=,++,-,-=,--,
<=>,<,<=,>,>=,==,!=,cmp,lt,le,gt,ge,eq,ne,abs(),"" and true/false
testing, as well as a number of other useful methods.
The new modules "Date::Pcalendar::Year" and "Date::Pcalendar" allow you
to create calendar objects (for a single year or arbitrary (dynamic)
ranges of years, respectively) for different countries/states/locations/
companies/individuals which know about all local holidays, and which allow
you to perform calculations based on work days (rather than just days),
like calculating the difference between two dates in terms of work days,
or adding/subtracting a number of work days to/from a date to yield a
new date. The dates in the calendar are also tagged with their names,
so that you can find out the name of a given day, or search for the
date of a given holiday.
Example applications:
---------------------
Please refer to the file "EXAMPLES.txt" in this distribution for details
about the example applications in the "examples" subdirectory.
examples/anniversaries.pl view on Meta::CPAN
##    This program is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
BEGIN { eval { require bytes; }; }
use strict;
no strict "vars";
use Date::Pcalc qw(:all);
use Date::Pcalendar;
# How many days in advance:
$Days = 90; # = roughly 3 months
$Anniversaries =
{
    "Spouse 1971"             =>  "30.12.",
    "Wedding Day 1992"        =>  "01.09.",
    "Valentine's Day"         =>  "14.02.",
examples/anniversaries.pl view on Meta::CPAN
    "Mom 1939"                =>  "19.08.",
    "Dad 1937"                =>  "23.04.",
    "Brother Timothy 1969"    =>  "24.04.",
    "Sister Catherine 1973"   =>  "21.10.",
    "Cousin Paul 1970"        =>  "16.10.",
    "Aunt Marjorie 1944"      =>  "09.06.",
    "Uncle George 1941"       =>  "02.08.",
    "Friend Alexander 1968"   =>  "12.06.",
};
$calendar = Date::Pcalendar->new( $Anniversaries );
@date = Today();
for ( $delta = 0; $delta <= $Days; $delta++ )
{
    if ($calendar->is_full(@date) and
        ((@labels = $calendar->labels(@date)) > 1))
    {
        $dow = shift(@labels);
        foreach $name (sort @labels)
        {
            $age = '';
            if ($name =~ s!\s*(\d+)\s*$!!)
            {
                $age = $date[0] - $1;
            }
            printf
examples/bug.pl view on Meta::CPAN
#!perl
BEGIN { eval { require bytes; }; }
use strict;
no strict "vars";
use Date::Pcalendar;
use Date::Pcalc::Object;
Date::Pcalc->date_format(2);
$cal = Date::Pcalendar->new( {} );
$date = $cal->add_delta_workdays(2002,11,11,-1);
print "\$date = $date\n";
$date = $cal->add_delta_workdays(2002,11,10,-1);
print "\$date = $date\n";
$date = $cal->add_delta_workdays(2002,11,9,-1);
examples/calendar.pl view on Meta::CPAN
##    Copyright (c) 2001 - 2009 by Steffen Beyer.                            ##
##    All rights reserved.                                                   ##
##                                                                           ##
##    This program is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
           #########################################################
           ##                                                     ##
           ##    See http://www.engelschall.com/~sb/calendar/     ##
           ##    for a "live" example of this CGI script.         ##
           ##                                                     ##
           #########################################################
BEGIN { eval { require bytes; }; }
use strict;
use Date::Pcalc qw(:all);
use Date::Pcalendar::Profiles qw($Profiles);
use Date::Pcalendar;
my $filler   = '<P> </P>';
my $RED      = '<FONT COLOR="#FF0000">';
my $PINK     = '<FONT COLOR="#CC00CC">';
my $END      = '</FONT>';
my $language = 6;
my $country  = 'NL';
my $select   = 0;
examples/calendar.pl view on Meta::CPAN
        'MUC' => 'München',
        'RAT' => 'Ratingen (Düsseldorf)',
        'STG' => 'Stuttgart',
        'ZRH' => 'Zürich (Schweiz)'
    );
    %profiles = map { $_, $_ } keys(%{$Profiles});
}
sub process_profiles()
{
    my $profile = $INC{'Date/Pcalendar/Profiles.pm'};
    my($read,$cache,$line,$key);
    $read = 1;
    if (defined($profile) and $profile ne '' and -f $profile and -r $profile and -s $profile)
    {
        $cache = $0;
        $cache =~ s!\.+[^/\\\.]*$!!;
        $cache .= ".cache";
        if (!(-f $cache and -s $cache) or ((stat($cache))[9] < (stat($profile))[9]))
        {
examples/calendar.pl view on Meta::CPAN
</TR></TABLE>
</FORM>
<P>
<HR NOSHADE SIZE="2">
<P>
<TABLE CELLSPACING="1" CELLPADDING="7" BORDER="2">
VERBATIM
    &print_calendar();
    print <<"VERBATIM";
</TABLE>
<P>
<HR NOSHADE SIZE="2">
<P>
<TABLE CELLSPACING="0" CELLPADDING="8" BORDER="0"><TR>
examples/calendar.pl view on Meta::CPAN
</FORM>
</TD>
</TR></TABLE>
<P>
<HR NOSHADE SIZE="2">
<P>
${RED}Please
<A HREF="mailto:STBEY\@cpan.org?subject=Error%20in%20calendar%20web%20page">report</A>
any errors you find on this page!${END}
<P>
<HR NOSHADE SIZE="2">
<P>
<A HREF="http://www.engelschall.com/u/sb/download/pkg/Date-Pcalc-6.1.tar.gz">Download</A>
the Perl software that does all <A HREF="calendar.pl">this</A>!
<P>
<HR NOSHADE SIZE="2">
<P>
</CENTER>
</BODY>
</HTML>
VERBATIM
}
sub print_calendar()
{
    my $year  = 0;
    my $index = 0;
    my $oyear = 0;
    my $oweek = 0;
    my $omonth = 0;
    my($calendar,$full,$half,$C,$N,$cell,$week,$dow);
    my(@date,$tags);
    local $_;
    $calendar = Date::Pcalendar->new( $Profiles->{$country}, 0, keys(%weekend) );
    print <<"VERBATIM";
<TR>
<TD COLSPAN="6" ALIGN="center"><B>$profiles{$country}</B></TD>
</TR>
<TR>
<TD ALIGN="right"><B>Year</B></TD>
<TD ALIGN="right"><B>Week<BR>Number</B></TD>
<TD ALIGN="left" ><B>Day of<BR>Week</B></TD>
<TD ALIGN="left" ><B>Month</B></TD>
examples/calendar.pl view on Meta::CPAN
VERBATIM
    @date = @{$start[0]};
    while ($start[2] > 0 and $date[0] <= 2299)
    {
        if ($date[0] >= 1583)
        {
            if ($year != $date[0])
            {
                $year  = $date[0];
                $index = $calendar->date2index(@date);
                $full  = $calendar->year($year)->vec_full();
                $half  = $calendar->year($year)->vec_half();
            }
            if ( ($dispyear == 0) or
                (($dispyear == 2) and (keys(%{$tags = $calendar->year($year)->tags($index)}))) or
                (($dispyear == 1) and ($full->bit_test($index) or $half->bit_test($index)) and not exists($weekend{Day_of_Week(@date)})))
            {
                print "<TR>\n";
                if    ($full->bit_test($index)) { $C =  $RED; $N = $END; }
                elsif ($half->bit_test($index)) { $C = $PINK; $N = $END; }
                else                            { $C =    ''; $N =   ''; }
                if ($oyear != $date[0])
                {
                    $oyear = $date[0];
                    $cell  = "<B>$oyear</B>";
examples/calendar.pl view on Meta::CPAN
                else { $cell = $filler; }
                print qq(<TD ALIGN="right">$cell</TD>\n);         # Year
                $week = Week_of_Year(@date);
                if ($oweek != $week)
                {
                    $oweek = $week;
                    $cell = "<B>$week</B>";
                }
                else { $cell = $filler; }
                print qq(<TD ALIGN="right">$cell</TD>\n);         # Week Number
                $tags = $calendar->year($year)->tags($index) unless ($dispyear == 2);
                $dow = html(Day_of_Week_to_Text(Day_of_Week(@date)));
                print qq(<TD ALIGN="left" >$C$dow$N</TD>\n);      # Day of Week
                if ($omonth != $date[1])
                {
                    $omonth = $date[1];
                    $cell = "<B>" . html(Month_to_Text($omonth)) . "</B>";
                }
                else { $cell = $filler; }
                print qq(<TD ALIGN="left" >$cell</TD>\n);         # Month
                print qq(<TD ALIGN="right">$C$date[2]$N</TD>\n);  # Day
examples/holidays.pl view on Meta::CPAN
##    All rights reserved.                                                   ##
##                                                                           ##
##    This program is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
BEGIN { eval { require bytes; }; }
use strict;
use Date::Pcalendar::Profiles qw( $Profiles );
use Date::Pcalendar::Year;
use Date::Pcalc::Object qw(:ALL);
sub print_holidays
{
    my($year) = shift_year(\@_);
    my($lang) = shift;
    my($prof) = shift;
    my($newl) = Decode_Language($lang);
    my($full,$half,$last,$oldl,$oldf,$i,$date,@labels,$dow,$day);
    die "No such language '$lang'" unless ($newl);
    die "No such calendar profile '$prof'"
        unless (exists $Profiles->{$prof});
    $year = Date::Pcalendar::Year->new( $year, $Profiles->{$prof} );
    $full = $year->vec_full();
    $half = $year->vec_half();
    $last = $year->val_days();
    $oldl = Language($newl);
    $oldf = Date::Pcalc->date_format(1);
    for ( $i = 0; $i < $last; $i++ )
    {
examples/income.pl view on Meta::CPAN
##                                                                           ##
##    Copyright (c) 2001 - 2009 by Steffen Beyer.                            ##
##    All rights reserved.                                                   ##
##                                                                           ##
##    This program is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
BEGIN { eval { require bytes; }; }
use Date::Pcalendar::Profiles qw( $Profiles );
use Date::Pcalendar;
use Date::Pcalc qw(:all);
$self = $0;
$self =~ s!^.*[/\\]!!;
$self =~ s!\.+[^./\\]*$!!;
unless (@ARGV == 4)
{
    die "Usage: $self <year_of_birth> <vacation_days_per_year> <hours_per_week> <brut_yearly_income>\n";
}
examples/income.pl view on Meta::CPAN
print "\n";
print "Year of birth      = $birth\n";
print "Current year       = $start\n";
print "Year of retirement = $stop\n";
print "Vacation days/year = $vacation\n";
print "Hours per week     = $hours_per_week\n";
print "Brut annual income = $brut_yearly_income\n";
print "\n";
#$Cal = Date::Pcalendar->new( $Profiles->{'sdm-MUC'} );
$Cal = Date::Pcalendar->new( $Profiles->{'DE-NW'} );
for ( $year = $start; $year <= $stop; $year++ )
{
    $Year = $Cal->year( $year );
    $full = $Year->vec_full(); # full holidays
    $half = $Year->vec_half(); # half holidays
    $work = $Year->vec_work(); # workspace
    $work->Complement($full);  # workdays plus half holidays
    $full = $full->Norm();
    $half = $half->Norm();
examples/linearcal.pl view on Meta::CPAN
##    All rights reserved.                                                   ##
##                                                                           ##
##    This program is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
BEGIN { eval { require bytes; }; }
use strict;
use Date::Pcalendar::Profiles qw( $Profiles );
use Date::Pcalendar;
use Date::Pcalc::Object qw(:ALL);
sub print_linear_calendar
{
    my(@start) = shift_date(\@_);
    my(@stop)  = shift_date(\@_);
    my($lang)  = shift;
    my($prof)  = shift;
    my($newl)  = Decode_Language($lang);
    my($cal,$start,$stop,$oldl,$oldf,@labels,$dow,$day);
    die "No such language '$lang'" unless ($newl);
    die "No such calendar profile '$prof'"
        unless (exists $Profiles->{$prof});
    $cal   = Date::Pcalendar->new( $Profiles->{$prof} );
    $start = Date::Pcalc->new(@start);
    $stop  = Date::Pcalc->new(@stop);
    $oldl = Language($newl);
    $oldf = Date::Pcalc->date_format(1);
    while ($start <= $stop)
    {
        @labels = $cal->labels($start);
        $dow = substr(shift(@labels),0,3);
examples/linearcal.pl view on Meta::CPAN
    Language($oldl);
    Date::Pcalc->date_format($oldf);
}
unless (@ARGV == 8)
{
    die "Usage: perl linearcal.pl YEAR1 MONTH1 DAY1 YEAR2 MONTH2 DAY2 LANGUAGE PROFILE\n";
}
print_linear_calendar( @ARGV );
__END__
examples/vacation.pl view on Meta::CPAN
##                                                                           ##
##    Copyright (c) 2001 - 2009 by Steffen Beyer.                            ##
##    All rights reserved.                                                   ##
##                                                                           ##
##    This program is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
BEGIN { eval { require bytes; }; }
use Date::Pcalendar::Profiles qw( $Profiles );
use Date::Pcalendar;
$cal = Date::Pcalendar->new( $Profiles->{'DE-NW'} );
$year = $cal->year( 2002 );
$delta = $year->delta_workdays( 2002,1,1, 2002,2,3, 1,1 );
print "$delta\n";
__END__
examples/weiberfastnacht.pl view on Meta::CPAN
##                                                                           ##
##    Copyright (c) 2001 - 2009 by Steffen Beyer.                            ##
##    All rights reserved.                                                   ##
##                                                                           ##
##    This program is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
BEGIN { eval { require bytes; }; }
use Date::Pcalendar::Profiles qw( $Profiles );
use Date::Pcalendar;
use Date::Pcalc::Object qw(:all);
Language(Decode_Language("Deutsch"));
Date::Pcalc->date_format(3);
$cal = Date::Pcalendar->new( $Profiles->{'DE-NW'} );
$cal->cache_add( 2000..2003 );
@date = $cal->search("Weiber");
print map sprintf("%s (%s)\n", $_, join(' ', $cal->labels($_->date()))), @date;
print "\n";
$year = $cal->year( 2004 );
lib/Date/Pcalc/Object.pod view on Meta::CPAN
Note that "C<abs($date)>" and "C<abs($delta)>" are just shorthands
for "C<$date-E<gt>number()>" and "C<$delta-E<gt>number()>".
The operator "C<abs()>", when applied to a date or delta vector,
returns the corresponding number of days (see below for an exception
to this), with the time part (if available) represented by a fraction
after the decimal point.
In the case of dates, the absolute value (to the left of the
decimal point) is the number of days since the 1st of January
S<1 A.D.> (by extrapolating the Gregorian calendar back beyond
its "natural" limit of 1582 A.D.) B<PLUS ONE>.
(I.e., the absolute value of the 1st of January 1 A.D. is 1.)
Exception:
If the "NUMBER" or "number_format()" is set to 0 (the default
setting), the absolute value of a date to the left of the decimal
point is "yyyymmdd", i.e., the number in which the uppermost four
digits correspond to the year, the next lower two digits to the
lib/Date/Pcalc/Object.pod view on Meta::CPAN
structures themselves.
This may not be what you want.
(You will have to override these two methods and write some
of your own if not.)
In order for the overloaded operators and the "shift_*()"
auxiliary functions from the "Date::Pcalc::Object" package
to work properly (the latter of which are heavily used in
the "Date::Pcalendar[::Year]" modules, for instance), the
package name of your subclass (= the one your objects will
be blessed into) is B<REQUIRED> to contain a "::".
Note that you should B<ONLY> subclass "Date::Pcalc", B<NEVER>
"Date::Pcalc::Object", since subclassing the latter is less
efficient (because "Date::Pcalc::Object" is just an empty class
which inherits from "Date::Pcalc" - subclassing "Date::Pcalc::Object"
would thus just introduce an additional name space layer to search
during Perl's runtime method binding process).
If you give your subclass a package name below/inside the
"Date::" namespace, you will also benefit from the fact that
all error messages produced by the "Date::Pcalc[::Object]" module
(and also the "Date::Pcalendar[::Year]" modules, by the way)
will appear to have originated from the place outside of all
"C</^Date::/>" modules (including yours) where one of the "Date::"
modules was first called - i.e., all errors are always blamed
on the user, no matter how deeply nested inside the "Date::"
modules they occur, and do not usually refer to places inside
any of the "Date::" modules (this assumes that there are no
bugs in the "Date::" modules, and that all errors are always
the user's fault C<:-)>).
Moreover, your module's own error messages will behave in the
lib/Date/Pcalc/Object.pod view on Meta::CPAN
  else
      { print "Sorry, you are under 18!\n"; }
=back
For more examples, see the "examples" subdirectory in this distribution,
and their descriptions in the file "EXAMPLES.txt".
=head1 SEE ALSO
Date::Pcalc(3), Date::Calc::Util(3), Date::Pcalendar(3),
Date::Pcalendar::Year(3), Date::Pcalendar::Profiles(3).
=head1 VERSION
This man page documents "Date::Pcalc::Object" version 6.1.
=head1 AUTHOR
  Steffen Beyer
  mailto:STBEY@cpan.org
  http://www.engelschall.com/u/sb/download/
lib/Date/Pcalendar/Profiles.pm view on Meta::CPAN
###############################################################################
##                                                                           ##
##    Copyright (c) 2000 - 2009 by Steffen Beyer.                            ##
##    All rights reserved.                                                   ##
##                                                                           ##
##    This package is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
package Date::Pcalendar::Profiles;
BEGIN { eval { require bytes; }; }
use strict;
use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION $Profiles );
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw();
lib/Date/Pcalendar/Profiles.pm view on Meta::CPAN
{
    "New Year's Day"            => \&GB_New_Year,
    "Good Friday"               => "-2",
    "Easter Sunday"             => "+0",
    "Easter Monday"             => "+1",
    "Early May Bank Holiday"    => \&GB_Early_May,
    "Late May Bank Holiday"     => "5/Mon/May", # Last Monday
#
# Jonathan Stowe <gellyfish@gellyfish.com> told me that spring
# bank holiday is the first Monday after Whitsun, but my pocket
# calendar suggests otherwise. I decided to follow my pocket
# guide and an educated guess ;-), but please correct me if
# I'm wrong!
#
    "Summer Bank Holiday"       => "5/Mon/Aug", # Last Monday
    "Christmas Day"             => \&GB_Christmas,
    "Boxing Day"                => \&GB_Boxing
};
sub GB_New_Year
{
    my($year,$label) = @_;
    return( &Next_Monday($year,1,1) );
}
#
# The following formula (also from Jonathan Stowe <gellyfish@gellyfish.com>)
# also contradicts my pocket calendar, but for lack of a better guess I
# left it as it is. Please tell me the correct formula in case this one
# is wrong! Thank you!
#
sub GB_Early_May # May bank holiday is the first Monday after May 1st
{
    my($year,$label) = @_;
    if (Day_of_Week($year,5,1) == 1)
        { return( Nth_Weekday_of_Month_Year($year,5,1,2) ); }
    else
        { return( Nth_Weekday_of_Month_Year($year,5,1,1) ); }
lib/Date/Pcalendar/Profiles.pm view on Meta::CPAN
# Thanks to:
# Bianca Taylor <bianca@unisolve.com.au>
# Andie Posey <andie@posey.org>
# Don Simonetta <don.simonetta@tequinox.com>
# Paul Fenwick <pjf@cpan.org>
# Brian Graham <brian.graham@nec.com.au>
# Pat Waters <pat.waters@dir.qld.gov.au>
# Stephen Riehm <Stephen.Riehm@gmx.net>
#     http://www.holidayfestival.com/Australia.html
#     http://www.earthcalendar.net/countries/2001/australia.html
# Sven Geisler <sgeisler@aeccom.com>
# Canberra (ACT):
#     http://www.workcover.act.gov.au/labourreg/publicholidays.html
# New South Wales (NSW):
#     http://www.dir.nsw.gov.au/holidays/index.html
# Northern Territory (NT):
#     http://www.nt.gov.au/ocpe/documents/public-holidays/
# Queensland (QLD):
#     http://www.wageline.qld.gov.au/publicholidays/list_pubhols.html
# South Australia (SA):
lib/Date/Pcalendar/Profiles.pod view on Meta::CPAN
=head1 NAME
Date::Pcalendar::Profiles - Some sample profiles for Date::Pcalendar
and Date::Pcalendar::Year
=head1 SYNOPSIS
  use Date::Pcalendar::Profiles qw( $Profiles );
  use Date::Pcalendar;
  $cal_US_AK = Date::Pcalendar->new( $Profiles->{'US-AK'} [,LANG[,WEEKEND]] );
  $cal_DE_BY = Date::Pcalendar->new( $Profiles->{'DE-BY'} [,LANG[,WEEKEND]] );
 or
  use Date::Pcalendar::Profiles qw( $Profiles );
  use Date::Pcalendar::Year;
  $year_2000_US_FL = Date::Pcalendar::Year->new( 2000, $Profiles->{'US-FL'} [,LANG[,WEEKEND]] );
  $year_2001_DE_NW = Date::Pcalendar::Year->new( 2001, $Profiles->{'DE-NW'} [,LANG[,WEEKEND]] );
 and also
  use Date::Pcalendar::Profiles
  qw(
      &Previous_Friday
      &Next_Monday
      &Next_Monday_or_Tuesday
      &Nearest_Workday
      &Sunday_to_Monday
      &Advent1
      &Advent2
      &Advent3
      &Advent4
      &Advent
  );
=head1 PREFACE
This module provides some sample profiles (i.e., holiday schemes)
for use with the Date::Pcalendar(3) and Date::Pcalendar::Year(3)
module.
You are not required to use these, you can always roll your own
(this is very easy). See the section "HOW TO ROLL YOUR OWN" below
for more instructions on how to do this, and take the profiles
from this module as examples.
Please let me know of any errors in these profiles, and please
send me your own profiles if you'd like to see them included in
the next release of this module! Thank you!
(But please, only use the ISO-Latin-1 character set whenever
possible, since my module doesn't support any other character
sets yet, or at least tell me which character set you used
so I can document this in this manual page. Thank you!)
=head1 DESCRIPTION
The method "init()" in module Date::Pcalendar::Year(3) is
responsible for parsing the calendar schemes contained
here in the Date::Pcalendar::Profiles module.
This method offers a "mini-language" which allows to
specify common date formulas, like for instance a simple
fixed date (in various different formats, e.g. american
or european), or things like "the second Sunday of May"
(Mother's Day), or "Easter Sunday minus 46 days" (Ash
Wednesday), to cite just a few.
See the section "DATE FORMULA SYNTAX" below for more
details.
lib/Date/Pcalendar/Profiles.pod view on Meta::CPAN
In order to be able to deal with such formulas, and in
order to be as flexible as possible, the "init()" method
offers the possibility of using callback functions to
deal with such dates and formulas.
See the section "CALLBACK INTERFACE" below for more
details on this topic.
In order to assist you with more common cases of odd
formulas, the module Date::Pcalendar::Profiles exports
the following utility subroutines (which are meant to
be used as "filters" in callback functions of your own):
=over 2
=item *
C<($year,$month,$day[,ANYTHING]) = Previous_Friday($year,$month,$day[,ANYTHING]);>
If the given date falls on a Saturday or Sunday, this
lib/Date/Pcalendar/Profiles.pod view on Meta::CPAN
copied to the output.
=back
The typical use of these filter subroutines is in a "return"
statement at the end of callback functions of your own, when
you already have calculated the holiday in question and only
need to adjust it according to the rule implemented by the
filter subroutine in question.
See also the implementation of the Date::Pcalendar::Profiles
module for examples of how to use these functions.
=head1 DATE FORMULA SYNTAX
 -  Fixed dates:
    "Christmas"  =>  "24.12",   # European format (day, month)
    "Christmas"  =>  "24.12.",
    "Christmas"  =>  "24Dec",
lib/Date/Pcalendar/Profiles.pod view on Meta::CPAN
    "Memorial Day"      =>  "5/Mon/May", # LAST Monday of May
 -  Half holidays, commemorative days:
    "Christmas"         =>  ":24.12.", # only half a day off
    "Valentine's Day"   =>  "#Feb/14", # not an official holiday
=head1 CALLBACK INTERFACE
The interface of the callback functions to use with the
"init()" method of the Date::Pcalendar::Year(3) module is
very simple:
The callback function receives two arguments when called,
first the year number for which the holiday is to be
calculated, and second the name (the "label") of the
holiday in question (which serves as key in the hash
of a holiday scheme).
This second parameter allows you to use the same callback
function for different holidays, which might be more practical
(than separate callback functions) if for instance you have
a set of similar holidays to calculate, like for instance
the four Sundays before Christmas ("Advent").
The callback function "Advent()" (exported by the
Date::Pcalendar::Profiles module) exemplifies this
technique.
The callback function is expected to return a list
"C<($year,$month,$day)>" with the exact date of the
holiday (the year number in the output must of course
match the year number passed as parameter).
A fatal error occurs if the returned list does not
constitute a valid date, in the requested year.
lib/Date/Pcalendar/Profiles.pod view on Meta::CPAN
The string ":" means that the date in question is a
"half" holiday, i.e., a day on which you get half a
day off from work.
In case the holiday in question was not observed or did
not exist in the requested year, the callback function
may also return an empty list. This will cause the "init()"
method to simply drop this holiday for that year.
The module Date::Pcalendar::Profiles exports the sample
callback functions "Advent1()", "Advent2()", "Advent3()",
"Advent4()" and "Advent()", which might assist you in
rolling your own profiles.
=head1 HOW TO ROLL YOUR OWN
Every calendar profile (holiday scheme) is a hash.
The name of the holiday (like "Christmas", for instance)
serves as the key in this hash and must therefore be
unique (unless you want to override a default which was
set previously, but see below for more on this).
The value for each key is either a string, which specifies
a simple date formula, or the reference of a callback function.
See the section "CALLBACK INTERFACE" above for a description
of the interface (in and out) of these callback functions.
See the section "DATE FORMULA SYNTAX" above and the description
of the "init()" method in L<Date::Pcalendar::Year(3)> for the
exact syntax of date formula strings.
B<BEWARE> that if keys are not unique in the source code,
later entries will overwrite previous ones! I.e.,
    ...
    "My special holiday" => "01-11",
    "My special holiday" => "02-11",
    ...
will B<NOT> set two holidays of the same name, one on November
first, the other on November second, but only one, on November
second!
Therefore, in order to use sets of defaults and to be able
to override some of them, you must B<FIRST> include any hash
containing the default definitions, and B<THEN> write down
your own definitions (see also the Date::Pcalendar::Profiles
module for examples of this!), like this:
    $defaults =
    {
        "Holiday #1" => "01-01",
        "Holiday #2" => "02-02",
        "Holiday #3" => "03-03"
    };
    $variant1 =
lib/Date/Pcalendar/Profiles.pod view on Meta::CPAN
this year number is omitted, we simply don't display the age.
Now in order to query this birthday database, we can use the
following little program:
  #!perl -w
  use strict;
  no strict "vars";
  use Date::Pcalc qw(:all);
  use Date::Pcalendar;
  $Birthdays =
  {
      ... # (see above)
  };
  @today = Today();
  $calendar = Date::Pcalendar->new( $Birthdays );
  $calendar->year( $today[0] );
  foreach $key (@ARGV)
  {
      if (@list = $calendar->search( $key ))
      {
          foreach $date (@list)
          {
              @labels = $calendar->labels( $date );
              $dow = shift(@labels);
              # More than one person might have birthday on the same date:
              $name = $key;
              foreach $person (@labels)
              {
                  if (index(lc($person),lc($key)) >= 0)
                  {
                      $name = $person;
                      last;
                  }
lib/Date/Pcalendar/Profiles.pod view on Meta::CPAN
  Spouse              :   +88 days => Sun 30-Dec-2001 (29 years old)
By the way, a similar program is included in the "examples"
subdirectory of the Date::Pcalc distribution, called "anniversaries.pl".
See also the file "EXAMPLES.txt" in the distribution's main directory
for a short description of that little script.
=head1 SEE ALSO
Date::Pcalendar(3), Date::Pcalendar::Year(3),
Date::Pcalc::Object(3), Date::Pcalc(3),
Date::Calc::Util(3).
=head1 LIMITATIONS
The calendar profiles included in this module usually do not take
historical irregularities into account (even though some do in order
to show how this can be done), they only provide means for calculating
B<regularly> recurring events (B<the profiles should therefore not be
relied upon for historical faithfulness>).
=head1 KNOWN BUGS
The australian calendar profiles are known to contain wrong dates.
This is due to the fact that Australia decrees its holidays individually
for each year, difficulting the calculation of the holidays by way of
a formula. An effort to compare (and to correct) the current implementation
with official documents (web pages) by the Australian authorities is under
way. This hasn't been finished yet because it is very time-consuming.
=head1 VERSION
This man page documents "Date::Pcalendar::Profiles" version 6.1.
=head1 AUTHOR
  Steffen Beyer
  mailto:STBEY@cpan.org
  http://www.engelschall.com/u/sb/download/
=head1 COPYRIGHT
Copyright (c) 2000 - 2009 by Steffen Beyer. All rights reserved.
lib/Date/Pcalendar/Year.pm view on Meta::CPAN
###############################################################################
##                                                                           ##
##    Copyright (c) 2000 - 2009 by Steffen Beyer.                            ##
##    All rights reserved.                                                   ##
##                                                                           ##
##    This package is free software; you can redistribute it                 ##
##    and/or modify it under the same terms as Perl itself.                  ##
##                                                                           ##
###############################################################################
package Date::Pcalendar::Year;
BEGIN { eval { require bytes; }; }
use strict;
use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION );
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw();
lib/Date/Pcalendar/Year.pm view on Meta::CPAN
sub new
{
    my($class)    = shift;
    my($year)     = shift_year(\@_);
    my($profile)  = shift;
    my($lang)     = shift || 0;
    my($self);
    &check_year($year);
    $self = { };
    $class = ref($class) || $class || 'Date::Pcalendar::Year';
    bless($self, $class);
    $self->init($year,$profile,$lang,@_);
    return $self;
}
sub init
{
    my($self)     = shift;
    my($year)     = shift_year(\@_);
    my($profile)  = shift;
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
=head1 NAME
Date::Pcalendar::Year - Implements embedded "year" objects for Date::Pcalendar
=head1 MOTTO
There is more than one way to do it - this is just one of them!
=head1 PREFACE
Note that Date::Pcalendar::Year (and Date::Pcalendar) can only deal
with years lying within the range [1583..2299].
=head1 SYNOPSIS
  use Date::Pcalendar::Year qw( check_year empty_period );
  use Date::Pcalendar::Year qw( :all ); # same as above
  check_year(YEAR|DATE); # dies if year < 1583 or year > 2299
  empty_period();        # warns about empty interval if $^W is set
  $index = $year->date2index(YEAR,MONTH,DAY|DATE);
  $date  = $year->index2date(INDEX);
  use Date::Pcalendar::Profiles qw( $Profiles );
  $year_2000_US_FL = Date::Pcalendar::Year->new( 2000, $Profiles->{'US-FL'} [,LANG[,WEEKEND]] );
  $year_2001_DE_NW = Date::Pcalendar::Year->new( 2001, $Profiles->{'DE-NW'} [,LANG[,WEEKEND]] );
  $year = Date::Pcalendar::Year->new( 2001, {} );
  $year->init( 2002, $Profiles->{'DE-SN'} [,LANG[,WEEKEND]] );
  $vector = $year->vec_full(); # vector of full holidays
  $vector = $year->vec_half(); # vector of half holidays
  $vector = $year->vec_work(); # NOT a vector of workdays but a workspace!
  $size   = $year->val_days(); # number of days in that year, size of vectors
  $base   = $year->val_base(); # number of days for [year,1,1] since [1,1,1]
  $number = $year->val_year(); # the year's number itself
  $number = $year->year();     # alias for val_year()
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
And similarly if a time or a combined date and time are expected.
If you substitute an expected year number by an anonymous array
(this is the recommended way of writing date constants, for
increased readability of your programs), it must contain three
values, nevertheless (otherwise the use of an anonymous array
would be pointless).
Don't confuse year numbers and their substitutes (a date object
or an array reference) with Date::Pcalendar::Year objects, which
are a totally different thing!
But incidentally C<:-)>, you may also pass a Date::Pcalendar::Year
object whenever a year number is expected. However, and perhaps
against your expectations at times, only the year number from
that object will be used, not the year object itself (the year
object in question might be using the wrong profile!).
Moreover, whenever a method of this class returns a date, it
does so by returning a Date::Pcalc[::Object] date object.
=head1 IMPLEMENTATION
Each Date::Pcalendar::Year object consists mainly of three bit
vectors, plus some administrative attributes, all stored in a
(blessed) hash.
All three bit vectors contain as many bits as there are days
in the corresponding year, i.e., either 365 or 366.
The first bit vector, called "FULL", contains set bits for
Saturdays, Sundays and all "full" legal holidays (i.e.,
days off, on which you usually do not work).
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
=item *
C<empty_period();>
This function issues a warning (from the perspective of the
caller of a Date::* module) that the given range of dates is
empty ("dates interval is empty"), provided that warnings are
enabled (i.e., "C<$^W>" is true).
This function is currently used by the method "delta_workdays()"
in this class, and by its equivalent from the Date::Pcalendar
module.
It is called whenever the range of dates of which the difference
in working days is to be calculated is empty. This can happen for
instance if you specify two adjacent dates both of which are not
to be included in the difference.
=back
Methods
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
date), i.e., a number between 0 (for January 1st) and the number
of days in the given year minus one, i.e., 364 or 365 (for
December 31st).
You may need this in order to access the bit vectors returned
by the methods "vec_full()", "vec_half()" and "vec_work()".
Note that there are shorthand methods in this module called
"is_full()", "is_half()" and "is_work()", which serve to test
individual bits of the three bit vectors which are a part of
each Date::Pcalendar::Year object.
An exception ("given year != object's year") is thrown if the
year associated with the year object itself and the year from
the given date do not match.
An exception ("invalid date") is also thrown if the given
arguments do not constitute a valid date, or ("given year
out of range [1583..2299]") if the given year lies outside
of the permitted range.
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
given year back into a date.
An exception ("invalid index") is thrown if the given index
is outside of the permitted range for the given year, i.e.,
C<[0..364]> or C<[0..365]>.
Note that this method returns a Date::Pcalc B<OBJECT>!
=item *
C<$year_2000_US_FL = Date::Pcalendar::Year-E<gt>new( 2000, $Profiles-E<gt>{'US-FL'} [,LANG[,WEEKEND]] );>
C<$year_2001_DE_NW = Date::Pcalendar::Year-E<gt>new( 2001, $Profiles-E<gt>{'DE-NW'} [,LANG[,WEEKEND]] );>
C<$year = Date::Pcalendar::Year-E<gt>new( 2001, {} );>
This is the constructor method. Call it to create a new
Date::Pcalendar::Year object.
The first argument must be a year number in the range
[1583..2299].
The second argument must be the reference of a hash,
which usually contains names of holidays and commemorative
days as keys and strings containing the date or formula
for each holiday as values.
Reading this hash and initializing the object's internal
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
=item *
C<$year-E<gt>init( 2002, $Profiles-E<gt>{'DE-SN'} [,LANG[,WEEKEND]] );>
This method is called by the "new()" constructor method,
internally, and has the same arguments as the latter.
See immediately above for a description of these arguments.
Note that you can also call this method explicitly yourself,
if needed, and you can of course subclass the Date::Pcalendar::Year
class and override the "init()" method with a method of your own.
The holiday scheme or "profile" (i.e., the reference of
a hash passed as the second argument to this method) must
obey the following semantics and syntax:
The keys are the names of the holiday or commemorative day
in question. Keys must be unique (but see further below).
The difference between a holiday and a commemorative day is
that you (usually) get a day off on a holiday, whereas on a
purely commemorative day, you don't.
A commemorative day is just a date with a name, nothing more.
The values belonging to these keys can either be the code
reference of a callback function (see L<Date::Pcalendar::Profiles(3)>
for more details and examples), or a string.
All other values cause a fatal error with program abortion.
The strings can specify three types of dates:
  -  fixed dates
     (like New Year, or first of January),
  -  dates relative to Easter Sunday
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
calculates the 5th of the requested day of week, and if that
doesn't exist, takes the 4th instead.
There are also two modifier characters which may prefix the
string with the date formula, "#" and ":".
The character "#" (mnemonic: it's only a comment) signals
that the date in question is a purely commemorative day,
i.e., it will not enter into any date calculations, but
can be queried with the "labels()" and "search()" methods,
and appears when printing a calendar, for instance.
The character ":" (mnemonic: divided into two halfs) specifies
that the date in question is only a "half" holiday, i.e., you
only get half a day off instead of a full day. Some companies
have this sort of thing. C<:-)>
The exact syntax for the date formula strings is the following
(by example):
 -  Fixed dates:
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
    "My special holiday" => "02-11",
    ...
will B<NOT> set two holidays of the same name, one on November
first, the other on November second, but only one, on November
second!
Therefore, in order to use sets of defaults and to be able
to override some of them, you must B<FIRST> include any hash
containing the default definitions, and B<THEN> write down
your own definitions (see also the Date::Pcalendar::Profiles
module for examples of this!), like this:
    $defaults =
    {
        "Holiday #1" => "01-01",
        "Holiday #2" => "02-02",
        "Holiday #3" => "03-03"
    };
    $variant1 =
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
    };
This is because of the way hashes work in Perl.
The "init()" method proceeds as follows:
First it checks whether the given year number lies in
the range [1583..2299]. A fatal error occurs if not.
Then it determines the number of days in the requested
year, and stores it in the given Date::Pcalendar::Year
object.
It then calls the Bit::Vector(3) module to allocate three
bit vectors with a number of bits equal to the number of
days in the requested year, and stores the three object
references (of the bit vectors) in the Date::Pcalendar::Year
object.
(See also the description of the three methods "vec_full()",
"vec_half()" and "vec_full()" immediately below.)
It then sets the bits which correspond to Saturdays and
Sundays (or optionally to the days whose numbers have been
specified as the "weekend") in the "full holidays" bit vector.
At last, it iterates over the keys of the given holiday
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
=item *
C<$number = $year-E<gt>val_year();>
C<$number = $year-E<gt>year();>
These two methods are identical, the latter being a shortcut of
the former.
They return the number of the year for which a calendar has been
stored in the given year object.
The method name "val_year()" is used here in order to be consistent
with the other attribute accessor methods of this class, and the
method "year()" is necessary in order to be able to pass
Date::Pcalendar::Year objects as parameters instead of a year number
in the methods of the Date::Pcalendar and Date::Pcalendar::Year
modules.
=item *
C<@names = $year-E<gt>labels(YEAR,MONTH,DAY|DATE);>
C<@holidays = $year-E<gt>labels();>
C<$holidays = $year-E<gt>labels();>
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
In scalar context, only the number of items in the resulting list
is returned, instead of the resulting list itself (as in list context).
=item *
C<$hashref  = $year-E<gt>tags(YEAR,MONTH,DAY|DATE);>
C<$hashref  = $year-E<gt>tags(INDEX);>
This method returns a hash reference for the given calendar and date
(or index). The hash it refers to is a copy of the calendar profile's
internal hash which contains the names for the given date as keys and
0, 1, 2, or 3 as their corresponding values meaning the following:
    0    =>    commemorative day
    1    =>    "half" holiday
    2    =>    "full" holiday
    3    =>    both a "half" and a "full" holiday
The value "3" should only occur if a date has been redefined by the
underlying profile using the same key (i.e., the same name) but with
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
You add days (i.e., you go forward in time) with a positive
offset "DELTA", and you subtract days (i.e., you go backwards
in time) with a negative offset.
Note that an exception ("invalid date") is raised if the
given date argument (the "start" date) does not constitute
a valid date.
Beware that this method is limited to date calculations within
a single year (in contrast to the method with the same name
from the Date::Pcalendar module).
Therefore, the method does not only return a date (object),
but also a "rest" and a "sign".
The "rest" indicates how many days are still left from your
original DELTA after going in the desired direction and
reaching a year boundary.
The "sign" indicates in which direction (future or past) one
needs to go in order to "eat up" the "rest" (by subtracting
a day from the "rest" for each work day passed), or to adjust
the resulting date (in order to skip any holidays directly
after a year boundary), if at all.
The "sign" is -1 for going backwards in time, +1 for going
forward, and 0 if the result doesn't need any more fixing
(for instance because the result lies in the same year as
the starting date).
The method "add_delta_workdays()" from the Date::Pcalendar
module uses the "rest" and "sign" return values from this
method in order to perform calculations which may cross
year boundaries.
Therefore, it is not recommended to use this method here
directly, as it is rather clumsy to use, but to use the
method with the same name from the Date::Pcalendar module
instead, which does the same but is much easier to use
and moreover allows calculations which cross an arbitrary
number of year boundaries.
B<BEWARE> that this method may currently return unexpected
(i.e., contradicting the above documentation) or plain wrong
results when going back in time (this is a bug!).
However, it works correctly and as documented above when
going forward in time.
=item *
C<$flag = $year-E<gt>is_full(YEAR,MONTH,DAY|DATE);>
This method returns "true" ("1") if the bit corresponding to
the given date is set in the bit vector representing "full"
holidays, and "false" ("0") otherwise.
I.e., the method returns "true" if the given date is a (full)
holiday (according to the calendar profile associated with the
given year object).
=item *
C<$flag = $year-E<gt>is_half(YEAR,MONTH,DAY|DATE);>
This method returns "true" ("1") if the bit corresponding to
the given date is set in the bit vector representing "half"
holidays, and "false" ("0") otherwise.
I.e., the method returns "true" if the given date is a half
holiday (according to the calendar profile associated with the
given year object).
Note that if a date is a "full" holiday, the "half" bit is
never set, even if you try to do so in your calendar profile,
on purpose or by accident.
=item *
C<$flag = $year-E<gt>is_work(YEAR,MONTH,DAY|DATE);>
This method returns "true" ("1") if the bit corresponding to
the given date is set in the bit vector used to perform all
sorts of calculations, and "false" ("0") otherwise.
lib/Date/Pcalendar/Year.pod view on Meta::CPAN
of days in the given year "C<$year>", which you can retrieve
through either "C<$days = $year-E<gt>vec_work-E<gt>Size();>"
or "C<$days = $year-E<gt>val_days();>".
See also L<Bit::Vector(3)> for more details.
=back
=head1 SEE ALSO
Bit::Vector(3), Date::Pcalendar(3), Date::Pcalendar::Profiles(3),
Date::Pcalc::Object(3), Date::Pcalc(3), Date::Calc::Util(3).
=head1 KNOWN BUGS
The method "add_delta_workdays()" is known to produce results
which are sometimes off by one working day when a negative
offset is used. As a workaround, try to add one working day
first and then subtract one working day more than initially
intended. See also the file "examples/bug.pl" for how to do
this.
=head1 VERSION
This man page documents "Date::Pcalendar::Year" version 6.1.
=head1 AUTHOR
  Steffen Beyer
  mailto:STBEY@cpan.org
  http://www.engelschall.com/u/sb/download/
=head1 COPYRIGHT
Copyright (c) 2000 - 2009 by Steffen Beyer. All rights reserved.
src/C_XS/DatePcalc.c view on Meta::CPAN
#ifndef MODULE_DATE_CALC
#define MODULE_DATE_CALC
/*****************************************************************************/
/*  MODULE NAME:  DatePcalc.c                           MODULE TYPE:  (lib)  */
/*****************************************************************************/
/*          Gregorian calendar date calculations in compliance with          */
/*          ISO/R 2015-1971, DIN 1355 and (to some extent) ISO 8601.         */
/*****************************************************************************/
/*  MODULE IMPORTS:                                                          */
/*****************************************************************************/
#include <stdio.h>                                  /*  MODULE TYPE:  (sys)  */
#include <stdlib.h>                                 /*  MODULE TYPE:  (sys)  */
#include <string.h>                                 /*  MODULE TYPE:  (sys)  */
#include <time.h>                                   /*  MODULE TYPE:  (sys)  */
#include "ToolBox.h"                                /*  MODULE TYPE:  (dat)  */
/*****************************************************************************/
src/C_XS/DatePcalc.h view on Meta::CPAN
#ifndef MODULE_DATE_CALC
#define MODULE_DATE_CALC
#ifdef __cplusplus
extern "C"
{
#endif
/*****************************************************************************/
/*  MODULE NAME:  DatePcalc.h                           MODULE TYPE:  (lib)  */
/*****************************************************************************/
/*          Gregorian calendar date calculations in compliance with          */
/*          ISO/R 2015-1971, DIN 1355 and (to some extent) ISO 8601.         */
/*****************************************************************************/
/*  MODULE IMPORTS:                                                          */
/*****************************************************************************/
#include <stdio.h>                                  /*  MODULE TYPE:  (sys)  */
#include <stdlib.h>                                 /*  MODULE TYPE:  (sys)  */
#include <string.h>                                 /*  MODULE TYPE:  (sys)  */
#include <time.h>                                   /*  MODULE TYPE:  (sys)  */
#include "ToolBox.h"                                /*  MODULE TYPE:  (dat)  */
/*****************************************************************************/
BEGIN { eval { require bytes; }; }
use strict;
no strict "vars";
# ======================================================================
#   $version = $Carp::Clan::VERSION;
#   $version = $Date::Pcalc::VERSION;
#   $version = &Date::Pcalc::Version();
#   $version = $Date::Pcalc::Object::VERSION;
#   $version = $Date::Pcalendar::Profiles::VERSION;
#   $version = $Date::Pcalendar::Year::VERSION;
#   $version = $Date::Pcalendar::VERSION;
# ======================================================================
$Carp::Clan::VERSION                = $Carp::Clan::VERSION                = 0;
$Date::Pcalc::VERSION               = $Date::Pcalc::VERSION               = 0;
$Date::Pcalc::Object::VERSION       = $Date::Pcalc::Object::VERSION       = 0;
$Date::Pcalendar::Profiles::VERSION = $Date::Pcalendar::Profiles::VERSION = 0;
$Date::Pcalendar::Year::VERSION     = $Date::Pcalendar::Year::VERSION     = 0;
$Date::Pcalendar::VERSION           = $Date::Pcalendar::VERSION           = 0;
$Bit::Vector::VERSION               = $Bit::Vector::VERSION               = 0;
$tests = 9;
eval { require Bit::Vector; };
unless ($@) { $tests += 6; }
print "1..$tests\n";
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
if ($Date::Pcalc::Object::VERSION eq '6.1')
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
eval
{
    require Date::Pcalendar::Profiles;
    Date::Pcalendar::Profiles->import( qw( $Profiles ) );
};
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
if ($Date::Pcalendar::Profiles::VERSION eq '6.1')
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
exit 0 if $n > $tests;
if ($Bit::Vector::VERSION >= '7.1')
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
if (&Bit::Vector::Version() >= '7.1')
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
eval
{
    require Date::Pcalendar::Year;
    Date::Pcalendar::Year->import( qw(:all) );
};
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
if ($Date::Pcalendar::Year::VERSION eq '6.1')
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
eval
{
    require Date::Pcalendar;
    Date::Pcalendar::Year->import( qw() );
};
unless ($@)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
if ($Date::Pcalendar::VERSION eq '6.1')
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
__END__
no strict "vars";
eval { require Bit::Vector; };
if ($@)
{
    print "1..0\n";
    exit 0;
}
require Date::Pcalendar;
require Date::Pcalendar::Profiles;
Date::Pcalendar::Profiles->import('$Profiles');
# ======================================================================
#   $cal  = Date::Pcalendar->new($prof);
#   $year = $cal->year($year);
#   $year = Date::Pcalendar::Year->new($year,$prof); # (implicitly)
# ======================================================================
print "1..", scalar(keys %{$Profiles}), "\n";
$n = 1;
$year = 2000;
foreach $key (keys %{$Profiles})
{
    eval
    {
        $cal  = Date::Pcalendar->new( $Profiles->{$key} );
        $year = $cal->year( $year );
    };
    unless ($@)
    {print "ok $n\n";} else {print "not ok $n\n";}
    $n++;
}
__END__
no strict "vars";
eval { require Bit::Vector; };
if ($@)
{
    print "1..0\n";
    exit 0;
}
require Date::Pcalendar::Year;
# ======================================================================
#   $year = Date::Pcalendar::Year->new(YEAR,PROFILE);
#   ($date,$rest,$sign) = $year->_move_forward_(INDEX,OFFSET,SIGN);
# ======================================================================
print "1..166\n";
$n = 1;
$year = Date::Pcalendar::Year->new(1995,{});
$full = $year->vec_full();
$yday = 0;
foreach $bit (1,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0)
{
    if ($full->bit_test($yday++) == $bit)
    {print "ok $n\n";} else {print "not ok $n\n";}
    $n++;
}
$year = Date::Pcalendar::Year->new(1996,{});
$full = $year->vec_full();
$yday = 0;
foreach $bit (0,0,0,0,0,1,1,0,0,0,0,0,1,1,0)
{
    if ($full->bit_test($yday++) == $bit)
    {print "ok $n\n";} else {print "not ok $n\n";}
    $n++;
}
$year = Date::Pcalendar::Year->new(1999,{});
$full = $year->vec_full();
$yday = 0;
foreach $bit (0,1,1,0,0,0,0,0,1,1,0)
{
    if ($full->bit_test($yday++) == $bit)
    {print "ok $n\n";} else {print "not ok $n\n";}
    $n++;
}
##################################################
$year = Date::Pcalendar::Year->new(1995,{},0,1,3,5);
$full = $year->vec_full();
$yday = 0;
foreach $bit (0,1,0,1,0,1,0,0,1,0,1,0,1,0,0,1)
{
    if ($full->bit_test($yday++) == $bit)
    {print "ok $n\n";} else {print "not ok $n\n";}
    $n++;
}
$year = Date::Pcalendar::Year->new(1996,{},1,2,4);
$full = $year->vec_full();
$yday = 0;
foreach $bit (0,1,0,1,0,0,0,0,1,0,1,0,0,0,0)
{
    if ($full->bit_test($yday++) == $bit)
    {print "ok $n\n";} else {print "not ok $n\n";}
    $n++;
}
$year = Date::Pcalendar::Year->new(1999,{},2,1,2,3,4,5);
$full = $year->vec_full();
$yday = 0;
foreach $bit (1,0,0,1,1,1,1,1,0,0,1)
{
    if ($full->bit_test($yday++) == $bit)
    {print "ok $n\n";} else {print "not ok $n\n";}
    $n++;
}
##################################################
$year = Date::Pcalendar::Year->new(2000,{});
$days = $year->val_days();
$last = $days - 1;
#$work = $year->vec_work();
$full = $year->vec_full();
$half = $year->vec_half();
$yday = 0;
foreach $bit (1,1,0,0,0,0,0,1,1,0)
{
no strict "vars";
eval { require Bit::Vector; };
if ($@)
{
    print "1..0\n";
    exit 0;
}
require Date::Pcalendar::Profiles;
require Date::Pcalendar;
# ======================================================================
#   $cal = Date::Pcalendar->new(PROFILE);
#   ($date,$rest) = $cal->add_delta_workdays(DATE,OFFSET);
#   $diff = $cal->delta_workdays(DATE1,DATE2,INC1,INC2);
# ======================================================================
print "1..24\n";
$n = 1;
$cal_DE_NW   = Date::Pcalendar->new( $Date::Pcalendar::Profiles::Profiles->{'DE-NW'} );
$cal_sdm_MUC = Date::Pcalendar->new( $Date::Pcalendar::Profiles::Profiles->{'sdm-MUC'} );
($date,$rest) = $cal_DE_NW->add_delta_workdays([2000,12,4],28);
if ($date == [2001,1,16])
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
if ($rest == 0)
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
no strict "vars";
eval { require Bit::Vector; };
if ($@)
{
    print "1..0\n";
    exit 0;
}
$Date::Pcalendar::Profiles::Profiles =
$Date::Pcalendar::Profiles::Profiles = 0; # Avoid "used only once" warning
require Date::Pcalc::Object;
require Date::Pcalendar::Profiles;
require Date::Pcalendar;
Date::Pcalc::Object->import(':all');
# ======================================================================
#   $cal = Date::Pcalendar->new(PROFILE[,LANG[,WEEKEND]]);
#   $cal->cache_add( YEAR [,YEAR]* );
#   $cal->cache_del( YEAR [,YEAR]* );
#   @list = $cal->cache_keys();
#   @dates = $cal->search(SUBSTRING);
#   @labels = $cal->labels(DATE);
#   @dates = $year->search(SUBSTRING);
#   @labels = $year->labels(DATE);
# ======================================================================
print "1..6\n";
$n = 1;
Date::Pcalc->date_format(3);
$cal = Date::Pcalendar->new( $Date::Pcalendar::Profiles::Profiles->{'DE-NW'}, Language(Decode_Language("Deutsch")) );
$cal->cache_add( 2000..2003,2005 );
@list = $cal->cache_keys();
if (join(',', @list) eq '2000,2001,2002,2003,2005')
{print "ok $n\n";} else {print "not ok $n\n";}
$n++;
$cal->cache_del( 2005 );