home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Editores / Perl5 / perl / lib / site / Date / DateCalc.pm next >
Encoding:
Perl POD Document  |  1997-08-10  |  24.7 KB  |  800 lines

  1.  
  2. #  Copyright (c) 1995, 1996, 1997 by Steffen Beyer. All rights reserved.
  3. #  This program is free software; you can redistribute it and/or modify
  4. #  it under the same terms as Perl itself.
  5.  
  6. package Date::DateCalc;
  7.  
  8. require Exporter;
  9. require DynaLoader;
  10.  
  11. @ISA = qw(Exporter DynaLoader);
  12.  
  13. @EXPORT = qw();
  14.  
  15. @EXPORT_OK = qw( leap check_date compress uncompress check_compressed
  16. compressed_to_short calc_days day_of_week dates_difference calc_new_date
  17. date_time_difference calc_new_date_time date_to_short date_to_string
  18. week_number first_in_week weeks_in_year day_name_tab month_name_tab
  19. decode_day decode_month decode_date days_in_month );
  20.  
  21. %EXPORT_TAGS = (all => [@EXPORT_OK]);
  22.  
  23. # "Version" is available but not exported!
  24. # Call with "Date::DateCalc::Version()"!
  25.  
  26. $VERSION = '3.2';
  27.  
  28. bootstrap Date::DateCalc $VERSION;
  29.  
  30. 1;
  31.  
  32. __END__
  33.  
  34. =head1 NAME
  35.  
  36. Date::DateCalc - Gregorian Calendar Date Calculations
  37.  
  38. in compliance with ISO/R 2015-1971 and DIN 1355 standards
  39.  
  40. =head1 SYNOPSIS
  41.  
  42. C<use Date::DateCalc;>
  43.  
  44. (in which case you must fully qualify every function with the name
  45. of this module, for example C<$flag = Date::DateCalc::leap($year)>)
  46.  
  47. or
  48.  
  49. C<use Date::DateCalc>
  50. C<qw( leap check_date compress uncompress check_compressed>
  51. C<compressed_to_short calc_days day_of_week dates_difference>
  52. C<calc_new_date date_time_difference calc_new_date_time>
  53. C<date_to_short date_to_string week_number first_in_week>
  54. C<weeks_in_year day_name_tab month_name_tab decode_day>
  55. C<decode_month decode_date days_in_month );>
  56.  
  57. (or only portions thereof, whatever you need)
  58.  
  59. or
  60.  
  61. C<use DateCalc qw(:all);>
  62.  
  63. (which imports everything).
  64.  
  65. =head1 DESCRIPTION
  66.  
  67. =head2 ===========
  68.  
  69. =head2 Convention:
  70.  
  71. =head2 ===========
  72.  
  73. In the following, "$year" stands for a "complete" year number
  74. (like "1995", for instance), whereas "$yy" may be an abbreviated
  75. year number (like "95") OR a complete year number.
  76.  
  77. Year numbers must be positive integers (greater than zero).
  78.  
  79. "$mm" stands for the number of a month (from 1 to 12), and "$dd"
  80. is the number of a day in a month (from 1 to 28,29,30 or 31,
  81. depending on the month and the year).
  82.  
  83. Hint: The functions that support abbreviated year numbers are
  84. the functions whose names contain the word "compress" and the
  85. function "decode_date()".
  86.  
  87. =head2   ====================
  88.  
  89. =head2 C<$flag = leap($year);>
  90.  
  91. =head2   ====================
  92.  
  93. This function returns a boolean value which is "true" (1) if the
  94. year "$year" is a leap year, and "false" (0) otherwise.
  95.  
  96. No check is made if the year "$year" is in the valid range.
  97.  
  98. For years less than 1, the result is probably meaningless (it IS
  99. almost meaningless, anyway, for years before 1582).
  100.  
  101. =head2   ==================================
  102.  
  103. =head2 C<$flag = check_date($year,$mm,$dd);>
  104.  
  105. =head2   ==================================
  106.  
  107. This function returns a boolean value which is "true" (1) if the
  108. three numbers "$year", "$mm" and "$dd" represent a valid date,
  109. and "false" (0) otherwise.
  110.  
  111. When determining validity, leap years are taken into account,
  112. i.e., the 29th of february is rejected in non-leap years.
  113.  
  114. Year numbers must be greater than zero (negative values will be
  115. interpreted as large positive numbers due to their internal 2's
  116. complement binary representation). A year number of zero is invalid.
  117.  
  118. =head2   ==============================
  119.  
  120. =head2 C<$date = compress($yy,$mm,$dd);>
  121.  
  122. =head2   ==============================
  123.  
  124. This function encodes a date in 16 bits. The encoding scheme is
  125. as follows:
  126.  
  127.     Bit-No.:       FEDCBA9 8765 43210
  128.     Contents:      yyyyyyy mmmm ddddd
  129.  
  130. All bits equal to zero is equivalent to "<no date>".
  131.  
  132. Through this encoding scheme, it is possible to COMPARE ENCODED
  133. DATES for equality and ORDER (less than/greater than) WITHOUT
  134. any previous DECODING!!
  135.  
  136. Note however that contiguous dates DO NOT NECESSARILY have
  137. contiguous compressed representations!
  138.  
  139. I.e., incrementing the compressed representation of a date may or
  140. MAY NOT yield a valid new date!
  141.  
  142. Note also that this function can only handle dates within one century.
  143.  
  144. This century can be biased at will by choosing a base century and year
  145. (also called an "epoch"). In this module, the base century is set to
  146. 1900 and the base year to 70 (standard on UNIX systems).
  147.  
  148. This allows the function to handle dates from 1970 up to 2069.
  149.  
  150. If the year "$yy" is equal to, say, 95, it is automatically
  151. assumed that 1995 is meant. However, if you specify a year
  152. number which is SMALLER than 70, like 64, for instance, it
  153. is assumed that you meant 2064.
  154.  
  155. You are not confined to abbreviated year numbers (smaller than
  156. 100), however. The function also accepts complete year numbers,
  157. provided that they are in the supported range (that is, from
  158. 1970 to 2069).
  159.  
  160. If no valid date is specified, zero is returned.
  161.  
  162. =head2   ======================================
  163.  
  164. =head2 C<($cc,$yy,$mm,$dd) = uncompress($date);>
  165.  
  166. =head2   ======================================
  167.  
  168. This function decodes dates that were encoded by "compress()".
  169. It returns the century, year, month and day of the date encoded
  170. in "$date" in the variables "$cc", "$yy", "$mm" and "$dd",
  171. respectively.
  172.  
  173. The expression "$cc + $yy" yields the complete year number (for
  174. example, 1900 + 95 = 1995).
  175.  
  176. If "$date" is zero or does not contain the compressed representation
  177. of a valid date, an empty list is returned.
  178.  
  179. =head2   ================================
  180.  
  181. =head2 C<$flag = check_compressed($date);>
  182.  
  183. =head2   ================================
  184.  
  185. This function returns a boolean value which is "true" (1) if
  186. "$date" contains a valid encoded date, and "false" (0) otherwise.
  187.  
  188. When determining validity, leap years are taken into account,
  189. i.e., the 29th of february is rejected in non-leap years.
  190.  
  191. =head2   ======================================
  192.  
  193. =head2 C<$datestr = compressed_to_short($date);>
  194.  
  195. =head2   ======================================
  196.  
  197. This function converts the encoded date in "$date" to a string
  198. of the format "dd-mmm-yy", which is returned.
  199.  
  200. ("mmm" is the 3-letter abbreviation (in English) of the month's name.)
  201.  
  202. If the date in "$date" is invalid, the string "<no date>" is
  203. returned.
  204.  
  205. Note that the string which is returned by this function is
  206. always exactly 9 characters long.
  207.  
  208. =head2   =================================
  209.  
  210. =head2 C<$days = calc_days($year,$mm,$dd);>
  211.  
  212. =head2   =================================
  213.  
  214. This function returns the (theoretical) number of days between
  215. the first of january of the year one and the given date *plus one*.
  216.  
  217. I.e., the value returned for the first of january of the year one
  218. is 1, the value returned for the second of january of the year one
  219. is 2, and so on.
  220.  
  221. This is because there is no year zero; the christian calendar starts
  222. with the year one. Consequently, there is also no day zero; the calendar
  223. starts with the first day, i.e., day one.
  224.  
  225. The function doesn't take into account the change from the Julian to
  226. the Gregorian calendar (used today) in 1582 (or later, for some countries),
  227. it simply extrapolates the gregorian calendar backwards.
  228.  
  229. This function is used internally to calculate the difference in days
  230. between two dates and to calculate the day of week.
  231.  
  232. Use this function to compare dates for "less than" and "greater than",
  233. or to compare dates for equality more easily.
  234.  
  235. Zero is returned if no valid date is specified.
  236.  
  237. (This is another reason why "C<calc_days(1,1,1)>" is equal to one and
  238. not to zero!)
  239.  
  240. =head2   ======================================
  241.  
  242. =head2 C<$weekday = day_of_week($year,$mm,$dd);>
  243.  
  244. =head2   ======================================
  245.  
  246. This function calculates the day of week for the given date
  247. (which must be a valid date).
  248.  
  249. The return values have the following meaning:
  250.  
  251.         0       =       Error
  252.         1       =       Monday
  253.         2       =       Tuesday
  254.         3       =       Wednesday
  255.         4       =       Thursday
  256.         5       =       Friday
  257.         6       =       Saturday
  258.         7       =       Sunday
  259.  
  260. The value zero is returned if the date is not valid.
  261.  
  262. =head2   ============================================================
  263.  
  264. =head2 C<$days = dates_difference($year1,$mm1,$dd1,$year2,$mm2,$dd2);>
  265.  
  266. =head2   ============================================================
  267.  
  268. This function calculates the difference in days between the two
  269. given dates.
  270.  
  271. The function calculates the difference "date 2" - "date 1", i.e.,
  272. you normally specify the two dates in chronological order.
  273.  
  274. If date 1 is later than date 2, the result will be negative,
  275. which allows you to use this function to compare dates.
  276.  
  277. If one of the two dates is invalid, the result will degrade
  278. to the value of the function "calc_days()" for the other date
  279. (possibly negative). If both dates are invalid, the result is
  280. zero.
  281.  
  282. It is the user's responsibility to make sure that both dates
  283. are valid (use "check_date()" for this)!
  284.  
  285. =head2   =======================================================
  286.  
  287. =head2 C<($year,$mm,$dd) = calc_new_date($year,$mm,$dd,$offset);>
  288.  
  289. =head2   =======================================================
  290.  
  291. Starting from the given date, a new date can be calculated with
  292. this function which is "$offset" days away from the original
  293. date. "$offset" may be positive (for a date later than the
  294. original date) or negative (for a date earlier than the given date).
  295.  
  296. If the given date is invalid or the new date cannot be calculated
  297. (for instance, if the new date would be before the year one),
  298. an empty list is returned.
  299.  
  300. To calculate a new date with a year, month and day offset, see the
  301. function "year_month_day_offset()" in the "Date::DateCalcLib" module.
  302.  
  303. =head2   ===========================================
  304.  
  305. =head2 C<($days,$hh,$mm,$ss) = date_time_difference( $year1,$month1,$day1,$hh1,$mm1,$ss1, $year2,$month2,$day2,$hh2,$mm2,$ss2 );>
  306.  
  307. =head2   ===========================================
  308.  
  309. This function calculates the difference in days, hours, minutes
  310. and seconds between the two given dates.
  311.  
  312. The function calculates the difference "date 2" - "date 1", i.e.,
  313. you normally specify the two dates in chronological order.
  314.  
  315. If date 1 is later than date 2, the result will be negative
  316. in every of the four return values, which allows you to use
  317. this function to compare dates and to feed its output into
  318. the function explained next in this text, "calc_new_date_time()".
  319.  
  320. If one (or both) of the two date/time pairs is invalid, an empty
  321. list is returned.
  322.  
  323. A date/time pair is invalid either when the date is invalid or
  324. when the values for hour, minute and second are outside the range
  325. of 0..23, 0..59 and 0..59, respectively.
  326.  
  327. =head2   =====================================================
  328.  
  329. =head2 C<($year,$month,$day,$hh,$mm,$ss) = calc_new_date_time( $year,$month,$day,$hh,$mm,$ss, $days_offset,$hh_offset,$mm_offset,$ss_offset );>
  330.  
  331. =head2   =====================================================
  332.  
  333. Starting from the given date and time, a new date and time can
  334. be calculated with this function.
  335.  
  336. The new date will be "$days_offset" days and "$hh_offset" hours,
  337. "$mm_offset" minutes and "$ss_offset" seconds away from the
  338. original date. The values of these four offsets may be positive or
  339. negative, independently from each other. This means that you can
  340. add, for instance, 9 hours and subtract 5 minutes at the same time.
  341.  
  342. If the new date and time cannot be calculated (for instance, if
  343. the given date is invalid or the new date would be before the year
  344. one, or the values for hour, minute and second are outside the
  345. range of 0..23, 0..59 and 0..59, respectively), an empty list is
  346. returned.
  347.  
  348. =head2   ========================================
  349.  
  350. =head2 C<$datestr = date_to_short($year,$mm,$dd);>
  351.  
  352. =head2   ========================================
  353.  
  354. This function converts the given date to a string of the format
  355. "www dd-mmm-yyyy", which is returned.
  356.  
  357. "www" is a (3-letter) abbreviation of the day of week, and "mmm"
  358. is a (3-letter) abbreviation of the month (both in English).
  359.  
  360. If the given date is invalid, the string "<no date>" is returned.
  361.  
  362. =head2   =========================================
  363.  
  364. =head2 C<$datestr = date_to_string($year,$mm,$dd);>
  365.  
  366. =head2   =========================================
  367.  
  368. This function converts the given date to a string of the format
  369. "wwwwwwwww, dd mmmmmmmmm yyyy", which is returned.
  370.  
  371. "wwwwwwwww" is the day of week and "mmmmmmmmm" the name of the
  372. month (both in English).
  373.  
  374. If the given date is invalid, the string "<no date>" is returned.
  375.  
  376. =head2   ===========================================
  377.  
  378. =head2 C<($week,$year) = week_number($year,$mm,$dd);>
  379.  
  380. =head2   ===========================================
  381.  
  382. This function calculates the number of the week in which the
  383. given date lies.
  384.  
  385. This can occasionally be the last week of the previous year
  386. or the first week of the next year.
  387.  
  388. If the given date is invalid, an empty list is returned.
  389.  
  390. =head2   =============================================
  391.  
  392. =head2 C<($year,$mm,$dd) = first_in_week($week,$year);>
  393.  
  394. =head2   =============================================
  395.  
  396. This function calculates the date of the first day (the Monday)
  397. of the given week in the given year.
  398.  
  399. The return value "$year" is adjusted accordingly if the first
  400. day of the given week lies in the previous year.
  401.  
  402. If the week number is invalid (less than one or greater than the
  403. number of weeks of the given year, as returned by the function
  404. "weeks_in_year()"), or if the year is invalid or the date cannot
  405. be calculated (for example, if the calculated date would be before
  406. the year one), an empty list is returned.
  407.  
  408. With help of the expression
  409.  
  410.     ($year,$mm,$dd) = first_in_week(week_number($year,$mm,$dd));
  411.  
  412. it is possible to easily calculate the date of the Monday belonging
  413. to the week in which the given date lies.
  414.  
  415. (However, a fatal Perl error will occur if the given date is invalid!)
  416.  
  417. Alternatively, the expression
  418.  
  419.     ($year,$mm,$dd) =
  420.     calc_new_date($year,$mm,$dd,-day_of_week($year,$mm,$dd)+1);
  421.  
  422. can be used to achieve the same effect.
  423.  
  424. (An empty list is returned if the given date is invalid.)
  425.  
  426. =head2   ==============================
  427.  
  428. =head2 C<$weeks = weeks_in_year($year);>
  429.  
  430. =head2   ==============================
  431.  
  432. This function returns the number of weeks of the given year
  433. (52 or 53 weeks).
  434.  
  435. No check is made if the year "$year" is in the valid range.
  436.  
  437. For years less than 1, the result is probably meaningless.
  438.  
  439. =head2   ===================================
  440.  
  441. =head2 C<$day_name = day_name_tab($weekday);>
  442.  
  443. =head2   ===================================
  444.  
  445. This function accesses the internal table of the days of week.
  446.  
  447. It returns the corresponding string for each numeric value of a
  448. day of week (as returned by the function "day_of_week()").
  449.  
  450. The value of "$weekday" is taken modulo 8 (!) internally to prevent
  451. out-of-range access to the internal array.
  452.  
  453. The strings which are returned are the following:
  454.  
  455.         0       =>      Error
  456.         1       =>      Monday
  457.         2       =>      Tuesday
  458.         3       =>      Wednesday
  459.         4       =>      Thursday
  460.         5       =>      Friday
  461.         6       =>      Saturday
  462.         7       =>      Sunday
  463.  
  464. =head2   =====================================
  465.  
  466. =head2 C<$month_name = month_name_tab($month);>
  467.  
  468. =head2   =====================================
  469.  
  470. This function accesses the internal table of the months' names.
  471.  
  472. It returns the corresponding string for each numeric value of a
  473. month.
  474.  
  475. The value of "$month" is taken modulo 13 (!) internally to prevent
  476. out-of-range access to the internal array.
  477.  
  478. The strings which are returned are the following:
  479.  
  480.          0       =>      Error
  481.          1       =>      January
  482.          2       =>      February
  483.          3       =>      March
  484.          4       =>      April
  485.          5       =>      May
  486.          6       =>      June
  487.          7       =>      July
  488.          8       =>      August
  489.          9       =>      September
  490.         10       =>      October
  491.         11       =>      November
  492.         12       =>      December
  493.  
  494. =head2   ===============================
  495.  
  496. =head2 C<$weekday = decode_day($buffer);>
  497.  
  498. =head2   ===============================
  499.  
  500. This function provides the inverse of the function "day_name_tab()".
  501.  
  502. Whereas "day_name_tab()" takes a number as its argument and returns
  503. a string, "decode_day()" takes a string (of any length) and tries
  504. to match it with the table of the names of days ("Monday", "Tuesday",
  505. and so on) and returns the corresponding number (1..7).
  506.  
  507. Only the first 3 characters are checked (in case-insensitive
  508. manner) for a unique match. If it uniquely identifies the day,
  509. you may also provide only one or two characters:
  510.  
  511.     Name of the day:     Uniquely identified by:     Value returned:
  512.  
  513.            Monday        M, Mo, Mon, ... Monday            1
  514.            Tuesday          Tu, Tue, ... Tuesday           2
  515.            Wednesday     W, We, Wed, ... Wednesday         3
  516.            Thursday         Th, Thu, ... Thursday          4
  517.            Friday        F, Fr, Fri, ... Friday            5
  518.            Saturday         Sa, Sat, ... Saturday          6
  519.            Sunday           Su, Sun, ... Sunday            7
  520.  
  521. If there is no match, zero is returned.
  522.  
  523. This function is roughly equivalent to an associative array:
  524.  
  525.     %day_tab = ( 'Mon' => 1, 'Tue' => 2, 'Wed' => 3, 'Thu' => 4,
  526.                  'Fri' => 5, 'Sat' => 6, 'Sun' => 7);
  527.     $weekday = $day_tab{$buffer};
  528.  
  529. except for the capability of recognizing abbreviations and
  530. to be case-independent.
  531.  
  532. =head2   ===============================
  533.  
  534. =head2 C<$month = decode_month($buffer);>
  535.  
  536. =head2   ===============================
  537.  
  538. This function provides the inverse of the function "month_name_tab()".
  539.  
  540. Whereas "month_name_tab" takes a number as its argument and returns
  541. a string, "decode_month" takes a string (of any length) and tries to
  542. match it with the table of the names of months ("January", "February",
  543. and so on) and returns the corresponding number (1..12).
  544.  
  545. Only the first 3 characters are checked (in case-insensitive
  546. manner) for a unique match. If it uniquely identifies the month,
  547. you may also provide only one or two characters:
  548.  
  549.     Name of the month:     Uniquely identified by:     Value returned:
  550.  
  551.              January          Ja, Jan, ... January           1
  552.              February      F, Fe, Feb, ... February          2
  553.              March                Mar, ... March             3
  554.              April            Ap, Apr, ... April             4
  555.              May                  May, ... May               5
  556.              June                 Jun, ... June              6
  557.              July                 Jul, ... July              7
  558.              August           Au, Aug, ... August            8
  559.              September     S, Se, Sep, ... September         9
  560.              October       O, Oc, Oct, ... October          10
  561.              November      N, No, Nov, ... November         11
  562.              December      D, De, Dec, ... December         12
  563.  
  564. If there is no match, zero is returned.
  565.  
  566. This function is roughly equivalent to an associative array:
  567.  
  568.     %month_tab = ( 'Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4,
  569.                    'May' => 5, 'Jun' => 6, 'Jul' => 7, 'Aug' => 8,
  570.                    'Sep' => 9, 'Oct' => 10, 'Nov' => 11, 'Dec' => 12);
  571.     $month = $month_tab{$buffer};
  572.  
  573. except for the capability of recognizing abbreviations and
  574. to be case-independent.
  575.  
  576. =head2   =======================================
  577.  
  578. =head2 C<($year,$mm,$dd) = decode_date($buffer);>
  579.  
  580. =head2   =======================================
  581.  
  582. Using this function, it is possible to parse dates in almost
  583. any format, provided the date is given as "day - month - year".
  584.  
  585. (To decode dates in U.S. american format, i.e., dates given
  586. as "month - day - year", see the function "decode_date_us()"
  587. in the "Date::DateCalcLib" module.)
  588.  
  589. The day and the year must be given as numbers, the month may be
  590. specified either by a number or an abbreviation (up to 3 characters
  591. long) of the month's name in English (case is ignored).
  592.  
  593. If they uniquely identify the month, one or two letters are
  594. sufficient (e.g. "s" for september or "ja" for january).
  595.  
  596. The year may be abbreviated as well, for instance "95" instead
  597. of "1995". (Year numbers below 100 are incremented by 1900.)
  598.  
  599. Any number of non-digits (i.e., all characters NOT in [0-9]) may
  600. precede the number of the day and follow the number of the year.
  601.  
  602. Any number of non-alphanumeric characters (i.e., all characters NOT
  603. in [A-Za-z0-9]) may separate the number of the day and the month and
  604. the month and the number of the year.
  605.  
  606. If after removing the preceding and trailing non-digit characters
  607. the string consists only of digits, it is automatically mapped to
  608. the day, month and year depending on its length, as intuitively as
  609. possible, as follows:
  610.  
  611.         Length:        Mapping:
  612.           3              dmy
  613.           4              dmyy
  614.           5              dmmyy
  615.           6              ddmmyy
  616.           7              dmmyyyy
  617.           8              ddmmyyyy
  618.  
  619. Example:
  620.  
  621. All the following strings will be recognized as "January 3rd 1964":
  622.  
  623.               3.1.64
  624.               3 1 64
  625.              03.01.64
  626.              03/01/64
  627.             3. Jan 1964
  628.             3. Jan '64
  629.              03-Jan-64
  630.              3.Jan1964
  631.               3Jan64
  632.                3ja64
  633.                3164
  634.  
  635. If the function is unable to extract a valid date from its input,
  636. it returns an empty list.
  637.  
  638. =head2   =================================
  639.  
  640. =head2 C<$days = days_in_month($year,$mm);>
  641.  
  642. =head2   =================================
  643.  
  644. This function accesses the internal table of the months' lengths
  645. and returns the length in days of the given month "$mm" in the
  646. given year "$year".
  647.  
  648. It is necessary to specify the year "$year" since the length of
  649. the month february is 29 instead of 28 in leap years.
  650.  
  651. This function is useful, for example, to calculate the last day
  652. of a month or the last working-day (payday!) of a month.
  653.  
  654. Last working-day of the month (legal holidays not taken into
  655. account):
  656.  
  657.     $dd = days_in_month($year,$mm);
  658.     $dw = day_of_week($year,$mm,$dd) - 1;
  659.     if ($dw > 4)
  660.     {
  661.         ($year,$mm,$dd) = calc_new_date($year,$mm,$dd,4-$dw);
  662.     }
  663.  
  664. Last working-day of the month (legal holidays taken into account):
  665.  
  666. (assuming that the array C<$holiday[$year][$mm][$dd] = 1;> contains
  667. all legal holidays)
  668.  
  669.     $dd = days_in_month($year,$mm);
  670.     while (1)
  671.     {
  672.         while ($holiday[$year][$mm][$dd])
  673.         {
  674.             ($year,$mm,$dd) = calc_new_date($year,$mm,$dd,-1);
  675.         }
  676.         $dw = day_of_week($year,$mm,$dd) - 1;
  677.         if ($dw > 4)
  678.         {
  679.             ($year,$mm,$dd) = calc_new_date($year,$mm,$dd,4-$dw);
  680.         }
  681.         else { last; }
  682.     }
  683.  
  684. The value of "$mm" is taken modulo 13 (!) internally to prevent
  685. out-of-range access to the internal array.
  686.  
  687. The values the internal array contains are the following:
  688.  
  689.     normal             leap
  690.      month             year              year
  691.  
  692.        0                 0                 0
  693.        1                31                31
  694.        2                28                29
  695.        3                31                31
  696.        4                30                30
  697.        5                31                31
  698.        6                30                30
  699.        7                31                31
  700.        8                31                31
  701.        9                30                30
  702.       10                31                31
  703.       11                30                30
  704.       12                31                31
  705.  
  706. =head2   =====================================
  707.  
  708. =head2 C<$version = Date::DateCalc::Version();>
  709.  
  710. =head2   =====================================
  711.  
  712. This function returns a string with the (numeric) version
  713. number of the "DateCalc" extension package.
  714.  
  715. Since this function is not exported, you always have to
  716. qualify it explicitly (i.e., "C<Date::DateCalc::Version()>").
  717.  
  718. This is to avoid possible conflicts with version functions
  719. from other packages.
  720.  
  721. =head1 EXAMPLE
  722.  
  723.     #!perl -w
  724.  
  725.     use strict;
  726.     no strict "vars";
  727.  
  728.     use Date::DateCalc qw(decode_date date_to_short dates_difference);
  729.  
  730.     print "\n";
  731.  
  732.     $ok = 0;
  733.     while (! $ok)
  734.     {
  735.         print "Please enter the date of your birthday (day-month-year): ";
  736.         $date = <STDIN>;
  737.         print "\n";
  738.         if (($yy1,$mm1,$dd1) = decode_date($date))
  739.         {
  740.             $datestr = date_to_short($yy1,$mm1,$dd1);
  741.             print "Your date is: $datestr\n";
  742.             print "\n";
  743.             print "Is that correct? (Yes/No) ";
  744.             $response = <STDIN>;
  745.             print "\n";
  746.             $ok = ($response =~ /^Y/i);
  747.         }
  748.     }
  749.     print "Your birthday is: $datestr\n";
  750.     print "\n";
  751.  
  752.     $ok = 0;
  753.     while (! $ok)
  754.     {
  755.         print "Please enter today's date (day-month-year): ";
  756.         $date = <STDIN>;
  757.         print "\n";
  758.         if (($yy2,$mm2,$dd2) = decode_date($date))
  759.         {
  760.             $datestr = date_to_short($yy2,$mm2,$dd2);
  761.             print "Your date is: $datestr\n";
  762.             print "\n";
  763.             print "Is that correct? (Yes/No) ";
  764.             $response = <STDIN>;
  765.             print "\n";
  766.             $ok = ($response =~ /^Y/i);
  767.         }
  768.     }
  769.     print "Today's date is: $datestr\n";
  770.     print "\n";
  771.  
  772.     $days = dates_difference($yy1,$mm1,$dd1,$yy2,$mm2,$dd2);
  773.     print "You are $days days old.\n";
  774.     print "\n";
  775.  
  776.     __END__
  777.  
  778. =head1 SEE ALSO
  779.  
  780. Date::DateCalcLib(3), perl(1), perlsub(1),
  781. perlmod(1), perlxs(1), perlxstut(1), perlguts(1).
  782.  
  783. =head1 VERSION
  784.  
  785. This man page documents "Date::DateCalc" version 3.2.
  786.  
  787. =head1 AUTHOR
  788.  
  789. Steffen Beyer <sb@sdm.de>.
  790.  
  791. =head1 COPYRIGHT
  792.  
  793. Copyright (c) 1995, 1996, 1997 by Steffen Beyer. All rights reserved.
  794.  
  795. =head1 LICENSE
  796.  
  797. This package is free software; you can redistribute it and/or modify
  798. it under the same terms as Perl itself.
  799.  
  800.