home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Calc.pod < prev    next >
Encoding:
Text File  |  2002-09-29  |  91.0 KB  |  2,869 lines

  1.  
  2. =head1 NAME
  3.  
  4. Date::Calc - Gregorian calendar date calculations
  5.  
  6. =head1 MOTTO
  7.  
  8. Keep it small, fast and simple
  9.  
  10. =head1 PREFACE
  11.  
  12. This package consists of a C library and a Perl module (which uses
  13. the C library, internally) for all kinds of date calculations based
  14. on the Gregorian calendar (the one used in all western countries today),
  15. thereby complying with all relevant norms and standards: S<ISO/R 2015-1971>,
  16. S<DIN 1355> and, to some extent, S<ISO 8601> (where applicable).
  17.  
  18. (See also http://www.engelschall.com/u/sb/download/Date-Calc/DIN1355/
  19. for a scan of part of the "S<DIN 1355>" document (in German)).
  20.  
  21. The module of course handles year numbers of 2000 and above correctly
  22. ("Year 2000" or "Y2K" compliance) -- actually all year numbers from 1
  23. to the largest positive integer representable on your system (which
  24. is at least 32767) can be dealt with.
  25.  
  26. This is not true, however, for the import/export functions in this
  27. package which are an interface to the internal POSIX date and time
  28. functions of your system, which can only cover dates in the following
  29. ranges:
  30.  
  31.  01-Jan-1970 00:00:00 GMT .. 19-Jan-2038 03:14:07 GMT [Unix etc.]
  32.  01-Jan-1904 00:00:00 LT  .. 06-Feb-2040 06:28:15 LT  [MacOS Classic]
  33.  (LT = local time)
  34.  
  35. Note that this package projects the Gregorian calendar back until the
  36. year S<1 A.D.> -- even though the Gregorian calendar was only adopted
  37. in 1582, mostly by the Catholic European countries, in obedience to the
  38. corresponding decree of Pope S<Gregory XIII> in that year.
  39.  
  40. Some (mainly protestant) countries continued to use the Julian calendar
  41. (used until then) until as late as the beginning of the 20th century.
  42.  
  43. Finally, note that this package is not intended to do everything you could
  44. ever imagine automagically for you; it is rather intended to serve as a
  45. toolbox (in the best of UNIX spirit and traditions) which should, however,
  46. always get you where you want to go.
  47.  
  48. See the section "RECIPES" at the bottom of this document for solutions
  49. to common problems!
  50.  
  51. If nevertheless you can't figure out how to solve a particular problem,
  52. please let me know! (See e-mail address at the end of this document.)
  53.  
  54. =head1 SYNOPSIS
  55.  
  56.   use Date::Calc qw(
  57.       Days_in_Year
  58.       Days_in_Month
  59.       Weeks_in_Year
  60.       leap_year
  61.       check_date
  62.       check_time
  63.       check_business_date
  64.       Day_of_Year
  65.       Date_to_Days
  66.       Day_of_Week
  67.       Week_Number
  68.       Week_of_Year
  69.       Monday_of_Week
  70.       Nth_Weekday_of_Month_Year
  71.       Standard_to_Business
  72.       Business_to_Standard
  73.       Delta_Days
  74.       Delta_DHMS
  75.       Delta_YMD
  76.       Delta_YMDHMS
  77.       Normalize_DHMS
  78.       Add_Delta_Days
  79.       Add_Delta_DHMS
  80.       Add_Delta_YM
  81.       Add_Delta_YMD
  82.       Add_Delta_YMDHMS
  83.       System_Clock
  84.       Today
  85.       Now
  86.       Today_and_Now
  87.       This_Year
  88.       Gmtime
  89.       Localtime
  90.       Mktime
  91.       Timezone
  92.       Date_to_Time
  93.       Time_to_Date
  94.       Easter_Sunday
  95.       Decode_Month
  96.       Decode_Day_of_Week
  97.       Decode_Language
  98.       Decode_Date_EU
  99.       Decode_Date_US
  100.       Fixed_Window
  101.       Moving_Window
  102.       Compress
  103.       Uncompress
  104.       check_compressed
  105.       Compressed_to_Text
  106.       Date_to_Text
  107.       Date_to_Text_Long
  108.       English_Ordinal
  109.       Calendar
  110.       Month_to_Text
  111.       Day_of_Week_to_Text
  112.       Day_of_Week_Abbreviation
  113.       Language_to_Text
  114.       Language
  115.       Languages
  116.       Decode_Date_EU2
  117.       Decode_Date_US2
  118.       Parse_Date
  119.       ISO_LC
  120.       ISO_UC
  121.   );
  122.  
  123.   use Date::Calc qw(:all);
  124.  
  125.   Days_in_Year
  126.       $days = Days_in_Year($year,$month);
  127.  
  128.   Days_in_Month
  129.       $days = Days_in_Month($year,$month);
  130.  
  131.   Weeks_in_Year
  132.       $weeks = Weeks_in_Year($year);
  133.  
  134.   leap_year
  135.       if (leap_year($year))
  136.  
  137.   check_date
  138.       if (check_date($year,$month,$day))
  139.  
  140.   check_time
  141.       if (check_time($hour,$min,$sec))
  142.  
  143.   check_business_date
  144.       if (check_business_date($year,$week,$dow))
  145.  
  146.   Day_of_Year
  147.       $doy = Day_of_Year($year,$month,$day);
  148.  
  149.   Date_to_Days
  150.       $days = Date_to_Days($year,$month,$day);
  151.  
  152.   Day_of_Week
  153.       $dow = Day_of_Week($year,$month,$day);
  154.  
  155.   Week_Number
  156.       $week = Week_Number($year,$month,$day);          # DEPRECATED
  157.  
  158.   Week_of_Year
  159.       ($week,$year) = Week_of_Year($year,$month,$day); # RECOMMENDED
  160.       $week = Week_of_Year($year,$month,$day);         # DANGEROUS
  161.  
  162.   Monday_of_Week
  163.       ($year,$month,$day) = Monday_of_Week($week,$year);
  164.  
  165.   Nth_Weekday_of_Month_Year
  166.       if (($year,$month,$day) =
  167.       Nth_Weekday_of_Month_Year($year,$month,$dow,$n))
  168.  
  169.   Standard_to_Business
  170.       ($year,$week,$dow) =
  171.       Standard_to_Business($year,$month,$day);
  172.  
  173.   Business_to_Standard
  174.       ($year,$month,$day) =
  175.       Business_to_Standard($year,$week,$dow);
  176.  
  177.   Delta_Days
  178.       $Dd = Delta_Days($year1,$month1,$day1,
  179.                        $year2,$month2,$day2);
  180.  
  181.   Delta_DHMS
  182.       ($Dd,$Dh,$Dm,$Ds) =
  183.       Delta_DHMS($year1,$month1,$day1, $hour1,$min1,$sec1,
  184.                  $year2,$month2,$day2, $hour2,$min2,$sec2);
  185.  
  186.   Delta_YMD
  187.       ($Dy,$Dm,$Dd) =
  188.       Delta_YMD($year1,$month1,$day1,
  189.                 $year2,$month2,$day2);
  190.  
  191.   Delta_YMDHMS
  192.       ($D_y,$D_m,$D_d, $Dh,$Dm,$Ds) =
  193.       Delta_YMDHMS($year1,$month1,$day1, $hour1,$min1,$sec1,
  194.                    $year2,$month2,$day2, $hour2,$min2,$sec2);
  195.  
  196.   Normalize_DHMS
  197.       ($Dd,$Dh,$Dm,$Ds) =
  198.       Normalize_DHMS($Dd,$Dh,$Dm,$Ds);
  199.  
  200.   Add_Delta_Days
  201.       ($year,$month,$day) =
  202.       Add_Delta_Days($year,$month,$day,
  203.                      $Dd);
  204.  
  205.   Add_Delta_DHMS
  206.       ($year,$month,$day, $hour,$min,$sec) =
  207.       Add_Delta_DHMS($year,$month,$day, $hour,$min,$sec,
  208.                      $Dd,$Dh,$Dm,$Ds);
  209.  
  210.   Add_Delta_YM
  211.       ($year,$month,$day) =
  212.       Add_Delta_YM($year,$month,$day,
  213.                    $Dy,$Dm);
  214.  
  215.   Add_Delta_YMD
  216.       ($year,$month,$day) =
  217.       Add_Delta_YMD($year,$month,$day,
  218.                     $Dy,$Dm,$Dd);
  219.  
  220.   Add_Delta_YMDHMS
  221.       ($year,$month,$day, $hour,$min,$sec) =
  222.       Add_Delta_YMDHMS($year,$month,$day, $hour,$min,$sec,
  223.                        $D_y,$D_m,$D_d, $Dh,$Dm,$Ds);
  224.  
  225.   System_Clock
  226.       ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
  227.       System_Clock([$gmt]);
  228.  
  229.   Today
  230.       ($year,$month,$day) = Today([$gmt]);
  231.  
  232.   Now
  233.       ($hour,$min,$sec) = Now([$gmt]);
  234.  
  235.   Today_and_Now
  236.       ($year,$month,$day, $hour,$min,$sec) = Today_and_Now([$gmt]);
  237.  
  238.   This_Year
  239.       $year = This_Year([$gmt]);
  240.  
  241.   Gmtime
  242.       ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
  243.       Gmtime([time]);
  244.  
  245.   Localtime
  246.       ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
  247.       Localtime([time]);
  248.  
  249.   Mktime
  250.       $time = Mktime($year,$month,$day, $hour,$min,$sec);
  251.  
  252.   Timezone
  253.       ($D_y,$D_m,$D_d, $Dh,$Dm,$Ds, $dst) = Timezone([time]);
  254.  
  255.   Date_to_Time
  256.       $time = Date_to_Time($year,$month,$day, $hour,$min,$sec);
  257.  
  258.   Time_to_Date
  259.       ($year,$month,$day, $hour,$min,$sec) = Time_to_Date([time]);
  260.  
  261.   Easter_Sunday
  262.       ($year,$month,$day) = Easter_Sunday($year);
  263.  
  264.   Decode_Month
  265.       if ($month = Decode_Month($string))
  266.  
  267.   Decode_Day_of_Week
  268.       if ($dow = Decode_Day_of_Week($string))
  269.  
  270.   Decode_Language
  271.       if ($lang = Decode_Language($string))
  272.  
  273.   Decode_Date_EU
  274.       if (($year,$month,$day) = Decode_Date_EU($string))
  275.  
  276.   Decode_Date_US
  277.       if (($year,$month,$day) = Decode_Date_US($string))
  278.  
  279.   Fixed_Window
  280.       $year = Fixed_Window($yy);
  281.  
  282.   Moving_Window
  283.       $year = Moving_Window($yy);
  284.  
  285.   Compress
  286.       $date = Compress($year,$month,$day);
  287.  
  288.   Uncompress
  289.       if (($century,$year,$month,$day) = Uncompress($date))
  290.  
  291.   check_compressed
  292.       if (check_compressed($date))
  293.  
  294.   Compressed_to_Text
  295.       $string = Compressed_to_Text($date);
  296.  
  297.   Date_to_Text
  298.       $string = Date_to_Text($year,$month,$day);
  299.  
  300.   Date_to_Text_Long
  301.       $string = Date_to_Text_Long($year,$month,$day);
  302.  
  303.   English_Ordinal
  304.       $string = English_Ordinal($number);
  305.  
  306.   Calendar
  307.       $string = Calendar($year,$month[,$orthodox]);
  308.  
  309.   Month_to_Text
  310.       $string = Month_to_Text($month);
  311.  
  312.   Day_of_Week_to_Text
  313.       $string = Day_of_Week_to_Text($dow);
  314.  
  315.   Day_of_Week_Abbreviation
  316.       $string = Day_of_Week_Abbreviation($dow);
  317.  
  318.   Language_to_Text
  319.       $string = Language_to_Text($lang);
  320.  
  321.   Language
  322.       $lang = Language();
  323.       Language($lang);
  324.       $oldlang = Language($newlang);
  325.  
  326.   Languages
  327.       $max_lang = Languages();
  328.  
  329.   Decode_Date_EU2
  330.       if (($year,$month,$day) = Decode_Date_EU2($string))
  331.  
  332.   Decode_Date_US2
  333.       if (($year,$month,$day) = Decode_Date_US2($string))
  334.  
  335.   Parse_Date
  336.       if (($year,$month,$day) = Parse_Date($string))
  337.  
  338.   ISO_LC
  339.       $lower = ISO_LC($string);
  340.  
  341.   ISO_UC
  342.       $upper = ISO_UC($string);
  343.  
  344.   Version
  345.       $string = Date::Calc::Version();
  346.  
  347. =head1 IMPORTANT NOTES
  348.  
  349. (See the section "RECIPES" at the bottom of this document for
  350. solutions to common problems!)
  351.  
  352. =over 2
  353.  
  354. =item *
  355.  
  356. "Year 2000" ("Y2K") compliance
  357.  
  358. The upper limit for any year number in this module is only given
  359. by the size of the largest positive integer that can be represented
  360. in a variable of the C type "int" on your system, which is at least
  361. 32767, according to the ANSI C standard (exceptions see below).
  362.  
  363. In order to simplify calculations, this module projects the gregorian
  364. calendar back until the year S<1 A.D.> -- i.e., back B<BEYOND> the
  365. year 1582 when this calendar was first decreed by the Catholic Pope
  366. S<Gregory XIII>!
  367.  
  368. Therefore, B<BE SURE TO ALWAYS SPECIFY "1998" WHEN YOU MEAN "1998">,
  369. for instance, and B<DO NOT WRITE "98" INSTEAD>, because this will
  370. in fact perform a calculation based on the year "98" A.D. and
  371. B<NOT> "1998"!
  372.  
  373. An exception from this rule are the functions which contain the
  374. word "compress" in their names (which can only handle years between
  375. 1970 and 2069 and also accept the abbreviations "00" to "99"), and
  376. the functions whose names begin with "Decode_Date_" (which translate
  377. year numbers below 100 using a technique known as "moving window").
  378.  
  379. If you want to convert a two-digit year number into a full-fledged,
  380. four-digit (at least for some years to come C<;-)>) year number,
  381. use the two functions "Fixed_Window()" and "Moving_Window()"
  382. (see their description further below).
  383.  
  384. Note also that the following import/export functions (which are
  385. interfaces to the POSIX functions "time()", "gmtime()", "localtime()"
  386. and "mktime()" or (the last two) substitutes for the BSD function
  387. "timegm()" and the POSIX function "gmtime()") have a very limited
  388. range of representable dates (in contrast to all other functions
  389. in this package, which cover virtually any date including and
  390. after S<January 1st 1 A.D.>):
  391.  
  392.               System_Clock()
  393.               Today()
  394.               Now()
  395.               Today_and_Now()
  396.               This_Year()
  397.               Gmtime()
  398.               Localtime()
  399.               Mktime()
  400.               Timezone()
  401.               Date_to_Time()
  402.               Time_to_Date()
  403.  
  404. These functions can only deal with dates in the range from
  405. S<01-Jan-1970 00:00:00 GMT> to S<19-Jan-2038 03:14:07 GMT>
  406. (the latter limit is only authoritative on S<32 bit> systems,
  407. however, and can (in principle, through a few code changes)
  408. be extended somewhat C<:-)> on S<64 bit> systems).
  409.  
  410. On MacOS Classic, the valid range of dates is between
  411. (both included) S<01-Jan-1904 00:00:00> (local time)
  412. to S<06-Feb-2040 06:28:15> (local time).
  413.  
  414. Note further that the function "Easter_Sunday()" can only
  415. be used for years in the range 1583 to 2299.
  416.  
  417. =item *
  418.  
  419. First index
  420.  
  421. B<ALL> ranges in this module start with "C<1>", B<NOT> "C<0>"!
  422.  
  423. I.e., the day of month, day of week, day of year, month of year,
  424. week of year, first valid year number and language B<ALL> start
  425. counting at one, B<NOT> zero!
  426.  
  427. The only exception is the function "C<Week_Number()>", which may
  428. in fact return "C<0>" when the given date actually lies in the
  429. last week of the B<PREVIOUS> year, and of course the numbers for
  430. hours (C<0..23>), minutes (C<0..59>) and seconds (C<0..59>).
  431.  
  432. =item *
  433.  
  434. Function naming conventions
  435.  
  436. Function names completely in lower case indicate a boolean return value.
  437.  
  438. =item *
  439.  
  440. Boolean values
  441.  
  442. Boolean values in this module are always a numeric zero ("C<0>") for
  443. "false" and a numeric one ("C<1>") for "true".
  444.  
  445. =item *
  446.  
  447. Exception handling
  448.  
  449. The functions in this module will usually die with a corresponding error
  450. message if their input parameters, intermediate results or output values
  451. are out of range.
  452.  
  453. The following functions handle errors differently:
  454.  
  455.   -  check_date()
  456.   -  check_time()
  457.   -  check_business_date()
  458.   -  check_compressed()
  459.  
  460. (which return a "false" return value when the given input does not represent
  461. a valid date or time),
  462.  
  463.   -  Nth_Weekday_of_Month_Year()
  464.  
  465. (which returns an empty list if the requested 5th day of week does not exist),
  466.  
  467.   -  Decode_Month()
  468.   -  Decode_Day_of_Week()
  469.   -  Decode_Language()
  470.   -  Fixed_Window()
  471.   -  Moving_Window()
  472.   -  Compress()
  473.  
  474. (which return "C<0>" upon failure or invalid input), and
  475.  
  476.   -  Decode_Date_EU()
  477.   -  Decode_Date_US()
  478.   -  Decode_Date_EU2()
  479.   -  Decode_Date_US2()
  480.   -  Parse_Date()
  481.   -  Uncompress()
  482.  
  483. (which return an empty list upon failure or invalid input).
  484.  
  485. Note that you can always catch an exception thrown by any of the functions
  486. in this module and handle it yourself by enclosing the function call in an
  487. "C<eval>" with curly brackets and checking the special variable "C<$@>"
  488. (see L<perlfunc(1)/eval> for details).
  489.  
  490. =back
  491.  
  492. =head1 DESCRIPTION
  493.  
  494. =over 2
  495.  
  496. =item *
  497.  
  498. C<use Date::Calc qw( Days_in_Year Days_in_Month ... );>
  499.  
  500. =item *
  501.  
  502. C<use Date::Calc qw(:all);>
  503.  
  504. You can either specify the functions you want to import explicitly by
  505. enumerating them between the parentheses of the "C<qw()>" operator, or
  506. you can use the "C<:all>" tag instead to import B<ALL> available functions.
  507.  
  508. =item *
  509.  
  510. C<$days = Days_in_Year($year,$month);>
  511.  
  512. This function returns the sum of the number of days in the months starting
  513. with January up to and including "C<$month>" in the given year "C<$year>".
  514.  
  515. I.e., "C<Days_in_Year(1998,1)>" returns "C<31>", "C<Days_in_Year(1998,2)>"
  516. returns "C<59>", "C<Days_in_Year(1998,3)>" returns "C<90>", and so on.
  517.  
  518. Note that "C<Days_in_Year($year,12)>" returns the number of days in the
  519. given year "C<$year>", i.e., either "C<365>" or "C<366>".
  520.  
  521. =item *
  522.  
  523. C<$days = Days_in_Month($year,$month);>
  524.  
  525. This function returns the number of days in the given month "C<$month>" of
  526. the given year "C<$year>".
  527.  
  528. The year must always be supplied, even though it is only needed when the
  529. month is February, in order to determine whether it is a leap year or not.
  530.  
  531. I.e., "C<Days_in_Month(1998,1)>" returns "C<31>", "C<Days_in_Month(1998,2)>"
  532. returns "C<28>", "C<Days_in_Month(2000,2)>" returns "C<29>",
  533. "C<Days_in_Month(1998,3)>" returns "C<31>", and so on.
  534.  
  535. =item *
  536.  
  537. C<$weeks = Weeks_in_Year($year);>
  538.  
  539. This function returns the number of weeks in the given year "C<$year>",
  540. i.e., either "C<52>" or "C<53>".
  541.  
  542. =item *
  543.  
  544. C<if (leap_year($year))>
  545.  
  546. This function returns "true" ("C<1>") if the given year "C<$year>" is
  547. a leap year and "false" ("C<0>") otherwise.
  548.  
  549. =item *
  550.  
  551. C<if (check_date($year,$month,$day))>
  552.  
  553. This function returns "true" ("C<1>") if the given three numerical
  554. values "C<$year>", "C<$month>" and "C<$day>" constitute a valid date,
  555. and "false" ("C<0>") otherwise.
  556.  
  557. =item *
  558.  
  559. C<if (check_time($hour,$min,$sec))>
  560.  
  561. This function returns "true" ("C<1>") if the given three numerical
  562. values "C<$hour>", "C<$min>" and "C<$sec>" constitute a valid time
  563. (C<0 E<lt>= $hour E<lt> 24>, C<0 E<lt>= $min E<lt> 60> and
  564. C<0 E<lt>= $sec E<lt> 60>), and "false" ("C<0>") otherwise.
  565.  
  566. =item *
  567.  
  568. C<if (check_business_date($year,$week,$dow))>
  569.  
  570. This function returns "true" ("C<1>") if the given three numerical
  571. values "C<$year>", "C<$week>" and "C<$dow>" constitute a valid date
  572. in business format, and "false" ("C<0>") otherwise.
  573.  
  574. B<Beware> that this function does B<NOT> compute whether a given date
  575. is a business day (i.e., Monday to Friday)!
  576.  
  577. To do so, use "C<(Day_of_Week($year,$month,$day) E<lt> 6)>" instead.
  578.  
  579. =item *
  580.  
  581. C<$doy = Day_of_Year($year,$month,$day);>
  582.  
  583. This function returns the (relative) number of the day of the given date
  584. in the given year.
  585.  
  586. E.g., "C<Day_of_Year($year,1,1)>" returns "C<1>",
  587. "C<Day_of_Year($year,2,1)>" returns "C<32>", and
  588. "C<Day_of_Year($year,12,31)>" returns either "C<365>" or "C<366>".
  589.  
  590. =item *
  591.  
  592. C<$days = Date_to_Days($year,$month,$day);>
  593.  
  594. This function returns the (absolute) number of the day of the given date,
  595. where counting starts at the 1st of January of the year S<1 A.D.>
  596.  
  597. I.e., "C<Date_to_Days(1,1,1)>" returns "C<1>", "C<Date_to_Days(1,12,31)>"
  598. returns "C<365>", "C<Date_to_Days(2,1,1)>" returns "C<366>",
  599. "C<Date_to_Days(1998,5,1)>" returns "C<729510>", and so on.
  600.  
  601. This is sometimes also referred to (not quite correctly) as the Julian
  602. date (or day). This may cause confusion, because also the number of the
  603. day in a year (from 1 to 365 or 366) is frequently called the "Julian date".
  604.  
  605. In fact the calendar that was used B<BEFORE> the Gregorian calendar
  606. was the Julian calendar - named after famous Julius Caesar, who had
  607. instituted it in Roman times. The Julian calendar was less precise
  608. because it had too many leap years compared to the true mean length
  609. of a year, and because rulers often changed it arbitrarily, in order
  610. to lengthen their own reign, for instance.
  611.  
  612. In order to convert the number returned by this function back into
  613. a date, use the function "C<Add_Delta_Days()>" (described further
  614. below), as follows:
  615.  
  616.   $days = Date_to_Days($year,$month,$day);
  617.   ($year,$month,$day) = Add_Delta_Days(1,1,1, $days - 1);
  618.  
  619. =item *
  620.  
  621. C<$dow = Day_of_Week($year,$month,$day);>
  622.  
  623. This function returns the number of the day of week of the given date.
  624.  
  625. The function returns "C<1>" for Monday, "C<2>" for Tuesday and so on
  626. until "C<7>" for Sunday.
  627.  
  628. Note that in the Hebrew calendar (on which the Christian calendar is based),
  629. the week starts with Sunday and ends with the Sabbath or Saturday (where
  630. according to the Genesis (as described in the Bible) the Lord rested from
  631. creating the world).
  632.  
  633. In medieval times, Catholic Popes have decreed the Sunday to be the official
  634. day of rest, in order to dissociate the Christian from the Hebrew belief.
  635.  
  636. Nowadays, the Sunday B<AND> the Saturday are commonly considered (and
  637. used as) days of rest, usually referred to as the "week-end".
  638.  
  639. Consistent with this practice, current norms and standards (such as
  640. S<ISO/R 2015-1971>, S<DIN 1355> and S<ISO 8601>) define the Monday
  641. as the first day of the week.
  642.  
  643. =item *
  644.  
  645. C<$week = Week_Number($year,$month,$day);>
  646.  
  647. This function returns the number of the week the given date lies in.
  648.  
  649. If the given date lies in the B<LAST> week of the B<PREVIOUS> year,
  650. "C<0>" is returned.
  651.  
  652. If the given date lies in the B<FIRST> week of the B<NEXT> year,
  653. "C<Weeks_in_Year($year) + 1>" is returned.
  654.  
  655. =item *
  656.  
  657. C<($week,$year) = Week_of_Year($year,$month,$day);>
  658.  
  659. This function returns the number of the week the given date lies in,
  660. as well as the year that week belongs to.
  661.  
  662. I.e., if the given date lies in the B<LAST> week of the B<PREVIOUS> year,
  663. "C<(Weeks_in_Year($year-1), $year-1)>" is returned.
  664.  
  665. If the given date lies in the B<FIRST> week of the B<NEXT> year,
  666. "C<(1, $year+1)>" is returned.
  667.  
  668. Otherwise, "C<(Week_Number($year,$month,$day), $year)>" is returned.
  669.  
  670. =item *
  671.  
  672. C<$week = Week_of_Year($year,$month,$day);>
  673.  
  674. In scalar context, this function returns just the week number. This
  675. allows you to write "C<$week = Week_of_Year($year,$month,$day);>"
  676. instead of "C<($week) = Week_of_Year($year,$month,$day);>" (note
  677. the parentheses around "C<$week>").
  678.  
  679. If the given date lies in the B<LAST> week of the B<PREVIOUS> year,
  680. "C<Weeks_in_Year($year-1)>" is returned.
  681.  
  682. If the given date lies in the B<FIRST> week of the B<NEXT> year,
  683. "C<1>" is returned.
  684.  
  685. Otherwise the return value is identical with that of
  686. "C<Week_Number($year,$month,$day)>".
  687.  
  688. B<BEWARE> that using this function in scalar context is a B<DANGEROUS>
  689. feature, because without knowing which year the week belongs to, you
  690. might inadvertently assume the wrong one!
  691.  
  692. If for instance you are iterating through an interval of dates, you might
  693. assume that the week always belongs to the same year as the given date,
  694. which unfortunately is B<WRONG> in some cases!
  695.  
  696. In many years, the 31st of December for instance belongs to week number
  697. one of the B<FOLLOWING> year. Assuming that the year is the same as your
  698. date (31st of December, in this example), sends you back to the first week
  699. of the B<CURRENT> year - the Monday of which, by the way, in case of bad
  700. luck, might actually lie in the year B<BEFORE> the current year!
  701.  
  702. This actually happens in 2002, for example.
  703.  
  704. So you always need to provide the correct corresponding year number
  705. by other means, keeping track of it yourself.
  706.  
  707. In case you do not understand this, never mind, but then simply
  708. B<DO NOT USE> this function in scalar context!
  709.  
  710. =item *
  711.  
  712. C<($year,$month,$day) = Monday_of_Week($week,$year);>
  713.  
  714. This function returns the date of the first day of the given week, i.e.,
  715. the Monday.
  716.  
  717. "C<$year>" must be greater than or equal to "C<1>", and "C<$week>" must
  718. lie in the range "C<1>" to "C<Weeks_in_Year($year)>".
  719.  
  720. Note that you can write
  721. "C<($year,$month,$day) = Monday_of_Week(Week_of_Year($year,$month,$day));>"
  722. in order to calculate the date of the Monday of the same week as the
  723. given date.
  724.  
  725. If you want to calculate any other day of week in the same week as a
  726. given date, use
  727.  
  728.   @date = Add_Delta_Days(Monday_of_Week(Week_of_Year(@date)),$offset);
  729.  
  730. where C<$offset = 1> for Tuesday, C<2> for Wednesday etc.
  731.  
  732. =item *
  733.  
  734. C<if (($year,$month,$day) = Nth_Weekday_of_Month_Year($year,$month,$dow,$n))>
  735.  
  736. This function calculates the date of the "C<$n>"th day of week "C<$dow>"
  737. in the given month "C<$month>" and year "C<$year>"; such as, for example,
  738. the 3rd Thursday of a given month and year.
  739.  
  740. This can be used to send a notification mail to the members of a group
  741. which meets regularly on every 3rd Thursday of a month, for instance.
  742.  
  743. (See the section "RECIPES" near the end of this document for a code
  744. snippet to actually do so.)
  745.  
  746. "C<$year>" must be greater than or equal to "C<1>", "C<$month>" must lie
  747. in the range "C<1>" to "C<12>", "C<$dow>" must lie in the range "C<1>"
  748. to "C<7>" and "C<$n>" must lie in the range "C<1>" to "C<5>", or a fatal
  749. error (with appropriate error message) occurs.
  750.  
  751. The function returns an empty list when the 5th of a given day of week
  752. does not exist in the given month and year.
  753.  
  754. =item *
  755.  
  756. C<($year,$week,$dow) = Standard_to_Business($year,$month,$day);>
  757.  
  758. This function converts a given date from standard notation (year,
  759. month, day (of month)) to business notation (year, week, day of week).
  760.  
  761. =item *
  762.  
  763. C<($year,$month,$day) = Business_to_Standard($year,$week,$dow);>
  764.  
  765. This function converts a given date from business notation (year,
  766. week, day of week) to standard notation (year, month, day (of month)).
  767.  
  768. =item *
  769.  
  770. C<$Dd = Delta_Days($year1,$month1,$day1, $year2,$month2,$day2);>
  771.  
  772. This function returns the difference in days between the two given
  773. dates.
  774.  
  775. The result is positive if the two dates are in chronological order,
  776. i.e., if date #1 comes chronologically B<BEFORE> date #2, and negative
  777. if the order of the two dates is reversed.
  778.  
  779. The result is zero if the two dates are identical.
  780.  
  781. =item *
  782.  
  783. C<($Dd,$Dh,$Dm,$Ds) = Delta_DHMS($year1,$month1,$day1, $hour1,$min1,$sec1, $year2,$month2,$day2, $hour2,$min2,$sec2);>
  784.  
  785. This function returns the difference in days, hours, minutes and seconds
  786. between the two given dates with times.
  787.  
  788. All four return values will be positive if the two dates are in chronological
  789. order, i.e., if date #1 comes chronologically B<BEFORE> date #2, and negative
  790. (in all four return values!) if the order of the two dates is reversed.
  791.  
  792. This is so that the two functions "C<Delta_DHMS()>" and "C<Add_Delta_DHMS()>"
  793. (description see further below) are complementary, i.e., mutually inverse:
  794.  
  795.   Add_Delta_DHMS(@date1,@time1, Delta_DHMS(@date1,@time1, @date2,@time2))
  796.  
  797. yields "C<(@date2,@time2)>" again, whereas
  798.  
  799.   Add_Delta_DHMS(@date2,@time2,
  800.       map(-$_, Delta_DHMS(@date1,@time1, @date2,@time2)))
  801.  
  802. yields "C<(@date1,@time1)>", and
  803.  
  804.   Delta_DHMS(@date1,@time1, Add_Delta_DHMS(@date1,@time1, @delta))
  805.  
  806. yields "C<@delta>" again.
  807.  
  808. The result is zero (in all four return values) if the two dates and times
  809. are identical.
  810.  
  811. =item *
  812.  
  813. C<($Dy,$Dm,$Dd) = Delta_YMD($year1,$month1,$day1, $year2,$month2,$day2);>
  814.  
  815. This function returns the vector
  816.  
  817.     ( $year2 - $year1, $month2 - $month1, $day2 - $day1 )
  818.  
  819. An error occurs if any of the two dates is invalid.
  820.  
  821. =item *
  822.  
  823. C<($D_y,$D_m,$D_d, $Dh,$Dm,$Ds) = Delta_YMDHMS($year1,$month1,$day1, $hour1,$min1,$sec1, $year2,$month2,$day2, $hour2,$min2,$sec2);>
  824.  
  825. This function is based on the function "Delta_YMD()" above but additionally
  826. calculates the time difference. When a carry over from the time difference
  827. occurs, the value of "C<$D_d>" is adjusted accordingly, thus giving the
  828. correct total date/time difference.
  829.  
  830. Arguments are expected to be in chronological order to yield a (usually)
  831. positive result.
  832.  
  833. In any case, adding the result of this function to the first date/time value
  834. (C<$year1,$month1,$day1,> C<$hour1,$min1,$sec1>) always gives the second
  835. date/time value (C<$year2,$month2,$day2,> C<$hour2,$min2,$sec2>) again,
  836. and adding the negative result (all elements of the result vector negated)
  837. to the second date/time value gives the first date/time value.
  838.  
  839. See the function "Add_Delta_YMDHMS()" further below for adding a date/time
  840. value and a date/time difference.
  841.  
  842. An error occurs if any of the two date/time values is invalid.
  843.  
  844. =item *
  845.  
  846. C<($Dd,$Dh,$Dm,$Ds) = Normalize_DHMS($Dd,$Dh,$Dm,$Ds);>
  847.  
  848. This function takes four arbitrary values for days, hours, minutes
  849. and seconds (which may have different signs) and renormalizes them
  850. so that the values for hours, minutes and seconds will lie in the
  851. ranges C<[-23..23]>, C<[-59..59]> and C<[-59..59]>, respectively,
  852. and so that all four values have the same sign (or are zero).
  853.  
  854. The given values are left untouched, i.e., unchanged.
  855.  
  856. =item *
  857.  
  858. C<($year,$month,$day) = Add_Delta_Days($year,$month,$day, $Dd);>
  859.  
  860. This function has two principal uses:
  861.  
  862. First, it can be used to calculate a new date, given an initial date and
  863. an offset (which may be positive or negative) in days, in order to answer
  864. questions like "today plus 90 days -- which date gives that?".
  865.  
  866. (In order to add a weeks offset, simply multiply the weeks offset with
  867. "C<7>" and use that as your days offset.)
  868.  
  869. Second, it can be used to convert the canonical representation of a date,
  870. i.e., the number of that day (where counting starts at the 1st of January
  871. in S<1 A.D.>), back into a date given as year, month and day.
  872.  
  873. Because counting starts at "C<1>", you will actually have to subtract "C<1>"
  874. from the canonical date in order to get back the original date:
  875.  
  876.   $canonical = Date_to_Days($year,$month,$day);
  877.  
  878.   ($year,$month,$day) = Add_Delta_Days(1,1,1, $canonical - 1);
  879.  
  880. Moreover, this function is the inverse of the function "C<Delta_Days()>":
  881.  
  882.   Add_Delta_Days(@date1, Delta_Days(@date1, @date2))
  883.  
  884. yields "C<@date2>" again, whereas
  885.  
  886.   Add_Delta_Days(@date2, -Delta_Days(@date1, @date2))
  887.  
  888. yields "C<@date1>", and
  889.  
  890.   Delta_Days(@date1, Add_Delta_Days(@date1, $delta))
  891.  
  892. yields "C<$delta>" again.
  893.  
  894. =item *
  895.  
  896. C<($year,$month,$day, $hour,$min,$sec) = Add_Delta_DHMS($year,$month,$day, $hour,$min,$sec, $Dd,$Dh,$Dm,$Ds);>
  897.  
  898. This function serves to add a days, hours, minutes and seconds offset to a
  899. given date and time, in order to answer questions like "today and now plus
  900. 7 days but minus 5 hours and then plus 30 minutes, what date and time gives
  901. that?":
  902.  
  903.   ($y,$m,$d,$H,$M,$S) = Add_Delta_DHMS(Today_and_Now(), +7,-5,+30,0);
  904.  
  905. =item *
  906.  
  907. C<($year,$month,$day) = Add_Delta_YM($year,$month,$day, $Dy,$Dm);>
  908.  
  909. This function can be used to add a year and/or month offset to a given
  910. date.
  911.  
  912. In contrast to the function described immediately below
  913. ("C<Add_Delta_YMD()>"), this function does no "wrapping" into
  914. the next month if the day happens to lie outside the valid range
  915. for the resulting year and month (after adding the year and month
  916. offsets). Instead, it simply truncates the day to the last possible
  917. day of the resulting month.
  918.  
  919. Examples:
  920.  
  921. Adding an offset of 0 years, 1 month to the date (1999,1,31) would result
  922. in the (invalid) date (1999,2,31). The function replaces this result by
  923. the (valid) date (1999,2,28).
  924.  
  925. Adding an offset of 1 year, 1 month to the same date (1999,1,31) as above
  926. would result in the (still invalid) date (2000,2,31). The function replaces
  927. this result by the valid date (2000,2,29) (because 2000 is a leap year).
  928.  
  929. Note that the year and month offsets can be negative, and that they can
  930. have different signs.
  931.  
  932. If you want to additionally add a days offset, use the function
  933. "C<Add_Delta_Days()>" before or after calling "C<Add_Delta_YM()>":
  934.  
  935.   @date2 = Add_Delta_Days( Add_Delta_YM(@date1, $Dy,$Dm), $Dd );
  936.   @date2 = Add_Delta_YM( Add_Delta_Days(@date1, $Dd), $Dy,$Dm );
  937.  
  938. Note that your result may depend on the order in which you call
  939. these two functions!
  940.  
  941. Consider the date (1999,2,28) and the offsets 0 years, 1 month
  942. and 1 day:
  943.  
  944. (1999,2,28) plus one month is (1999,3,28), plus one day is
  945. (1999,3,29). (1999,2,28) plus one day is (1999,3,1), plus
  946. one month is (1999,4,1).
  947.  
  948. (Which is also the reason why the "C<Add_Delta_YM()>" function
  949. does not allow to add a days offset, because this would actually
  950. require TWO functions: One for adding the days offset BEFORE and
  951. one for adding it AFTER applying the year/month offsets.)
  952.  
  953. An error occurs if the initial date is not valid.
  954.  
  955. Note that "C<Add_Delta_YM( Add_Delta_YM(@date, $Dy,$Dm), -$Dy,-$Dm );>"
  956. will not, in general, return the original date "C<@date>" (consider
  957. the examples given above!).
  958.  
  959. =item *
  960.  
  961. C<($year,$month,$day) = Add_Delta_YMD($year,$month,$day, $Dy,$Dm,$Dd);>
  962.  
  963. This function serves to add a years, months and days offset to a given date.
  964.  
  965. (In order to add a weeks offset, simply multiply the weeks offset with "C<7>"
  966. and add this number to your days offset.)
  967.  
  968. Note that the three offsets for years, months and days are applied
  969. independently from each other. This also allows them to have
  970. different signs.
  971.  
  972. The years and months offsets are applied first, and the days offset
  973. is applied last.
  974.  
  975. If the resulting date happens to fall on a day after the end of the
  976. resulting month, like the 32nd of April or the 30th of February, then
  977. the date is simply counted forward into the next month (possibly also
  978. into the next year) by the number of excessive days (e.g., the 32nd of
  979. April will become the 2nd of May).
  980.  
  981. B<BEWARE> that this behaviour differs from that of previous versions
  982. of this module! In previous versions, the day was simply truncated to
  983. the maximum number of days in the resulting month.
  984.  
  985. If you want the previous behaviour, use the new function "C<Add_Delta_YM()>"
  986. (described immediately above) plus the function "C<Add_Delta_Days()>"
  987. instead.
  988.  
  989. B<BEWARE> also that because a year and a month offset is not equivalent
  990. to a fixed number of days, the transformation performed by this function
  991. is B<NOT ALWAYS REVERSIBLE>!
  992.  
  993. This is in contrast to the functions "C<Add_Delta_Days()>" and
  994. "C<Add_Delta_DHMS()>", which are fully and truly reversible (with
  995. the help of the functions "C<Delta_Days()>" and "C<Delta_DHMS()>",
  996. for instance).
  997.  
  998. Note that for this same reason,
  999.  
  1000.   @date = Add_Delta_YMD(
  1001.           Add_Delta_YMD(@date, $Dy,$Dm,$Dd), -$Dy,-$Dm,-$Dd);
  1002.  
  1003. will in general B<NOT> return the initial date "C<@date>".
  1004.  
  1005. Note that this is B<NOT> a program bug but B<NECESSARILY> so
  1006. because of the variable lengths of years and months!
  1007.  
  1008. =item *
  1009.  
  1010. C<($year,$month,$day, $hour,$min,$sec) = Add_Delta_YMDHMS($year,$month,$day, $hour,$min,$sec, $D_y,$D_m,$D_d, $Dh,$Dm,$Ds);>
  1011.  
  1012. Same as the function above, except that a time offset may be given in
  1013. addition to the year, month and day offset.
  1014.  
  1015. =item *
  1016.  
  1017. C<($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) = System_Clock([$gmt]);>
  1018.  
  1019. If your operating system supports the corresponding system calls
  1020. ("C<time()>" and "C<localtime()>" or "C<gmtime()>"), this function
  1021. will return the information provided by your system clock, i.e.,
  1022. the current date and time, the number of the day of year, the number
  1023. of the day of week and a flag signaling whether daylight savings time
  1024. is currently in effect or not.
  1025.  
  1026. The ranges of values returned (and their meanings) are as follows:
  1027.  
  1028.         $year   :   1970..2038 (or more)  [Unix etc.]
  1029.         $year   :   1904..2040            [MacOS Classic]
  1030.  
  1031.         $month  :   1..12
  1032.         $day    :   1..31
  1033.         $hour   :   0..23
  1034.         $min    :   0..59
  1035.         $sec    :   0..59    (0..61 on some systems)
  1036.         $doy    :   1..366
  1037.         $dow    :   1..7
  1038.         $dst    :  -1..1
  1039.  
  1040. "C<$doy>" is the day of year, sometimes also referred to as the
  1041. "julian date", which starts at "C<1>" and goes up to the number
  1042. of days in that year.
  1043.  
  1044. The day of week ("C<$dow>") will be "C<1>" for Monday, "C<2>" for
  1045. Tuesday and so on until "C<7>" for Sunday.
  1046.  
  1047. The daylight savings time flag ("C<$dst>") will be "C<-1>" if this
  1048. information is not available on your system, "C<0>" for no daylight
  1049. savings time (i.e., winter time) and "C<1>" when daylight savings
  1050. time is in effect.
  1051.  
  1052. If your operating system does not provide the necessary system calls,
  1053. calling this function will result in a fatal "not available on this
  1054. system" error message.
  1055.  
  1056. If you want to handle this exception yourself, use "C<eval>" as follows:
  1057.  
  1058.   eval { ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
  1059.     System_Clock(); };
  1060.  
  1061.   if ($@)
  1062.   {
  1063.       # Handle missing system clock
  1064.       # (For instance, ask user to enter this information manually)
  1065.   }
  1066.  
  1067. Note that curlies ("{" and "}") are used here to delimit the statement to
  1068. be "eval"ed (which is the way to catch exceptions in Perl), and not quotes
  1069. (which is a way to evaluate Perl expressions at runtime).
  1070.  
  1071. If the optional (boolean) input parameter "C<$gmt>" is given, a "true"
  1072. value ("C<1>") will cause "C<gmtime()>" to be used instead of "C<localtime()>",
  1073. internally, thus returning Greenwich Mean Time (GMT, or UTC) instead of
  1074. local time.
  1075.  
  1076. =item *
  1077.  
  1078. C<($year,$month,$day) = Today([$gmt]);>
  1079.  
  1080. This function returns a subset of the values returned by the function
  1081. "C<System_Clock()>" (see above for details), namely the current year,
  1082. month and day.
  1083.  
  1084. A fatal "not available on this system" error message will appear if the
  1085. corresponding system calls are not supported by your current operating
  1086. system.
  1087.  
  1088. If the optional (boolean) input parameter "C<$gmt>" is given, a "true"
  1089. value ("C<1>") will cause "C<gmtime()>" to be used instead of "C<localtime()>",
  1090. internally, thus returning Greenwich Mean Time (GMT, or UTC) instead of
  1091. local time.
  1092.  
  1093. =item *
  1094.  
  1095. C<($hour,$min,$sec) = Now([$gmt]);>
  1096.  
  1097. This function returns a subset of the values returned by the function
  1098. "C<System_Clock()>" (see above for details), namely the current time
  1099. (hours, minutes and full seconds).
  1100.  
  1101. A fatal "not available on this system" error message will appear if the
  1102. corresponding system calls are not supported by your current operating
  1103. system.
  1104.  
  1105. If the optional (boolean) input parameter "C<$gmt>" is given, a "true"
  1106. value ("C<1>") will cause "C<gmtime()>" to be used instead of "C<localtime()>",
  1107. internally, thus returning Greenwich Mean Time (GMT, or UTC) instead of
  1108. local time.
  1109.  
  1110. =item *
  1111.  
  1112. C<($year,$month,$day, $hour,$min,$sec) = Today_and_Now([$gmt]);>
  1113.  
  1114. This function returns a subset of the values returned by the function
  1115. "C<System_Clock()>" (see above for details), namely the current date
  1116. (year, month, day) and time (hours, minutes and full seconds).
  1117.  
  1118. A fatal "not available on this system" error message will appear if the
  1119. corresponding system calls are not supported by your current operating
  1120. system.
  1121.  
  1122. If the optional (boolean) input parameter "C<$gmt>" is given, a "true"
  1123. value ("C<1>") will cause "C<gmtime()>" to be used instead of "C<localtime()>",
  1124. internally, thus returning Greenwich Mean Time (GMT, or UTC) instead of
  1125. local time.
  1126.  
  1127. =item *
  1128.  
  1129. C<$year = This_Year([$gmt]);>
  1130.  
  1131. This function returns the current year, according to local time.
  1132.  
  1133. A fatal "not available on this system" error message will appear if the
  1134. corresponding system calls are not supported by your current operating
  1135. system.
  1136.  
  1137. If the optional (boolean) input parameter "C<$gmt>" is given, a "true"
  1138. value ("C<1>") will cause "C<gmtime()>" to be used instead of "C<localtime()>",
  1139. internally, thus returning Greenwich Mean Time (GMT, or UTC) instead of
  1140. local time. However, this will only make a difference within a few hours
  1141. around New Year (unless you are on a Pacific island, where this can
  1142. be almost 24 hours).
  1143.  
  1144. =item *
  1145.  
  1146. C<($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) = Gmtime([time]);>
  1147.  
  1148. This is Date::Calc's equivalent of Perl's built-in "gmtime()" function.
  1149. See also L<perlfunc/gmtime>.
  1150.  
  1151. The ranges of values returned (and their meanings) are as follows:
  1152.  
  1153.         $year   :   1970..2038 (or more)  [Unix etc.]
  1154.         $year   :   1904..2040            [MacOS Classic]
  1155.  
  1156.         $month  :   1..12
  1157.         $day    :   1..31
  1158.         $hour   :   0..23
  1159.         $min    :   0..59
  1160.         $sec    :   0..59
  1161.         $doy    :   1..366
  1162.         $dow    :   1..7
  1163.         $dst    :  -1..1
  1164.  
  1165. "C<$doy>" is the day of year, sometimes also referred to as the
  1166. "julian date", which starts at "C<1>" and goes up to the number
  1167. of days in that year.
  1168.  
  1169. The day of week ("C<$dow>") will be "C<1>" for Monday, "C<2>" for
  1170. Tuesday and so on until "C<7>" for Sunday.
  1171.  
  1172. The daylight savings time flag ("C<$dst>") will be "C<-1>" if this
  1173. information is not available on your system, "C<0>" for no daylight
  1174. savings time (i.e., winter time) and "C<1>" when daylight savings
  1175. time is in effect.
  1176.  
  1177. A fatal "time out of range" error will occur if the given time value
  1178. is out of range C<[0..(~0E<gt>E<gt>1)]>.
  1179.  
  1180. If the time value is omitted, the "time()" function is called instead,
  1181. internally.
  1182.  
  1183. =item *
  1184.  
  1185. C<($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) = Localtime([time]);>
  1186.  
  1187. This is Date::Calc's equivalent of Perl's built-in "localtime()" function.
  1188. See also L<perlfunc/localtime>.
  1189.  
  1190. The ranges of values returned (and their meanings) are as follows:
  1191.  
  1192.         $year   :   1970..2038 (or more)  [Unix etc.]
  1193.         $year   :   1904..2040            [MacOS Classic]
  1194.  
  1195.         $month  :   1..12
  1196.         $day    :   1..31
  1197.         $hour   :   0..23
  1198.         $min    :   0..59
  1199.         $sec    :   0..59
  1200.         $doy    :   1..366
  1201.         $dow    :   1..7
  1202.         $dst    :  -1..1
  1203.  
  1204. "C<$doy>" is the day of year, sometimes also referred to as the
  1205. "julian date", which starts at "C<1>" and goes up to the number
  1206. of days in that year.
  1207.  
  1208. The day of week ("C<$dow>") will be "C<1>" for Monday, "C<2>" for
  1209. Tuesday and so on until "C<7>" for Sunday.
  1210.  
  1211. The daylight savings time flag ("C<$dst>") will be "C<-1>" if this
  1212. information is not available on your system, "C<0>" for no daylight
  1213. savings time (i.e., winter time) and "C<1>" when daylight savings
  1214. time is in effect.
  1215.  
  1216. A fatal "time out of range" error will occur if the given time value is
  1217. out of range C<[0..(~0E<gt>E<gt>1)]>.
  1218.  
  1219. If the time value is omitted, the "time()" function is called instead,
  1220. internally.
  1221.  
  1222. =item *
  1223.  
  1224. C<$time = Mktime($year,$month,$day, $hour,$min,$sec);>
  1225.  
  1226. This function converts a date into a time value, i.e., into the number
  1227. of seconds since whatever moment in time your system considers to be
  1228. the "epoch". On Unix and most other systems this is the number of seconds
  1229. since January 1st 1970 at midnight (GMT). On MacOS Classic this is the
  1230. number of seconds since January 1st 1904 at midnight (local time).
  1231.  
  1232. The function is similar to the "POSIX::mktime()" function (see L<POSIX/mktime>
  1233. for more details), but in contrast to the latter, it expects dates in the
  1234. usual ranges used throughout this module: The year 2001 stays year 2001,
  1235. and months are numbered from 1 to 12.
  1236.  
  1237. A fatal "date out of range" error will occur if the given date cannot
  1238. be expressed in terms of seconds since the epoch (this happens for
  1239. instance when the date lies before the epoch, or if it is later than
  1240. S<19-Jan-2038 03:14:07 GMT> on S<32 bit> Unix systems, or later than
  1241. S<06-Feb-2040 06:28:15> (local time) on a Macintosh with MacOS Classic).
  1242.  
  1243. Just like the "POSIX::mktime()" function, this function uses the
  1244. "mktime()" system call, internally.
  1245.  
  1246. This means that the given date and time is considered to be in local time,
  1247. and that the value returned by this function will depend on your machine's
  1248. local settings such as the time zone, whether daylight savings time is
  1249. (or was, at the time) in effect, and the system clock itself.
  1250.  
  1251. B<BEWARE> that "mktime()" does not always return the same time value
  1252. as fed into "localtime()", when you feed the output of "localtime()"
  1253. back into "mktime()", on some systems!
  1254.  
  1255. I.e., "C<Mktime((Localtime($time))[0..5])>" will not always return
  1256. the same value as given in "C<$time>"!
  1257.  
  1258. =item *
  1259.  
  1260. C<($D_y,$D_m,$D_d, $Dh,$Dm,$Ds, $dst) = Timezone([time]);>
  1261.  
  1262. This function returns the difference between "C<localtime(time)>" and
  1263. "C<gmtime(time)>", which is the timezone offset in effect for the current
  1264. location and the given "C<time>".
  1265.  
  1266. This offset is positive if you are located to the east of Greenwich,
  1267. and is usually negative (except during daylight savings time, in some
  1268. locations) if you are located to the west of Greenwich.
  1269.  
  1270. Note that this offset is influenced by all of the relevant system
  1271. settings and parameters on your machine; such as locales, environment
  1272. variables (e.g. "C<TZ>") and the system clock itself. See the
  1273. relevant documentation on your system for more details.
  1274.  
  1275. If the "C<time>" is omitted, the "C<time()>" function will
  1276. be called automatically, internally (similar to the built-in
  1277. functions "C<localtime()>" and "C<gmtime()>" in Perl).
  1278.  
  1279. A fatal "time out of range" error will occur if the given time value
  1280. is out of range C<[0..(~0E<gt>E<gt>1)]>.
  1281.  
  1282. The last item of the returned list is a flag which indicates whether
  1283. daylight savings time is currently in effect. This flag is negative
  1284. (-1) if this information is not available on your system. It is zero
  1285. (0) when daylight savings time is off, and positive (+1) when daylight
  1286. savings time is on.
  1287.  
  1288. Thus you can check very quickly whether daylight savings time is
  1289. currently in effect by evaluating this function in scalar context
  1290. (in scalar context, Perl returns the last item of a list):
  1291.  
  1292.   if (scalar Timezone > 0) { # yes, daylight savings time
  1293.  
  1294. However, a slightly more efficient way would be this:
  1295.  
  1296.   if (scalar System_Clock > 0) { # yes, daylight savings time
  1297.  
  1298. =item *
  1299.  
  1300. C<$time = Date_to_Time($year,$month,$day, $hour,$min,$sec);>
  1301.  
  1302. This function is a replacement for the BSD function "timegm()"
  1303. (which is not available on all Unix systems), which converts
  1304. a given date and time into a time value, i.e., into the number
  1305. of seconds since whatever moment in time your system considers to be
  1306. the "epoch". On Unix and most other systems this is the number of seconds
  1307. since January 1st 1970 at midnight (GMT). On MacOS Classic this is the
  1308. number of seconds since January 1st 1904 at midnight (local time).
  1309.  
  1310. Under Unix, the date and time are considered to be in UTC
  1311. ("Universal Time Coordinated", and so is the resulting time value.
  1312.  
  1313. UTC is almost the same as GMT (or "Greenwich Mean Time"), except
  1314. that UTC has leap seconds (in order to account for small variations
  1315. in the rotation of the earth, for instance), whereas GMT does not.
  1316.  
  1317. Under MacOS Classic, however, both input and output are
  1318. considered to be in local time.
  1319.  
  1320. The ranges of year and month follow the same rules as throughout
  1321. the rest of this module (and not the contorted rules of its Unix
  1322. equivalent), i.e., the year "2001" stays "2001" and the month
  1323. ranges from 1 to 12.
  1324.  
  1325. A fatal "date out of range" error will occur if the given date cannot
  1326. be expressed in terms of seconds since the epoch (this happens for
  1327. instance when the date lies before the epoch, or if it is later than
  1328. S<19-Jan-2038 03:14:07 GMT> on S<32 bit> Unix systems, or later than
  1329. S<06-Feb-2040 06:28:15> (local time) on a Macintosh with MacOS Classic).
  1330.  
  1331. This function should be very fast, because it is implemented in
  1332. a very straightforward manner and doesn't use any internal system
  1333. calls.
  1334.  
  1335. Moreover, the functions "Date_to_Time()" and "Time_to_Date()"
  1336. are guaranteed to be complementary, i.e., that
  1337. "C<Date_to_Time(Time_to_Date($time))>" and
  1338. "C<Time_to_Date(Date_to_Time($year,$month,$day, $hour,$min,$sec))>"
  1339. will always return the initial values.
  1340.  
  1341. =item *
  1342.  
  1343. C<($year,$month,$day, $hour,$min,$sec) = Time_to_Date([time]);>
  1344.  
  1345. This function is an alternative to the POSIX "gmtime()" function
  1346. (and its built-in Perl equivalent), which converts a given time
  1347. value into the corresponding date and time. The given time value
  1348. must be the number of seconds since whatever moment in time your
  1349. system considers to be the "epoch". On Unix and most other systems
  1350. this is the number of seconds since January 1st 1970 at midnight
  1351. (GMT). On MacOS Classic this is the number of seconds since
  1352. January 1st 1904 at midnight (local time).
  1353.  
  1354. Under Unix, the given time value is considered to be in UTC
  1355. ("Universal Time Coordinated", and so is the resulting date
  1356. and time.
  1357.  
  1358. UTC is almost the same as GMT (or "Greenwich Mean Time"), except
  1359. that UTC has leap seconds (in order to account for small variations
  1360. in the rotation of the earth, for instance), whereas GMT does not.
  1361.  
  1362. Under MacOS Classic, however, both input and output
  1363. are considered to be in local time.
  1364.  
  1365. If the input value "C<time>" is omitted, the "C<time()>" function
  1366. will be called automatically, internally (similar to the built-in
  1367. functions "C<localtime()>" and "C<gmtime()>" in Perl).
  1368.  
  1369. A fatal "time out of range" error will occur if the given time
  1370. value is negative.
  1371.  
  1372. This function should be very fast, because it is implemented in
  1373. a very straightforward manner and doesn't use any internal system
  1374. calls (except for "time()", if the input value is omitted).
  1375.  
  1376. Moreover, the functions "Date_to_Time()" and "Time_to_Date()"
  1377. are guaranteed to be complementary, i.e., that
  1378. "C<Date_to_Time(Time_to_Date($time))>" and
  1379. "C<Time_to_Date(Date_to_Time($year,$month,$day, $hour,$min,$sec))>"
  1380. will always return the initial values.
  1381.  
  1382. =item *
  1383.  
  1384. C<($year,$month,$day) = Easter_Sunday($year);>
  1385.  
  1386. This function calculates the date of Easter Sunday for all years in the
  1387. range from 1583 to 2299 (all other year numbers will result in a fatal
  1388. "year out of range" error message) using the method known as the "Gaussian
  1389. Rule".
  1390.  
  1391. Some related christian feast days which depend on the date of Easter Sunday:
  1392.  
  1393.   Carnival Monday / Rosenmontag / Veille du Mardi Gras   =  -48 days
  1394.   Mardi Gras / Karnevalsdienstag / Mardi Gras            =  -47 days
  1395.   Ash Wednesday / Aschermittwoch / Mercredi des Cendres  =  -46 days
  1396.   Palm Sunday / Palmsonntag / Dimanche des Rameaux       =   -7 days
  1397.   Easter Friday / Karfreitag / Vendredi Saint            =   -2 days
  1398.   Easter Saturday / Ostersamstag / Samedi de Paques      =   -1 day
  1399.   Easter Monday / Ostermontag / Lundi de Paques          =   +1 day
  1400.   Ascension of Christ / Christi Himmelfahrt / Ascension  =  +39 days
  1401.   Whitsunday / Pfingstsonntag / Dimanche de Pentecote    =  +49 days
  1402.   Whitmonday / Pfingstmontag / Lundi de Pentecote        =  +50 days
  1403.   Feast of Corpus Christi / Fronleichnam / Fete-Dieu     =  +60 days
  1404.  
  1405. Use the offsets shown above to calculate the date of the corresponding
  1406. feast day as follows:
  1407.  
  1408.   ($year,$month,$day) = Add_Delta_Days(Easter_Sunday($year), $offset));
  1409.  
  1410. =item *
  1411.  
  1412. C<if ($month = Decode_Month($string))>
  1413.  
  1414. This function takes a string as its argument, which should contain the
  1415. name of a month B<IN THE CURRENTLY SELECTED LANGUAGE> (see further below
  1416. for details about the multi-language support of this package), or any uniquely
  1417. identifying abbreviation of a month's name (i.e., the first few letters),
  1418. and returns the corresponding number (1..12) upon a successful match, or
  1419. "C<0>" otherwise (therefore, the return value can also be used as the
  1420. conditional expression in an "if" statement).
  1421.  
  1422. Note that the input string may not contain any other characters which do not
  1423. pertain to the month's name, especially no leading or trailing whitespace.
  1424.  
  1425. Note also that matching is performed in a case-insensitive manner (this may
  1426. depend on the "locale" setting on your current system, though!)
  1427.  
  1428. With "English" as the currently selected language (which is the default),
  1429. the following examples will all return the value "C<9>":
  1430.  
  1431.   $month = Decode_Month("s");
  1432.   $month = Decode_Month("Sep");
  1433.   $month = Decode_Month("septemb");
  1434.   $month = Decode_Month("September");
  1435.  
  1436. =item *
  1437.  
  1438. C<if ($dow = Decode_Day_of_Week($string))>
  1439.  
  1440. This function takes a string as its argument, which should contain the
  1441. name of a day of week B<IN THE CURRENTLY SELECTED LANGUAGE> (see further
  1442. below for details about the multi-language support of this package), or any
  1443. uniquely identifying abbreviation of the name of a day of week (i.e., the
  1444. first few letters), and returns the corresponding number (1..7) upon a
  1445. successful match, or "C<0>" otherwise (therefore, the return value can
  1446. also be used as the conditional expression in an "if" statement).
  1447.  
  1448. Note that the input string may not contain any other characters which
  1449. do not pertain to the name of the day of week, especially no leading
  1450. or trailing whitespace.
  1451.  
  1452. Note also that matching is performed in a case-insensitive manner (this may
  1453. depend on the "locale" setting on your current system, though!)
  1454.  
  1455. With "English" as the currently selected language (which is the default),
  1456. the following examples will all return the value "C<3>":
  1457.  
  1458.   $dow = Decode_Day_of_Week("w");
  1459.   $dow = Decode_Day_of_Week("Wed");
  1460.   $dow = Decode_Day_of_Week("wednes");
  1461.   $dow = Decode_Day_of_Week("Wednesday");
  1462.  
  1463. =item *
  1464.  
  1465. C<if ($lang = Decode_Language($string))>
  1466.  
  1467. This function takes a string as its argument, which should contain the
  1468. name of one of the languages supported by this package (B<IN THIS VERY
  1469. LANGUAGE ITSELF>), or any uniquely identifying abbreviation of the name
  1470. of a language (i.e., the first few letters), and returns its corresponding
  1471. internal number (1..13 in the original distribution) upon a successful match,
  1472. or "C<0>" otherwise (therefore, the return value can also be used as the
  1473. conditional expression in an "if" statement).
  1474.  
  1475. Note that the input string may not contain any other characters which do
  1476. not pertain to the name of a language, especially no leading or trailing
  1477. whitespace.
  1478.  
  1479. Note also that matching is performed in a case-insensitive manner (this may
  1480. depend on the "locale" setting on your current system, though!)
  1481.  
  1482. The original distribution supports the following thirteen languages:
  1483.  
  1484.             English                    ==>    1    (default)
  1485.             Franτais    (French)       ==>    2
  1486.             Deutsch     (German)       ==>    3
  1487.             Espa±ol     (Spanish)      ==>    4
  1488.             PortuguΩs   (Portuguese)   ==>    5
  1489.             Nederlands  (Dutch)        ==>    6
  1490.             Italiano    (Italian)      ==>    7
  1491.             Norsk       (Norwegian)    ==>    8
  1492.             Svenska     (Swedish)      ==>    9
  1493.             Dansk       (Danish)       ==>   10
  1494.             suomi       (Finnish)      ==>   11
  1495.             Magyar      (Hungarian)    ==>   12
  1496.             Polski      (Polish)       ==>   13
  1497.  
  1498. See the section "How to install additional languages" in the file
  1499. "INSTALL.txt" in this distribution for how to add more languages
  1500. to this package.
  1501.  
  1502. In the original distribution (no other languages installed),
  1503. the following examples will all return the value "C<3>":
  1504.  
  1505.   $lang = Decode_Language("d");
  1506.   $lang = Decode_Language("de");
  1507.   $lang = Decode_Language("Deutsch");
  1508.  
  1509. Note that you may not be able to enter the special international characters
  1510. in some of the languages' names over the keyboard directly on some systems.
  1511.  
  1512. This should never be a problem, though; just enter an abbreviation of the
  1513. name of the language consisting of the first few letters up to the character
  1514. before the first special international character.
  1515.  
  1516. =item *
  1517.  
  1518. C<if (($year,$month,$day) = Decode_Date_EU($string))>
  1519.  
  1520. This function scans a given string and tries to parse any date
  1521. which might be embedded in it.
  1522.  
  1523. The function returns an empty list if it can't successfully
  1524. extract a valid date from its input string, or else it returns
  1525. the date found.
  1526.  
  1527. The function accepts almost any format, as long as the date is
  1528. given in the european order (hence its name) day-month-year.
  1529.  
  1530. Thereby, zero or more B<NON-NUMERIC> characters may B<PRECEDE>
  1531. the day and B<FOLLOW> the year.
  1532.  
  1533. Moreover, zero or more B<NON-ALPHANUMERIC> characters are permitted
  1534. B<BETWEEN> these three items (i.e., between day and month and between
  1535. month and year).
  1536.  
  1537. The month may be given either numerically (i.e., a number from "C<1>"
  1538. to "C<12>"), or alphanumerically, i.e., as the name of the month B<IN
  1539. THE CURRENTLY SELECTED LANGUAGE>, or any uniquely identifying abbreviation
  1540. thereof.
  1541.  
  1542. (See further below for details about the multi-language support of this
  1543. package!)
  1544.  
  1545. If the year is given as one or two digits only (i.e., if the year is less
  1546. than 100), it is mapped to a "window" of +/- 50 years around the current
  1547. year, as described by the "Moving_Window()" function (see further below).
  1548.  
  1549. If the day, month and year are all given numerically but B<WITHOUT> any
  1550. delimiting characters between them, this string of digits will be mapped
  1551. to the day, month and year as follows:
  1552.  
  1553.                 Length:        Mapping:
  1554.                   3              dmy
  1555.                   4              dmyy
  1556.                   5              dmmyy
  1557.                   6              ddmmyy
  1558.                   7              dmmyyyy
  1559.                   8              ddmmyyyy
  1560.  
  1561. (Where "d" stands for "day", "m" stands for "month" and "y" stands for
  1562. "year".)
  1563.  
  1564. All other strings consisting purely of digits (without any intervening
  1565. delimiters) are rejected, i.e., not recognized.
  1566.  
  1567. Examples:
  1568.  
  1569.   "3.1.64"
  1570.   "3 1 64"
  1571.   "03.01.64"
  1572.   "03/01/64"
  1573.   "3. Jan 1964"
  1574.   "Birthday: 3. Jan '64 in Backnang/Germany"
  1575.   "03-Jan-64"
  1576.   "3.Jan1964"
  1577.   "3Jan64"
  1578.   "030164"
  1579.   "3ja64"
  1580.   "3164"
  1581.  
  1582. Experiment! (See the corresponding example applications in the
  1583. "examples" subdirectory of this distribution in order to do so.)
  1584.  
  1585. =item *
  1586.  
  1587. C<if (($year,$month,$day) = Decode_Date_US($string))>
  1588.  
  1589. This function scans a given string and tries to parse any date
  1590. which might be embedded in it.
  1591.  
  1592. The function returns an empty list if it can't successfully
  1593. extract a valid date from its input string, or else it returns
  1594. the date found.
  1595.  
  1596. The function accepts almost any format, as long as the date is
  1597. given in the U.S. american order (hence its name) month-day-year.
  1598.  
  1599. Thereby, zero or more B<NON-ALPHANUMERIC> characters may B<PRECEDE>
  1600. and B<FOLLOW> the month (i.e., precede the month and separate it from
  1601. the day which follows behind).
  1602.  
  1603. Moreover, zero or more B<NON-NUMERIC> characters are permitted
  1604. B<BETWEEN> the day and the year, as well as B<AFTER> the year.
  1605.  
  1606. The month may be given either numerically (i.e., a number from "C<1>"
  1607. to "C<12>"), or alphanumerically, i.e., as the name of the month B<IN
  1608. THE CURRENTLY SELECTED LANGUAGE>, or any uniquely identifying abbreviation
  1609. thereof.
  1610.  
  1611. (See further below for details about the multi-language support of this
  1612. package!)
  1613.  
  1614. If the year is given as one or two digits only (i.e., if the year is less
  1615. than 100), it is mapped to a "window" of +/- 50 years around the current
  1616. year, as described by the "Moving_Window()" function (see further below).
  1617.  
  1618. If the month, day and year are all given numerically but B<WITHOUT> any
  1619. delimiting characters between them, this string of digits will be mapped
  1620. to the month, day and year as follows:
  1621.  
  1622.                 Length:        Mapping:
  1623.                   3              mdy
  1624.                   4              mdyy
  1625.                   5              mddyy
  1626.                   6              mmddyy
  1627.                   7              mddyyyy
  1628.                   8              mmddyyyy
  1629.  
  1630. (Where "m" stands for "month", "d" stands for "day" and "y" stands for
  1631. "year".)
  1632.  
  1633. All other strings consisting purely of digits (without any intervening
  1634. delimiters) are rejected, i.e., not recognized.
  1635.  
  1636. If only the day and the year form a contiguous string of digits, they
  1637. will be mapped as follows:
  1638.  
  1639.                 Length:        Mapping:
  1640.                   2              dy
  1641.                   3              dyy
  1642.                   4              ddyy
  1643.                   5              dyyyy
  1644.                   6              ddyyyy
  1645.  
  1646. (Where "d" stands for "day" and "y" stands for "year".)
  1647.  
  1648. Examples:
  1649.  
  1650.   "1 3 64"
  1651.   "01/03/64"
  1652.   "Jan 3 '64"
  1653.   "Jan 3 1964"
  1654.   "===> January 3rd 1964 (birthday)"
  1655.   "Jan31964"
  1656.   "Jan364"
  1657.   "ja364"
  1658.   "1364"
  1659.  
  1660. Experiment! (See the corresponding example applications in the
  1661. "examples" subdirectory of this distribution in order to do so.)
  1662.  
  1663. =item *
  1664.  
  1665. C<$year = Fixed_Window($yy);>
  1666.  
  1667. This function applies a "fixed window" strategy to two-digit year
  1668. numbers in order to convert them into four-digit year numbers.
  1669.  
  1670. All other year numbers are passed through unchanged, except for
  1671. negative year numbers, which cause the function to return zero
  1672. ("C<0>") instead.
  1673.  
  1674. Two-digit year numbers "C<yy>" below 70 are converted to "C<20yy>",
  1675. whereas year numbers equal to or greater than 70 (but less than 100)
  1676. are converted to "C<19yy>".
  1677.  
  1678. In the original distribution of this package, the base century is
  1679. set to "1900" and the base year to "70" (which is a standard on UNIX
  1680. systems), but these constants (also called the "epoch") can actually
  1681. be chosen at will (in the files "DateCalc.c" and "DateCalc.h") at
  1682. compile time of this module.
  1683.  
  1684. =item *
  1685.  
  1686. C<$year = Moving_Window($yy);>
  1687.  
  1688. This function applies a "moving window" strategy to two-digit year
  1689. numbers in order to convert them into four-digit year numbers, provided
  1690. the necessary system calls (system clock) are available. Otherwise the
  1691. function falls back to the "fixed window" strategy described in the
  1692. function above.
  1693.  
  1694. All other year numbers are passed through unchanged, except for
  1695. negative year numbers, which cause the function to return zero
  1696. ("C<0>") instead.
  1697.  
  1698. Two-digit year numbers are mapped according to a "window" of 50 years
  1699. in both directions (past and future) around the current year.
  1700.  
  1701. That is, two-digit year numbers are first mapped to the same century
  1702. as the current year. If the resulting year is smaller than the current
  1703. year minus 50, then one more century is added to the result. If the
  1704. resulting year is equal to or greater than the current year plus 50,
  1705. then a century is subtracted from the result.
  1706.  
  1707. =item *
  1708.  
  1709. C<$date = Compress($year,$month,$day);>
  1710.  
  1711. WARNING: This function is legacy code, its use is deprecated!
  1712.  
  1713. This function encodes a date in 16 bits, which is the value being returned.
  1714.  
  1715. The encoding scheme is as follows:
  1716.  
  1717.             Bit number:    FEDCBA9 8765 43210
  1718.             Contents:      yyyyyyy mmmm ddddd
  1719.  
  1720. (Where the "yyyyyyy" contain the number of the year, "mmmm" the number of
  1721. the month and "ddddd" the number of the day.)
  1722.  
  1723. The function returns "C<0>" if the given input values do not represent a
  1724. valid date. Therefore, the return value of this function can also be used
  1725. as the conditional expression in an "if" statement, in order to check
  1726. whether the given input values constitute a valid date).
  1727.  
  1728. Through this special encoding scheme, it is possible to B<COMPARE>
  1729. compressed dates for equality and order (less than/greater than)
  1730. B<WITHOUT> any previous B<DECODING>!
  1731.  
  1732. Note however that contiguous dates do B<NOT> necessarily have contiguous
  1733. compressed representations!
  1734.  
  1735. I.e., incrementing the compressed representation of a date B<MAY OR MAY NOT>
  1736. yield a valid new date!
  1737.  
  1738. Note also that this function can only handle dates within one century.
  1739.  
  1740. This century can be chosen at will (at compile time of this module)
  1741. by defining a base century and year (also called the "epoch"). In the
  1742. original distribution of this package, the base century is set to
  1743. "1900" and the base year to "70" (which is standard on UNIX systems).
  1744.  
  1745. This allows this function to handle dates from "1970" up to "2069".
  1746.  
  1747. If the given year is equal to, say, "95", this package will automatically
  1748. assume that you really meant "1995" instead. However, if you specify a year
  1749. number which is B<SMALLER> than 70, like "64", for instance, this package
  1750. will assume that you really meant "2064".
  1751.  
  1752. You are not confined to two-digit (abbreviated) year numbers, though.
  1753.  
  1754. The function also accepts "full-length" year numbers, provided that they
  1755. lie in the supported range (i.e., from "1970" to "2069", in the original
  1756. configuration of this package).
  1757.  
  1758. Note that this function is maintained mainly for backward compatibility,
  1759. and that its use is not recommended.
  1760.  
  1761. =item *
  1762.  
  1763. C<if (($century,$year,$month,$day) = Uncompress($date))>
  1764.  
  1765. WARNING: This function is legacy code, its use is deprecated!
  1766.  
  1767. This function decodes dates that were encoded previously using the function
  1768. "C<Compress()>".
  1769.  
  1770. It returns the century, year, month and day of the date encoded in "C<$date>"
  1771. if "C<$date>" represents a valid date, or an empty list otherwise.
  1772.  
  1773. The year returned in "C<$year>" is actually a two-digit year number
  1774. (i.e., the year number taken modulo 100), and only the expression
  1775. "C<$century + $year>" yields the "full-length" year number
  1776. (for example, C<1900 + 95 = 1995>).
  1777.  
  1778. Note that this function is maintained mainly for backward compatibility,
  1779. and that its use is not recommended.
  1780.  
  1781. =item *
  1782.  
  1783. C<if (check_compressed($date))>
  1784.  
  1785. WARNING: This function is legacy code, its use is deprecated!
  1786.  
  1787. This function returns "true" ("C<1>") if the given input value
  1788. constitutes a valid compressed date, and "false" ("C<0>") otherwise.
  1789.  
  1790. Note that this function is maintained mainly for backward compatibility,
  1791. and that its use is not recommended.
  1792.  
  1793. =item *
  1794.  
  1795. C<$string = Compressed_to_Text($date);>
  1796.  
  1797. WARNING: This function is legacy code, its use is deprecated!
  1798.  
  1799. This function returns a string of fixed length (always 9 characters long)
  1800. containing a textual representation of the compressed date encoded in
  1801. "C<$date>".
  1802.  
  1803. This string has the form "dd-Mmm-yy", where "dd" is the two-digit number
  1804. of the day, "Mmm" are the first three letters of the name of the month
  1805. in the currently selected language (see further below for details about
  1806. the multi-language support of this package), and "yy" is the two-digit
  1807. year number (i.e., the year number taken modulo 100).
  1808.  
  1809. If "C<$date>" does not represent a valid date, the string "??-???-??" is
  1810. returned instead.
  1811.  
  1812. Note that this function is maintained mainly for backward compatibility,
  1813. and that its use is not recommended.
  1814.  
  1815. =item *
  1816.  
  1817. C<$string = Date_to_Text($year,$month,$day);>
  1818.  
  1819. This function returns a string containing a textual representation of the
  1820. given date of the form "www dd-Mmm-yyyy", where "www" are the first three
  1821. letters of the name of the day of week in the currently selected language,
  1822. or a special abbreviation, if special abbreviations have been defined for
  1823. the currently selected language (see further below for details about the
  1824. multi-language support of this package), "dd" is the day (one or two digits),
  1825. "Mmm" are the first three letters of the name of the month in the currently
  1826. selected language, and "yyyy" is the number of the year in full length.
  1827.  
  1828. If the given input values do not constitute a valid date, a fatal "not a
  1829. valid date" error occurs.
  1830.  
  1831. (See the section "RECIPES" near the end of this document for a code snippet
  1832. for how to print dates in any format you like.)
  1833.  
  1834. =item *
  1835.  
  1836. C<$string = Date_to_Text_Long($year,$month,$day);>
  1837.  
  1838. This function returns a string containing a textual representation of the
  1839. given date roughly of the form "Wwwwww, dd Mmmmmm yyyy", where "Wwwwww"
  1840. is the name of the day of week in the currently selected language (see
  1841. further below for details about the multi-language support of this package),
  1842. "dd" is the day (one or two digits), "Mmmmmm" is the name of the month
  1843. in the currently selected language, and "yyyy" is the number of the year
  1844. in full length.
  1845.  
  1846. The exact format of the output string depends on the currently selected
  1847. language. In the original distribution of this package, these formats are
  1848. defined as follows:
  1849.  
  1850.   1  English    :  "Wwwwww, Mmmmmm ddth yyyy"
  1851.   2  French     :  "Wwwwww dd mmmmmm yyyy"
  1852.   3  German     :  "Wwwwww, den dd. Mmmmmm yyyy"
  1853.   4  Spanish    :  "Wwwwww, dd de mmmmmm de yyyy"
  1854.   5  Portuguese :  "Wwwwww, dia dd de mmmmmm de yyyy"
  1855.   6  Dutch      :  "Wwwwww, dd mmmmmm yyyy"
  1856.   7  Italian    :  "Wwwwww, dd Mmmmmm yyyy"
  1857.   8  Norwegian  :  "wwwwww, dd. mmmmmm yyyy"
  1858.   9  Swedish    :  "wwwwww, dd mmmmmm yyyy"
  1859.  10  Danish     :  "wwwwww, dd. mmmmmm yyyy"
  1860.  11  Finnish    :  "wwwwww, dd. mmmmmmta yyyy"
  1861.  12  Hungarian  :  "dd. Mmmmmm yyyy., wwwwww"
  1862.  13  Polish     :  "Wwwwww, dd Mmmmmm yyyy"
  1863.  
  1864. (You can change these formats in the file "DateCalc.c" before
  1865. building this module in order to suit your personal preferences.)
  1866.  
  1867. If the given input values do not constitute a valid date, a fatal
  1868. "not a valid date" error occurs.
  1869.  
  1870. In order to capitalize the day of week at the beginning of the string
  1871. in Norwegian, use "C<lcfirst(Date_to_Text_Long($year,$month,$day));>".
  1872.  
  1873. (See the section "RECIPES" near the end of this document for
  1874. an example on how to print dates in any format you like.)
  1875.  
  1876. =item *
  1877.  
  1878. C<$string = English_Ordinal($number);>
  1879.  
  1880. This function returns a string containing the (english) abbreviation
  1881. of the ordinal number for the given (cardinal) number "C<$number>".
  1882.  
  1883. I.e.,
  1884.  
  1885.     0  =>  '0th'    10  =>  '10th'    20  =>  '20th'
  1886.     1  =>  '1st'    11  =>  '11th'    21  =>  '21st'
  1887.     2  =>  '2nd'    12  =>  '12th'    22  =>  '22nd'
  1888.     3  =>  '3rd'    13  =>  '13th'    23  =>  '23rd'
  1889.     4  =>  '4th'    14  =>  '14th'    24  =>  '24th'
  1890.     5  =>  '5th'    15  =>  '15th'    25  =>  '25th'
  1891.     6  =>  '6th'    16  =>  '16th'    26  =>  '26th'
  1892.     7  =>  '7th'    17  =>  '17th'    27  =>  '27th'
  1893.     8  =>  '8th'    18  =>  '18th'    28  =>  '28th'
  1894.     9  =>  '9th'    19  =>  '19th'    29  =>  '29th'
  1895.  
  1896. etc.
  1897.  
  1898. =item *
  1899.  
  1900. C<$string = Calendar($year,$month[,$orthodox]);>
  1901.  
  1902. This function returns a calendar of the given month in the given year
  1903. (somewhat similar to the UNIX "C<cal>" command), B<IN THE CURRENTLY SELECTED
  1904. LANGUAGE> (see further below for details about the multi-language support
  1905. of this package).
  1906.  
  1907. Example:
  1908.  
  1909.   print Calendar(1998,5);
  1910.  
  1911. This will print:
  1912.  
  1913.            May 1998
  1914.   Mon Tue Wed Thu Fri Sat Sun
  1915.                     1   2   3
  1916.     4   5   6   7   8   9  10
  1917.    11  12  13  14  15  16  17
  1918.    18  19  20  21  22  23  24
  1919.    25  26  27  28  29  30  31
  1920.  
  1921. If the optional boolean parameter "C<$orthodox>" is given and true,
  1922. the calendar starts on Sunday instead of Monday.
  1923.  
  1924. =item *
  1925.  
  1926. C<$string = Month_to_Text($month);>
  1927.  
  1928. This function returns the name of the given month in the currently selected
  1929. language (see further below for details about the multi-language support of
  1930. this package).
  1931.  
  1932. If the given month lies outside of the valid range from "C<1>" to "C<12>",
  1933. a fatal "month out of range" error will occur.
  1934.  
  1935. =item *
  1936.  
  1937. C<$string = Day_of_Week_to_Text($dow);>
  1938.  
  1939. This function returns the name of the given day of week in the currently
  1940. selected language (see further below for details about the multi-language
  1941. support of this package).
  1942.  
  1943. If the given day of week lies outside of the valid range from "C<1>" to "C<7>",
  1944. a fatal "day of week out of range" error will occur.
  1945.  
  1946. =item *
  1947.  
  1948. C<$string = Day_of_Week_Abbreviation($dow);>
  1949.  
  1950. This function returns the special abbreviation of the name of the given
  1951. day of week, B<IF> such special abbreviations have been defined for the
  1952. currently selected language (see further below for details about the
  1953. multi-language support of this package).
  1954.  
  1955. (In the original distribution of this package, this is only true for
  1956. Portuguese.)
  1957.  
  1958. If not, the first three letters of the name of the day of week in the
  1959. currently selected language are returned instead.
  1960.  
  1961. If the given day of week lies outside of the valid range from "C<1>"
  1962. to "C<7>", a fatal "day of week out of range" error will occur.
  1963.  
  1964. Currently, this table of special abbreviations is only used by the
  1965. functions "C<Date_to_Text()>" and "C<Calendar()>", internally.
  1966.  
  1967. =item *
  1968.  
  1969. C<$string = Language_to_Text($lang);>
  1970.  
  1971. This function returns the name of any language supported by this package
  1972. when the internal number representing that language is given as input.
  1973.  
  1974. The original distribution supports the following thirteen languages:
  1975.  
  1976.             1   ==>   English                     (default)
  1977.             2   ==>   Franτais    (French)
  1978.             3   ==>   Deutsch     (German)
  1979.             4   ==>   Espa±ol     (Spanish)
  1980.             5   ==>   PortuguΩs   (Portuguese)
  1981.             6   ==>   Nederlands  (Dutch)
  1982.             7   ==>   Italiano    (Italian)
  1983.             8   ==>   Norsk       (Norwegian)
  1984.             9   ==>   Svenska     (Swedish)
  1985.            10   ==>   Dansk       (Danish)
  1986.            11   ==>   suomi       (Finnish)
  1987.            12   ==>   Magyar      (Hungarian)
  1988.            13   ==>   Polski      (Polish)
  1989.  
  1990. See the section "How to install additional languages" in the file
  1991. "INSTALL.txt" in this distribution for how to add more languages
  1992. to this package.
  1993.  
  1994. See the description of the function "C<Languages()>" further below
  1995. to determine how many languages are actually available in a given
  1996. installation of this package.
  1997.  
  1998. =item *
  1999.  
  2000. C<$lang = Language();>
  2001.  
  2002. =item *
  2003.  
  2004. C<Language($lang);>
  2005.  
  2006. =item *
  2007.  
  2008. C<$oldlang = Language($newlang);>
  2009.  
  2010. This function can be used to determine which language is currently selected,
  2011. and to change the selected language.
  2012.  
  2013. Thereby, each language has a unique internal number.
  2014.  
  2015. The original distribution contains the following thirteen languages:
  2016.  
  2017.             1   ==>   English                     (default)
  2018.             2   ==>   Franτais    (French)
  2019.             3   ==>   Deutsch     (German)
  2020.             4   ==>   Espa±ol     (Spanish)
  2021.             5   ==>   PortuguΩs   (Portuguese)
  2022.             6   ==>   Nederlands  (Dutch)
  2023.             7   ==>   Italiano    (Italian)
  2024.             8   ==>   Norsk       (Norwegian)
  2025.             9   ==>   Svenska     (Swedish)
  2026.            10   ==>   Dansk       (Danish)
  2027.            11   ==>   suomi       (Finnish)
  2028.            12   ==>   Magyar      (Hungarian)
  2029.            13   ==>   Polski      (Polish)
  2030.  
  2031. See the section "How to install additional languages" in the file
  2032. "INSTALL.txt" in this distribution for how to add more languages
  2033. to this package.
  2034.  
  2035. See the description of the function "C<Languages()>" further below
  2036. to determine how many languages are actually available in a given
  2037. installation of this package.
  2038.  
  2039. B<BEWARE> that in order for your programs to be portable, you should B<NEVER>
  2040. actually use the internal number of a language in this package B<EXPLICITLY>,
  2041. because the same number could mean different languages on different systems,
  2042. depending on what languages have been added to any given installation of this
  2043. package.
  2044.  
  2045. Therefore, you should always use a statement such as
  2046.  
  2047.   Language(Decode_Language("Name_of_Language"));
  2048.  
  2049. to select the desired language, and
  2050.  
  2051.   $language = Language_to_Text(Language());
  2052.  
  2053. or
  2054.  
  2055.   $old_language = Language_to_Text(Language("Name_of_new_Language"));
  2056.  
  2057. to determine the (previously) selected language.
  2058.  
  2059. If the so chosen language is not available in the current installation,
  2060. this will result in an appropriate error message, instead of silently
  2061. using the wrong (a random) language (which just happens to have the
  2062. same internal number in the other installation).
  2063.  
  2064. Note that in the current implementation of this package, the selected
  2065. language is a global setting valid for B<ALL> functions that use the names
  2066. of months, days of week or languages internally, valid for B<ALL PROCESSES>
  2067. using the same copy of the "Date::Calc" shared library in memory!
  2068.  
  2069. This may have surprising side-effects in a multi-user environment, and even
  2070. more so when Perl will be capable of multi-threading in some future release.
  2071.  
  2072. =item *
  2073.  
  2074. C<$max_lang = Languages();>
  2075.  
  2076. This function returns the (maximum) number of languages which are
  2077. currently available in your installation of this package.
  2078.  
  2079. (This may vary from installation to installation.)
  2080.  
  2081. See the section "How to install additional languages" in the file
  2082. "INSTALL.txt" in this distribution for how to add more languages
  2083. to this package.
  2084.  
  2085. In the original distribution of this package there are thirteen built-in
  2086. languages, therefore the value returned by this function will be "C<13>"
  2087. if no other languages have been added to your particular installation.
  2088.  
  2089. =item *
  2090.  
  2091. C<if (($year,$month,$day) = Decode_Date_EU2($string))>
  2092.  
  2093. This function is the Perl equivalent of the function "C<Decode_Date_EU()>"
  2094. (implemented in C), included here merely as an example to demonstrate how
  2095. easy it is to write your own routine in Perl (using regular expressions)
  2096. adapted to your own special needs, should the necessity arise, and intended
  2097. primarily as a basis for your own development.
  2098.  
  2099. In one particular case this Perl version is actually slightly more permissive
  2100. than its C equivalent, as far as the class of permitted intervening (i.e.,
  2101. delimiting) characters is concerned.
  2102.  
  2103. (Can you tell the subtle, almost insignificant difference by looking at
  2104. the code? Or by experimenting? Hint: Try the string "a3b1c64d" with both
  2105. functions.)
  2106.  
  2107. =item *
  2108.  
  2109. C<if (($year,$month,$day) = Decode_Date_US2($string))>
  2110.  
  2111. This function is the Perl equivalent of the function "C<Decode_Date_US()>"
  2112. (implemented in C), included here merely as an example to demonstrate how
  2113. easy it is to write your own routine in Perl (using regular expressions)
  2114. adapted to your own special needs, should the necessity arise, and intended
  2115. primarily as a basis for your own development.
  2116.  
  2117. In one particular case this Perl version is actually slightly more permissive
  2118. than its C equivalent.
  2119.  
  2120. (Hint: This is the same difference as with the "C<Decode_Date_EU()>" and
  2121. "C<Decode_Date_EU2()>" pair of functions.)
  2122.  
  2123. In a different case, the C version is a little bit more permissive than its
  2124. Perl equivalent.
  2125.  
  2126. (Can you tell the difference by looking at the code? Or by experimenting?
  2127. Hint: Try the string "(1/364)" with both functions.)
  2128.  
  2129. =item *
  2130.  
  2131. C<if (($year,$month,$day) = Parse_Date($string))>
  2132.  
  2133. This function is useful for parsing dates as returned by the UNIX "C<date>"
  2134. command or as found in the headers of e-mail (in order to determine the
  2135. date at which some e-mail has been sent or received, for instance).
  2136.  
  2137. Example #1:
  2138.  
  2139.   ($year,$month,$day) = Parse_Date(`/bin/date`);
  2140.  
  2141. Example #2:
  2142.  
  2143.   while (<MAIL>)
  2144.   {
  2145.       if (/^From \S/)
  2146.       {
  2147.           ($year,$month,$day) = Parse_Date($_);
  2148.           ...
  2149.       }
  2150.       ...
  2151.   }
  2152.  
  2153. The function returns an empty list if it can't extract a valid date from
  2154. the input string.
  2155.  
  2156. =item *
  2157.  
  2158. C<$lower = ISO_LC($string);>
  2159.  
  2160. Returns a copy of the given string where all letters of the ISO-Latin-1
  2161. character set have been replaced by their lower case equivalents.
  2162.  
  2163. Similar to Perl's built-in function "C<lc()>" (see L<perlfunc/lc>) but
  2164. for the whole ISO-Latin-1 character set, not just plain ASCII.
  2165.  
  2166. =item *
  2167.  
  2168. C<$upper = ISO_UC($string);>
  2169.  
  2170. Returns a copy of the given string where all letters of the ISO-Latin-1
  2171. character set have been replaced by their upper case equivalents.
  2172.  
  2173. Similar to Perl's built-in function "C<uc()>" (see L<perlfunc/uc>) but
  2174. for the whole ISO-Latin-1 character set, not just plain ASCII.
  2175.  
  2176. =item *
  2177.  
  2178. C<$string = Date::Calc::Version();>
  2179.  
  2180. This function returns a string with the (numeric) version number of the
  2181. S<C library> ("DateCalc.c") at the core of this package (which is also
  2182. (automatically) the version number of the "Calc.xs" file).
  2183.  
  2184. Note that under all normal circumstances, this version number should be
  2185. identical with the one found in the Perl variable "C<$Date::Calc::VERSION>"
  2186. (the version number of the "Calc.pm" file).
  2187.  
  2188. Since this function is not exported, you always have to qualify it explicitly,
  2189. i.e., "C<Date::Calc::Version()>".
  2190.  
  2191. This is to avoid possible name space conflicts with version functions from
  2192. other modules.
  2193.  
  2194. =back
  2195.  
  2196. =head1 RECIPES
  2197.  
  2198. =over 4
  2199.  
  2200. =item 1)
  2201.  
  2202. How do I compare two dates?
  2203.  
  2204. Solution #1:
  2205.  
  2206.   use Date::Calc qw( Date_to_Days );
  2207.  
  2208.   if (Date_to_Days($year1,$month1,$day1)  <
  2209.       Date_to_Days($year2,$month2,$day2))
  2210.  
  2211.   if (Date_to_Days($year1,$month1,$day1)  <=
  2212.       Date_to_Days($year2,$month2,$day2))
  2213.  
  2214.   if (Date_to_Days($year1,$month1,$day1)  >
  2215.       Date_to_Days($year2,$month2,$day2))
  2216.  
  2217.   if (Date_to_Days($year1,$month1,$day1)  >=
  2218.       Date_to_Days($year2,$month2,$day2))
  2219.  
  2220.   if (Date_to_Days($year1,$month1,$day1)  ==
  2221.       Date_to_Days($year2,$month2,$day2))
  2222.  
  2223.   if (Date_to_Days($year1,$month1,$day1)  !=
  2224.       Date_to_Days($year2,$month2,$day2))
  2225.  
  2226.   $cmp = (Date_to_Days($year1,$month1,$day1)  <=>
  2227.           Date_to_Days($year2,$month2,$day2));
  2228.  
  2229. Solution #2:
  2230.  
  2231.   use Date::Calc qw( Delta_Days );
  2232.  
  2233.   if (Delta_Days($year1,$month1,$day1,
  2234.                  $year2,$month2,$day2) > 0)
  2235.  
  2236.   if (Delta_Days($year1,$month1,$day1,
  2237.                  $year2,$month2,$day2) >= 0)
  2238.  
  2239.   if (Delta_Days($year1,$month1,$day1,
  2240.                  $year2,$month2,$day2) < 0)
  2241.  
  2242.   if (Delta_Days($year1,$month1,$day1,
  2243.                  $year2,$month2,$day2) <= 0)
  2244.  
  2245.   if (Delta_Days($year1,$month1,$day1,
  2246.                  $year2,$month2,$day2) == 0)
  2247.  
  2248.   if (Delta_Days($year1,$month1,$day1,
  2249.                  $year2,$month2,$day2) != 0)
  2250.  
  2251. =item 2)
  2252.  
  2253. How do I check whether a given date lies within a certain range of dates?
  2254.  
  2255.   use Date::Calc qw( Date_to_Days );
  2256.  
  2257.   $lower = Date_to_Days($year1,$month1,$day1);
  2258.   $upper = Date_to_Days($year2,$month2,$day2);
  2259.  
  2260.   $date = Date_to_Days($year,$month,$day);
  2261.  
  2262.   if (($date >= $lower) && ($date <= $upper))
  2263.   {
  2264.       # ok
  2265.   }
  2266.   else
  2267.   {
  2268.       # not ok
  2269.   }
  2270.  
  2271. =item 3)
  2272.  
  2273. How do I compare two dates with times? How do I check whether two dates
  2274. and times lie more or less than a given time interval apart?
  2275.  
  2276. Solution #1:
  2277.  
  2278.   use Date::Calc qw( Add_Delta_DHMS Date_to_Days );
  2279.  
  2280.   @date1 = (2002,8,31,23,59,1);
  2281.   @date2 = (2002,9,1,11,30,59); # ==> less than 12 hours
  2282.  
  2283.   #@date1 = (2002,8,31,22,59,1);
  2284.   #@date2 = (2002,9,1,11,30,59); # ==> more than 12 hours
  2285.  
  2286.   # Omit the next line if you just want to compare the two dates
  2287.   # (and change @date3 and @d3 to @date1 and @d1, respectively):
  2288.  
  2289.   @date3 = Add_Delta_DHMS(@date1, 0,12,0,0); # ==> is the difference within 12 hours?
  2290.  
  2291.   @d2 = ( Date_to_Days(@date2[0..2]), ($date2[3]*60+$date2[4])*60+$date2[5] );
  2292.   @d3 = ( Date_to_Days(@date3[0..2]), ($date3[3]*60+$date3[4])*60+$date3[5] );
  2293.  
  2294.   @diff = ( $d2[0]-$d3[0], $d2[1]-$d3[1] );
  2295.  
  2296.   if ($diff[0] > 0 and $diff[1] < 0) { $diff[0]--; $diff[1] += 86400; }
  2297.   if ($diff[0] < 0 and $diff[1] > 0) { $diff[0]++; $diff[1] -= 86400; }
  2298.  
  2299.   if (($diff[0] || $diff[1]) >= 0) { print "More than 12 hours.\n"; }
  2300.   else                             { print "Less than 12 hours.\n"; }
  2301.  
  2302. Solution #2:
  2303.  
  2304. This solution is only feasible if your dates are guaranteed to lie
  2305. within the range given by your system's epoch and overflow date and
  2306. time!
  2307.  
  2308.      Unix:    1-Jan-1970 00:00:00  to  19-Jan-2038 03:14:07
  2309.      MacOS:   1-Jan-1904 00:00:00  to   6-Feb-2040 06:28:15
  2310.  
  2311.   use Date::Calc qw( Date_to_Time );
  2312.  
  2313.   @date1 = (2002,8,31,23,59,1);
  2314.   @date2 = (2002,9,1,11,30,59); # ==> less than 12 hours
  2315.  
  2316.   #@date1 = (2002,8,31,22,59,1);
  2317.   #@date2 = (2002,9,1,11,30,59); # ==> more than 12 hours
  2318.  
  2319.   $d1 = Date_to_Time(@date1);
  2320.   $d2 = Date_to_Time(@date2);
  2321.  
  2322.   if ($d1 <= $d2) { print "The two dates are in chronological order.\n"; }
  2323.   else            { print "The two dates are in reversed order.\n"; }
  2324.  
  2325.   if ($d1 + 12*60*60 <= $d2) { print "More than 12 hours.\n"; }
  2326.   else                       { print "Less than 12 hours.\n"; }
  2327.  
  2328. =item 4)
  2329.  
  2330. How do I verify whether someone has a certain age?
  2331.  
  2332.   use Date::Calc qw( Decode_Date_EU Today leap_year Delta_Days );
  2333.  
  2334.   $date = <STDIN>; # get birthday
  2335.  
  2336.   ($year1,$month1,$day1) = Decode_Date_EU($date);
  2337.  
  2338.   ($year2,$month2,$day2) = Today();
  2339.  
  2340.   if (($day1 == 29) && ($month1 == 2) && !leap_year($year2))
  2341.       { $day1--; }
  2342.  
  2343.   if ( (($year2 - $year1) >  18) ||
  2344.      ( (($year2 - $year1) == 18) &&
  2345.      (Delta_Days($year2,$month1,$day1, $year2,$month2,$day2) >= 0) ) )
  2346.   {
  2347.       print "Ok - you are over 18.\n";
  2348.   }
  2349.   else
  2350.   {
  2351.       print "Sorry - you aren't 18 yet!\n";
  2352.   }
  2353.  
  2354.   Or, alternatively (substituting the last "if" statement above):
  2355.  
  2356.   if (($year1+18 <=> $year2 || $month1 <=> $month2 || $day1 <=> $day2) <= 0)
  2357.       { print "Ok - you are over 18.\n"; }
  2358.   else
  2359.       { print "Sorry - you aren't 18 yet!\n"; }
  2360.  
  2361. =item 5)
  2362.  
  2363. How do I calculate the number of the week of month
  2364. the current date lies in?
  2365.  
  2366. For example:
  2367.  
  2368.             April 1998
  2369.     Mon Tue Wed Thu Fri Sat Sun
  2370.               1   2   3   4   5  =  week #1
  2371.       6   7   8   9  10  11  12  =  week #2
  2372.      13  14  15  16  17  18  19  =  week #3
  2373.      20  21  22  23  24  25  26  =  week #4
  2374.      27  28  29  30              =  week #5
  2375.  
  2376. Solution:
  2377.  
  2378.   use Date::Calc qw( Today Day_of_Week );
  2379.  
  2380.   ($year,$month,$day) = Today();
  2381.  
  2382.   $week = int(($day + Day_of_Week($year,$month,1) - 2) / 7) + 1;
  2383.  
  2384. =item 6)
  2385.  
  2386. How do I calculate whether a given date is the 1st, 2nd, 3rd, 4th or 5th
  2387. of that day of week in the given month?
  2388.  
  2389. For example:
  2390.  
  2391.            October 2000
  2392.     Mon Tue Wed Thu Fri Sat Sun
  2393.                               1
  2394.       2   3   4   5   6   7   8
  2395.       9  10  11  12  13  14  15
  2396.      16  17  18  19  20  21  22
  2397.      23  24  25  26  27  28  29
  2398.      30  31
  2399.  
  2400. Is Sunday, the 15th of October 2000, the 1st, 2nd, 3rd, 4th or 5th
  2401. Sunday of that month?
  2402.  
  2403. Solution:
  2404.  
  2405.   use Date::Calc qw( Day_of_Week Delta_Days
  2406.                      Nth_Weekday_of_Month_Year
  2407.                      Date_to_Text_Long English_Ordinal
  2408.                      Day_of_Week_to_Text Month_to_Text );
  2409.  
  2410.   ($year,$month,$day) = (2000,10,15);
  2411.  
  2412.   $dow = Day_of_Week($year,$month,$day);
  2413.  
  2414.   $n = int( Delta_Days(
  2415.             Nth_Weekday_of_Month_Year($year,$month,$dow,1),
  2416.             $year,$month,$day)
  2417.             / 7) + 1;
  2418.  
  2419.   printf("%s is the %s %s in %s %d.\n",
  2420.       Date_to_Text_Long($year,$month,$day),
  2421.       English_Ordinal($n),
  2422.       Day_of_Week_to_Text($dow),
  2423.       Month_to_Text($month),
  2424.       $year);
  2425.  
  2426. This prints:
  2427.  
  2428.   Sunday, October 15th 2000 is the 3rd Sunday in October 2000.
  2429.  
  2430. =item 7)
  2431.  
  2432. How do I calculate the date of the Wednesday of the same week as
  2433. the current date?
  2434.  
  2435. Solution #1:
  2436.  
  2437.   use Date::Calc qw( Today Day_of_Week Add_Delta_Days );
  2438.  
  2439.   $searching_dow = 3; # 3 = Wednesday
  2440.  
  2441.   @today = Today();
  2442.  
  2443.   $current_dow = Day_of_Week(@today);
  2444.  
  2445.   @date = Add_Delta_Days(@today, $searching_dow - $current_dow);
  2446.  
  2447. Solution #2:
  2448.  
  2449.   use Date::Calc qw( Today Add_Delta_Days
  2450.                      Monday_of_Week Week_of_Year );
  2451.  
  2452.   $searching_dow = 3; # 3 = Wednesday
  2453.  
  2454.   @today = Today();
  2455.  
  2456.   @date = Add_Delta_Days( Monday_of_Week( Week_of_Year(@today) ),
  2457.                           $searching_dow - 1 );
  2458.  
  2459. Solution #3:
  2460.  
  2461.   use Date::Calc qw( Standard_to_Business Today
  2462.                      Business_to_Standard );
  2463.  
  2464.   @business = Standard_to_Business(Today());
  2465.  
  2466.   $business[2] = 3; # 3 = Wednesday
  2467.  
  2468.   @date = Business_to_Standard(@business);
  2469.  
  2470. =item 8)
  2471.  
  2472. How can I add a week offset to a business date (including across
  2473. year boundaries)?
  2474.  
  2475.   use Date::Calc qw( Business_to_Standard Add_Delta_Days
  2476.                      Standard_to_Business );
  2477.  
  2478.   @temp = Business_to_Standard($year,$week,$dow);
  2479.  
  2480.   @temp = Add_Delta_Days(@temp, $week_offset * 7);
  2481.  
  2482.   ($year,$week,$dow) = Standard_to_Business(@temp);
  2483.  
  2484. =item 9)
  2485.  
  2486. How do I calculate the last and the next Saturday for any
  2487. given date?
  2488.  
  2489.   use Date::Calc qw( Today Day_of_Week Add_Delta_Days
  2490.                      Day_of_Week_to_Text Date_to_Text );
  2491.  
  2492.   $searching_dow = 6; # 6 = Saturday
  2493.  
  2494.   @today = Today();
  2495.  
  2496.   $current_dow = Day_of_Week(@today);
  2497.  
  2498.   if ($searching_dow == $current_dow)
  2499.   {
  2500.       @prev = Add_Delta_Days(@today,-7);
  2501.       @next = Add_Delta_Days(@today,+7);
  2502.   }
  2503.   else
  2504.   {
  2505.       if ($searching_dow > $current_dow)
  2506.       {
  2507.           @next = Add_Delta_Days(@today,
  2508.                     $searching_dow - $current_dow);
  2509.           @prev = Add_Delta_Days(@next,-7);
  2510.       }
  2511.       else
  2512.       {
  2513.           @prev = Add_Delta_Days(@today,
  2514.                     $searching_dow - $current_dow);
  2515.           @next = Add_Delta_Days(@prev,+7);
  2516.       }
  2517.   }
  2518.  
  2519.   $dow = Day_of_Week_to_Text($searching_dow);
  2520.  
  2521.   print "Today is:      ", ' ' x length($dow),
  2522.                                Date_to_Text(@today), "\n";
  2523.   print "Last $dow was:     ", Date_to_Text(@prev),  "\n";
  2524.   print "Next $dow will be: ", Date_to_Text(@next),  "\n";
  2525.  
  2526. This will print something like:
  2527.  
  2528.   Today is:              Sun 12-Apr-1998
  2529.   Last Saturday was:     Sat 11-Apr-1998
  2530.   Next Saturday will be: Sat 18-Apr-1998
  2531.  
  2532. =item 10)
  2533.  
  2534. How can I calculate the last business day (payday!) of a month?
  2535.  
  2536. Solution #1 (holidays B<NOT> taken into account):
  2537.  
  2538.   use Date::Calc qw( Days_in_Month Day_of_Week Add_Delta_Days );
  2539.  
  2540.   $day = Days_in_Month($year,$month);
  2541.   $dow = Day_of_Week($year,$month,$day);
  2542.   if ($dow > 5)
  2543.   {
  2544.       ($year,$month,$day) =
  2545.           Add_Delta_Days($year,$month,$day, 5-$dow);
  2546.   }
  2547.  
  2548. Solution #2 (holidays taken into account):
  2549.  
  2550. This solution expects a multi-dimensional array "C<@holiday>", which
  2551. contains all holidays, as follows: "C<$holiday[$year][$month][$day] = 1;>".
  2552.  
  2553. (See the description of the function "C<Easter_Sunday()>" further above for
  2554. how to calculate the moving (variable) christian feast days!)
  2555.  
  2556. Days which are not holidays remain undefined or should have a value of zero
  2557. in this array.
  2558.  
  2559.   use Date::Calc qw( Days_in_Month Add_Delta_Days Day_of_Week );
  2560.  
  2561.   $day = Days_in_Month($year,$month);
  2562.   while (1)
  2563.   {
  2564.       while ($holiday[$year][$month][$day])
  2565.       {
  2566.           ($year,$month,$day) =
  2567.               Add_Delta_Days($year,$month,$day, -1);
  2568.       }
  2569.       $dow = Day_of_Week($year,$month,$day);
  2570.       if ($dow > 5)
  2571.       {
  2572.           ($year,$month,$day) =
  2573.               Add_Delta_Days($year,$month,$day, 5-$dow);
  2574.       }
  2575.       else { last; }
  2576.   }
  2577.  
  2578. Solution #3 (holidays taken into account, more comfortable,
  2579. but requires Date::Calendar(3) and Date::Calc::Object(3)):
  2580.  
  2581.   use Date::Calc::Object qw( Today Add_Delta_YM Date_to_Text_Long );
  2582.   use Date::Calendar::Profiles qw($Profiles);
  2583.   use Date::Calendar;
  2584.  
  2585.   $calendar = Date::Calendar->new( $Profiles->{'DE-BW'} );
  2586.  
  2587.   @today = Today();
  2588.   @nextmonth = Add_Delta_YM(@today[0,1],1, 0,1);
  2589.  
  2590.   $workaround = $calendar->add_delta_workdays(@nextmonth,+1);
  2591.   $payday     = $calendar->add_delta_workdays($workaround,-2);
  2592.  
  2593.   print "Pay day = ", Date_to_Text_Long($payday->date()), "\n";
  2594.  
  2595. The "workaround" is necessary due to a bug in the method
  2596. "add_delta_workdays()" when adding a negative number of
  2597. workdays.
  2598.  
  2599. =item 11)
  2600.  
  2601. How do I convert a MS Visual Basic "DATETIME" value into its date
  2602. and time constituents?
  2603.  
  2604.   use Date::Calc qw( Add_Delta_DHMS Date_to_Text );
  2605.  
  2606.   $datetime = "35883.121653";
  2607.  
  2608.   ($Dd,$Dh,$Dm,$Ds) = ($datetime =~ /^(\d+)\.(\d\d)(\d\d)(\d\d)$/);
  2609.  
  2610.   ($year,$month,$day, $hour,$min,$sec) =
  2611.       Add_Delta_DHMS(1900,1,1, 0,0,0, $Dd,$Dh,$Dm,$Ds);
  2612.  
  2613.   printf("The given date is %s %02d:%02d:%02d\n",
  2614.       Date_to_Text($year,$month,$day), $hour, $min, $sec);
  2615.  
  2616. This prints:
  2617.  
  2618.   The given date is Tue 31-Mar-1998 12:16:53
  2619.  
  2620. Since I do not have or use Visual Basic, I can't guarantee that
  2621. the number format assumed here is really the one used by Visual
  2622. Basic - but you get the general idea. C<:-)>
  2623.  
  2624. Moreover, consider the following:
  2625.  
  2626. Morten Sickel <Morten.Sickel@nrpa.no> wrote:
  2627.  
  2628. I discovered a bug in Excel (2000): Excel thinks that 1900 was
  2629. a leap year. Users should use 31-Dec-1899 as the date to add
  2630. an Excel date value to in order to get the correct date.
  2631.  
  2632. I found out on the web that this bug originated in Lotus 123,
  2633. which made 29-Feb-1900 an "industrial standard". MS chose to
  2634. keep the bug in order to be compatible with Lotus 123. But
  2635. they have not mentioned anything about it in the help files.
  2636.  
  2637. =item 12)
  2638.  
  2639. How can I send a reminder to members of a group on the day
  2640. before a meeting which occurs every first Friday of a month?
  2641.  
  2642.   use Date::Calc qw( Today Date_to_Days Add_Delta_YMD
  2643.                      Nth_Weekday_of_Month_Year );
  2644.  
  2645.   ($year,$month,$day) = Today();
  2646.  
  2647.   $tomorrow = Date_to_Days($year,$month,$day) + 1;
  2648.  
  2649.   $dow = 5; # 5 = Friday
  2650.   $n   = 1; # 1 = First of that day of week
  2651.  
  2652.   $meeting_this_month = Date_to_Days(
  2653.       Nth_Weekday_of_Month_Year($year,$month,$dow,$n) );
  2654.  
  2655.   ($year,$month,$day) = Add_Delta_YMD($year,$month,$day, 0,1,0);
  2656.  
  2657.   $meeting_next_month = Date_to_Days(
  2658.       Nth_Weekday_of_Month_Year($year,$month,$dow,$n) );
  2659.  
  2660.   if (($tomorrow == $meeting_this_month) ||
  2661.       ($tomorrow == $meeting_next_month))
  2662.   {
  2663.       # Send reminder e-mail!
  2664.   }
  2665.  
  2666. =item 13)
  2667.  
  2668. How can I print a date in a different format than provided by
  2669. the functions "C<Date_to_Text()>", "C<Date_to_Text_Long()>" or
  2670. "C<Compressed_to_Text()>"?
  2671.  
  2672.   use Date::Calc qw( Today Day_of_Week_to_Text
  2673.                      Day_of_Week Month_to_Text
  2674.                      English_Ordinal );
  2675.  
  2676.   ($year,$month,$day) = Today();
  2677.  
  2678. For example with leading zeros for the day: "S<Fri 03-Jan-1964>"
  2679.  
  2680.   printf("%.3s %02d-%.3s-%d\n",
  2681.       Day_of_Week_to_Text(Day_of_Week($year,$month,$day)),
  2682.       $day,
  2683.       Month_to_Text($month),
  2684.       $year);
  2685.  
  2686. For example in U.S. american format: "S<April 12th, 1998>"
  2687.  
  2688.   $string = sprintf("%s %s, %d",
  2689.                 Month_to_Text($month),
  2690.                 English_Ordinal($day),
  2691.                 $year);
  2692.  
  2693. For example in one of the possible formats as specified by S<ISO 8601>:
  2694.  
  2695.   @date = ($year,$month,$day,$hour,$min,$sec);
  2696.   $date = sprintf("%d-%02d-%02d %02d:%02d:%02d", @date);
  2697.  
  2698. (See also L<perlfunc(1)/printf> and/or L<perlfunc(1)/sprintf>!)
  2699.  
  2700. =item 14)
  2701.  
  2702. How can I iterate through a range of dates?
  2703.  
  2704.   use Date::Calc qw( Delta_Days Add_Delta_Days );
  2705.  
  2706.   @start = (1999,5,27);
  2707.   @stop  = (1999,6,1);
  2708.  
  2709.   $j = Delta_Days(@start,@stop);
  2710.  
  2711.   for ( $i = 0; $i <= $j; $i++ )
  2712.   {
  2713.       @date = Add_Delta_Days(@start,$i);
  2714.       printf("%4d/%02d/%02d\n", @date);
  2715.   }
  2716.  
  2717. Note that the loop can be improved; see also the recipe below.
  2718.  
  2719. =item 15)
  2720.  
  2721. How can I create a (Perl) list of dates in a certain range?
  2722.  
  2723.   use Date::Calc qw( Delta_Days Add_Delta_Days Date_to_Text );
  2724.  
  2725.   sub date_range
  2726.   {
  2727.       my(@date) = (@_)[0,1,2];
  2728.       my(@list);
  2729.       my($i);
  2730.  
  2731.       $i = Delta_Days(@_);
  2732.       while ($i-- >= 0)
  2733.       {
  2734.           push( @list, [ @date ] );
  2735.           @date = Add_Delta_Days(@date, 1) if ($i >= 0);
  2736.       }
  2737.       return(@list);
  2738.   }
  2739.  
  2740.   @range = &date_range(1999,11,3, 1999,12,24); # in chronological order
  2741.  
  2742.   foreach $date (@range)
  2743.   {
  2744.       print Date_to_Text(@{$date}), "\n";
  2745.   }
  2746.  
  2747. Note that you probably shouldn't use this one, because it is much
  2748. more efficient to iterate through all the dates (as shown in the
  2749. recipe immediately above) than to construct such an array and then
  2750. to loop through it. Also, it is much more space-efficient not to
  2751. create this array.
  2752.  
  2753. =item 16)
  2754.  
  2755. How can I calculate the difference in days between dates,
  2756. but without counting Saturdays and Sundays?
  2757.  
  2758.   sub Delta_Business_Days
  2759.   {
  2760.       my(@date1) = (@_)[0,1,2];
  2761.       my(@date2) = (@_)[3,4,5];
  2762.       my($minus,$result,$dow1,$dow2,$diff,$temp);
  2763.  
  2764.       $minus  = 0;
  2765.       $result = Delta_Days(@date1,@date2);
  2766.       if ($result != 0)
  2767.       {
  2768.           if ($result < 0)
  2769.           {
  2770.               $minus = 1;
  2771.               $result = -$result;
  2772.               $dow1 = Day_of_Week(@date2);
  2773.               $dow2 = Day_of_Week(@date1);
  2774.           }
  2775.           else
  2776.           {
  2777.               $dow1 = Day_of_Week(@date1);
  2778.               $dow2 = Day_of_Week(@date2);
  2779.           }
  2780.           $diff = $dow2 - $dow1;
  2781.           $temp = $result;
  2782.           if ($diff != 0)
  2783.           {
  2784.               if ($diff < 0)
  2785.               {
  2786.                   $diff += 7;
  2787.               }
  2788.               $temp -= $diff;
  2789.               $dow1 += $diff;
  2790.               if ($dow1 > 6)
  2791.               {
  2792.                   $result--;
  2793.                   if ($dow1 > 7)
  2794.                   {
  2795.                       $result--;
  2796.                   }
  2797.               }
  2798.           }
  2799.           if ($temp != 0)
  2800.           {
  2801.               $temp /= 7;
  2802.               $result -= ($temp << 1);
  2803.           }
  2804.       }
  2805.       if ($minus) { return -$result; }
  2806.       else        { return  $result; }
  2807.   }
  2808.  
  2809. This solution is probably of little practical value, however,
  2810. because it doesn't take legal holidays into account.
  2811.  
  2812. See L<Date::Calendar(3)> for how to do that.
  2813.  
  2814. =back
  2815.  
  2816. =head1 SEE ALSO
  2817.  
  2818. Date::Calc::Object(3), Date::Calendar(3),
  2819. Date::Calendar::Year(3), Date::Calendar::Profiles(3).
  2820.  
  2821.   "The Calendar FAQ":
  2822.   http://www.tondering.dk/claus/calendar.html
  2823.   by Claus Tondering <claus@tondering.dk>
  2824.  
  2825. =head1 LIMITATIONS
  2826.  
  2827. In the current implementation of this package, the selected language
  2828. is stored in a global variable.
  2829.  
  2830. Therefore, when you are using a threaded Perl, this may cause undesired
  2831. side effects (of one thread always selecting the language for B<ALL OTHER>
  2832. threads as well).
  2833.  
  2834. =head1 VERSION
  2835.  
  2836. This man page documents "Date::Calc" version 5.3.
  2837.  
  2838. =head1 AUTHOR
  2839.  
  2840.   Steffen Beyer
  2841.   mailto:sb@engelschall.com
  2842.   http://www.engelschall.com/u/sb/download/
  2843.  
  2844. =head1 COPYRIGHT
  2845.  
  2846. Copyright (c) 1995 - 2002 by Steffen Beyer. All rights reserved.
  2847.  
  2848. =head1 LICENSE
  2849.  
  2850. This package is free software; you can redistribute it and/or
  2851. modify it under the same terms as Perl itself, i.e., under the
  2852. terms of the "Artistic License" or the "GNU General Public License".
  2853.  
  2854. The C library at the core of this Perl module can additionally
  2855. be redistributed and/or modified under the terms of the
  2856. "GNU Library General Public License".
  2857.  
  2858. Please refer to the files "Artistic.txt", "GNU_GPL.txt" and
  2859. "GNU_LGPL.txt" in this distribution for details!
  2860.  
  2861. =head1 DISCLAIMER
  2862.  
  2863. This package is distributed in the hope that it will be useful,
  2864. but WITHOUT ANY WARRANTY; without even the implied warranty of
  2865. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  2866.  
  2867. See the "GNU General Public License" for more details.
  2868.  
  2869.