=======================================
  Module "Date::DateCalc" Version 2.2
=======================================

------------------------------------------------------------------------------
 Extension Module for Perl 5.002 (should work with Perl 5.000 and up as well)
------------------------------------------------------------------------------


Legal stuff:
------------

Copyright (c) 1996 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.


Requirements:
-------------

Perl version 5.000 or higher, a compiler complying with ANSI C standards (!).
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

What does it do:
----------------

The package provides a Perl interface to a C library which offers a wide
variety of date calculations, complying with the ISO/R 2015-1971 and DIN
1355 standards which specify things as what leap years are, when they
occur, how the week numbers are defined, what's the first day of the week,
how many weeks (52 or 53) a given year has, and so on (Gregorian calendar,
as opposed to the Julian calendar, which was used until 1582).

To give you an idea of what the package can do, here a list of all the
functions it exports:

  $flag = leap($year);
  $date = compress($yy,$mm,$dd);
  ($cc,$yy,$mm,$dd) = uncompress($date);
  $flag = check_compressed($date);
  $datestr = compressed_to_short($date);
  $flag = check_date($year,$mm,$dd);
  $days = calc_days($year,$mm,$dd);
  $weekday = day_of_week($year,$mm,$dd);
  $days = dates_difference($year1,$mm1,$dd1,$year2,$mm2,$dd2);
  ($year,$mm,$dd) = calc_new_date($year,$mm,$dd,$offset);
  ($days,$hh,$mm,$ss) = date_time_difference
  (
      $year1,$month1,$day1,$hh1,$mm1,$ss1,
      $year2,$month2,$day2,$hh2,$mm2,$ss2
  );
  ($year,$month,$day,$hh,$mm,$ss) = calc_new_date_time
  (
      $year,$month,$day,$hh,$mm,$ss,
      $days_offset,$hh_offset,$mm_offset,$ss_offset
  );
  $datestr = date_to_short($year,$mm,$dd);
  $datestr = date_to_string($year,$mm,$dd);
  ($week,$year) = week_number($year,$mm,$dd);
  ($year,$mm,$dd) = first_in_week($week,$year);
  $weeks = weeks_in_year($year);
  $day_name = day_name_tab($weekday);
  $month_name = month_name_tab($month);
  $weekday = decode_day($day_name);
  $month = decode_month($month_name);
  ($year,$mm,$dd) = decode_date($date);
  $days = days_in_month($year,$mm);
  $version = Date::DateCalc::Version();

For more details, see the Date::DateCalc(3) man page!


What's new in version 2.0:
--------------------------

The two functions "day_short_tab" and "month_short_tab" are gone,
these tables are not needed any longer internally. Substitute them
with substr(day_name_tab($dd),0,3) and substr(month_name_tab($mm),0,3),
respectively.

The functions "encode", "decode", "valid_date" and "date_string"
have been renamed to "compress", "uncompress", "check_compressed"
and "compressed_to_short", respectively, to reflect the fact that
they belong together and to make the user interface more consistent.

Two new functions have been added: "decode_day" and "decode_month".
They take the name of a day or month as their argument and return
its number.

The function "day_of_week" has been changed. It now returns values
in the range 1..7 (as opposed to 0..6 previously). This is to make
things more consistent and to make the function "decode_day" work
exactly as "decode_month" (which was already present in previous
versions but was not exported, btw).

Since the table "day_name_tab" has been changed accordingly, you
probably won't need to change existing code.

Two more functions are new: "date_time_difference" and "calc_new_date_time".
They allow to calculate differences in dates and new dates which include not
only year, month and day, but also hour, minute, and second. They are exten-
sions of the functions "dates_difference" and "calc_new_date" (which they
also use).

A utility has been added to the package ("parse_date.pl") which allows
you to parse dates as returned by the UNIX "date" command. You can also
parse the date of submitment of mails this way. This allows you to deter-
mine the time the mail took to arrive, or you can automatically increase
the priority of problem reports as time passes by, for instance. (This
latter tool can be obtained by sending me a mail to <sb@sdm.de>.)

The german man-page is gone, it is too much effort to maintain two
versions of the man-page. Sorry.

What's new in version 2.1:
--------------------------

The man page is no separate file anymore, it is now included in the
file DateCalc.pm in POD format, where it will automatically be found
and installed in your "man" directory by "make install".


Preliminary steps for use with Perl prior to version 5.002:
-----------------------------------------------------------

Edit the file "Makefile.PL" in this package and the change the line
    'VERSION_FROM'	=> 'DateCalc.pm',
to
    'VERSION'		=> '2.2',

Then edit the file "DateCalc.pm" and change the line
    bootstrap Date::DateCalc $VERSION;
to
    bootstrap Date::DateCalc;

Finally, edit the file "DateCalc.xs" and delete the line
    PROTOTYPES: DISABLE


How to install it:
------------------

Please unpack and build this package OUTSIDE the Perl source and distribution
tree!!

 1) Change directory to the directory that has been created by unpacking this
    package ("DateCalc-2.2").

 2) Type "perl Makefile.PL" (or whatever the name and path of your Perl 5
    binary is).

    This will create a "Makefile" with the appropriate parameters for your
    system (for instance, where the install directories are, and so on).

 3) Type "make".

    This will create a dynamically linkable library file that will be linked
    to Perl later, at runtime, provided your system supports dynamic linking.

    Please refer to the MakeMaker documentation for instructions on how
    to build a new Perl with statically linked libraries (invoke "perldoc
    ExtUtils::MakeMaker" for this), if your system DOESN'T support dynamic
    linking!

    (Note, however, that I didn't test this since my system does support
    dynamic linking.)

    Should you encounter any compiler warnings or errors (like the redefini-
    tion of certain types already defined by your system), please contact
    me by mail at <sb@sdm.de>, sending me your compiler output (both STDOUT
    and STDERR). Thank you!

    ======================================================================
    Be aware that you need a C compiler which supports ANSI C in order to
    successfully compile this package!
    ======================================================================

    Also note that problems may arise with the c89 compiler of HP, although
    it allegedly supports ANSI C!

    I recommend the GNU gcc compiler, which is available for free on the
    Internet.

    (HP users are strongly recommended to install the GNU assembler GAS
    first before installing GNU gcc)

    Should you get the error messages

    DateCalc.c: 15: Unable to find include file 'EXTERN.h'.
    DateCalc.c: 16: Unable to find include file 'perl.h'.
    DateCalc.c: 17: Unable to find include file 'XSUB.h'.

    then edit the file Makefile.PL and change the line

    'INC'	=> '',     # e.g., '-I/opt/pkg/perl5.002/dist' 

    in such a way that it points to your Perl 5 distribution tree, e.g.,

    'INC'       => '-I/usr/ctr/dlt/private/perl/perl5.002',

    or the like, and start over with the generation of the Makefile at 2).

 4) Now issue "make test".

    The output should look somewhat like this:

    PERL_DL_NONLAZY=1 /opt/bin/perl -I./blib/arch -I./blib/lib
    -I/opt/lib/perl5.002/ sun4-sunos/5.002 -I/opt/lib/perl5.002
    -e 'use Test::Harness qw(&runtests $verbose); $verbose=0;
    runtests @ARGV;' t/*.t
    t/f000..............ok
    t/f001..............ok
    t/f002..............ok
    t/f003..............ok
    t/f004..............ok
    t/f005..............ok
    t/f006..............ok
    t/f007..............ok
    t/f008..............ok
    t/f009..............ok
    t/f010..............ok
    t/f011..............ok
    t/f012..............ok
    t/f013..............ok
    t/f014..............ok
    t/f015..............ok
    t/f016..............ok
    t/f017..............ok
    t/f018..............ok
    t/f019..............ok
    t/f020..............ok
    t/f021..............ok
    t/f022..............ok
    t/f023..............ok
    t/f024..............ok
    t/f025..............ok
    All tests successful.
    Files=26,  Tests=299,  8 secs ( 4.05 cusr  2.02 csys =  6.07 cpu)

 5) At last, type "make install".
        
 6) Now you can try to run the "demo". Start it with "perl demo" (or what-
    ever the name and path of your Perl 5 binary is).

    It will ask you for your birthday and the current date and calculate your
    age in days. You may enter the dates in almost any format, provided that
    you enter them in the order day - month - year. You may also use an (up
    to 3 letters) abbreviation for the month. You might try "03-Jan-1964",
    for example. Experiment!

    "demo_us" is (in principle) the same program as "demo", but it expects
    dates in U.S. american format in the order month - day - year. Moreover,
    the decoding is done entirely in Perl, whereas "demo" uses the package's
    C function "decode_date".

    Finally, the program "demo2" lets you find out about, for instance,
    the second thursday of a given month and year.

    The program takes four numeric arguments: n for the n-th day (1..5),
    the day of week (1=Monday..7=Sunday), the month (1..12) and the year
    (1..*):

    > perl demo2 2 4 4 1996
    The 2nd Thursday in April 1996 is Thursday, 11 April 1996

    > perl demo2 4 1 4 1996
    The 4th Monday in April 1996 is Monday, 22 April 1996

    > perl demo2 5 1 4 1996
    The 5th Monday in April 1996 is Monday, 29 April 1996

    > perl demo2 5 3 4 1996
    The 5th Wednesday in April 1996 is <no date>

    > cal 4 1996
       April 1996
     S  M Tu  W Th  F  S
        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


 7) Enjoy!


Version history:
----------------

Version 1.0 was the initial release (released as an article in the news-
groups comp.lang.perl.misc and de.comp.lang.perl).

Version 1.01 tried to fix some "violations" of programming standards for
Perl extension modules I wasn't aware of. (Everything was very new to me!)

Version 1.1 supplied a much more elaborate set of test scripts which are
run and evaluated automatically by Test::Harness when "make test" is
issued, testing every single function in this package very thoroughly.

This version also tried to fix the problem with the redefinition of the
types "uint", "ulong" etc. that arose on some systems which define these
types themselves, by renaming them to "unint", "unlong" and so forth.

Version 1.2a was another attempt to solve the problem of the predefined
types by renaming them to some more unusual (and hence less probably
already defined) names. (See the file 'lib_defs.h' for details)

(Other developers beware: The type names "uint", "u_int" and "unint" (and
the like) are all taken! Do NOT use these names for your own types!)

It also "fixed" what I thought was a possible problem in the DateCalc.xs
file where the name of the stack pointer for argument and return value
passing seems to be "SP" and not "sp" (used in the EXTEND(sp,num) macro).

After carefully re-reading the PERLAPI manual, I found out that "SP" and
"sp" are "global" and "local" stack pointers, respectively. So the above
"fix" in version 1.2a is reversed in version 1.2b.

Since version 1.2a (where the "a" stands for "alpha", BTW) seems to have
succeeded in fixing the system "typedef"s problem, I am re-releasing it
(with only marginal corrections (like the one above, for example) and some
small refinements of the documentation) as version 1.2b ("b" for "beta").

From version 1.3 on, the C library "lib_date.c" is compiled separately; it is
no longer '#include'd in the XS file. Moreover, the function "days_in_month"
was added.

Version 1.4 fixed a bug in DateCalc.xs where the function newSVnv(double)
was used instead of newSViv(IV) although an integer value is passed to it.

Version 1.5 introduced a notice that you need a compiler capable of
processing ANSI C in order to successfully compile this module, and
contained a second demo for decoding dates in U.S. american format.

Version 1.6 was tested with Perl 5.002 for compatibility (positive)
and a third demo was added which shows how to calculate, for instance,
the 2nd Thursday of a given month and year. This version has never been
published on the Internet, however.

Version 2.0 offered new features, such as date/time calculations and a
few other new functions. The german man page was dropped because the
expense of maintaining two man pages is not bearable in the long run.
The functions "day_short_tab" and "month_short_tab" are gone, these
tables are not needed any longer internally. The functions "encode",
"decode", "valid_date" and "date_string" have been renamed to
"compress", "uncompress", "check_compressed" and "compressed_to_short",
respectively, to reflect the fact that they belong together and to
make the user interface more consistent. Moreover, the values returned
by the function "day_of_week" have been shifted by one, they now go
from 1 to 7 (previously from 0 to 6), to make things more consistent
and to make the function "decode_day" work exactly as "decode_month"
(which was already present in former versions but was not exported).
The function and table "day_name_tab" has been changed accordingly.
The two functions "date_time_difference" and "calc_new_date_time"
are new, they allow to calculate differences in dates and new dates
which include not only year, month and day, but also hour, minute,
and second. They are extensions of the functions "dates_difference"
and "calc_new_date" (which they also use).

Version 2.1 fixed a minor bug in lib_date.c:
wrong:    if ((*ss <= 60) and (*mm <= 60) and (*hh <= 24) and
right:    if ((*ss < 60) and (*mm < 60) and (*hh < 24) and
among other minor adjustments in orthography and style, plus
adaptations to conform with new Perl 5.002 module standards.

Version 2.2 fixes a bug concerning arrays as parameters: enabling
prototypes in DateCalc.xs caused

    ($year,$mm,$dd) = first_in_week(week_number($year,$mm,$dd));

to generate Perl compilation errors, because "week_number" passes
an array to "first_in_week". To circumvent this, you had to pass
arrays explicitly, element by element:

    @w = week_number($year,$mm,$dd);
    ($year,$mm,$dd) = first_in_week( $w[0], $w[1] );

With version 2.2, this workaround is obsolete.


Thanks:
-------

Many thanks to Andreas Koenig for his efforts as upload-manager for the
CPAN, his patience, and lots of very good advice and suggestions! Thank
you for doing such a tremendous (and very time-consuming) job!!

Also many thanks to David Jenkins for reviewing this README file and the
english man page.

Thanks to Jarkko Hietaniemi for suggesting the "days_in_month" function.

Many thanks to Christian <chrisi@vm.akh-wien.ac.at> for reporting the bug
fixed in version 1.4, which showed up on an HP E55 running HP-UX 10.01 and
Perl 5.001m with the c89 Ansi 89 compiler from HP.

Also many thanks to David Thompson <dlt@dewey.csun.edu> for reporting a
problem he encountered concerning the inclusion of the Perl distribution
("Unable to find include file ...") and for suggesting a solution for this
problem. (That's the most pleasant kind of problem report, of course! ;-) )

Many thanks to Tom Limoncelli <tal@plts.org> for raising the question of
how to calculate the 2nd Thursday of a given month and year!

Many thanks to Bart Robinson <lomew@cs.utah.edu> for suggesting the "all"
export option and the "decode_day" and "decode_month" functions.

Also many thanks to Ron Savage <Ron.Savage@datacraft.com.au> for suggesting
the incorporation of time calculations into this module. (Sorry that I
didn't include the handling of time zones, which can be taken care of
more easily by adding/subtracting the appropriate time value in an extra,
preliminary step!)

Many thanks to Jonathan Lemon <jlemon@americantv.com> for reporting
the bug (and how to fix it!) concerning arrays as parameters, fixed
in version 2.2!


Final note:
-----------

Please report any comments, problems, suggestions, findings, complaints,
questions, insights, compliments or donations ;-) and so on to:

sb@sdm.de (Steffen Beyer)

With kind regards,
--
Steffen Beyer
mailto:sb@sdm.de        |s  |d &|m  |  software design & management GmbH&Co.KG
phone: +49 89 63812-244 |   |   |   |  Thomas-Dehler-Str. 27
fax:   +49 89 63812-150 |   |   |   |  81737 Munich, Germany.
