1Pcalc(3)              User Contributed Perl Documentation             Pcalc(3)
2
3
4

NAME

6       Date::Pcalc - Gregorian calendar date calculations
7

MOTTO

9       Keep it small, fast and simple
10

PREFACE

12       This package consists of a library written in pure Perl providing all
13       sorts of date calculations based on the Gregorian calendar (the one
14       used in all western countries today), thereby complying with all
15       relevant norms and standards: ISO/R 2015-1971, DIN 1355 and, to some
16       extent, 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 "DIN 1355" document (in German)).
20
21       This package is meant as a drop-in replacement for Date::Calc(3), the
22       latter of which is written in C and XS and therefore needs a C compiler
23       in order to build and install (which this one doesn't).
24
25       The module of course handles year numbers of 2000 and above correctly
26       ("Year 2000" or "Y2K" compliance) -- actually all year numbers from 1
27       to the largest positive integer representable on your system (which is
28       at least 32767) can be dealt with.
29
30       This is not true, however, for the import/export functions in this
31       package which are an interface to the internal POSIX date and time
32       functions of your system, which can only cover dates in the following
33       ranges:
34
35        01-Jan-1970 00:00:00 GMT .. 19-Jan-2038 03:14:07 GMT [Unix etc.]
36        01-Jan-1904 00:00:00 LT  .. 06-Feb-2040 06:28:15 LT  [MacOS Classic]
37        (LT = local time)
38
39       Note that this package projects the Gregorian calendar back until the
40       year 1 A.D. -- even though the Gregorian calendar was only adopted in
41       1582, mostly by the Catholic European countries, in obedience to the
42       corresponding decree of Pope Gregory XIII in that year.
43
44       Some (mainly protestant) countries continued to use the Julian calendar
45       (used until then) until as late as the beginning of the 20th century.
46
47       Finally, note that this package is not intended to do everything you
48       could ever imagine automagically for you; it is rather intended to
49       serve as a toolbox (in the best of UNIX spirit and traditions) which
50       should, however, always get you where you want to go.
51
52       See the section "RECIPES" at the bottom of this document for solutions
53       to common problems!
54
55       If nevertheless you can't figure out how to solve a particular problem,
56       please let me know! (See e-mail address at the end of this document.)
57

SYNOPSIS

59         use Date::Pcalc qw(
60             Days_in_Year
61             Days_in_Month
62             Weeks_in_Year
63             leap_year
64             check_date
65             check_time
66             check_business_date
67             Day_of_Year
68             Date_to_Days
69             Day_of_Week
70             Week_Number
71             Week_of_Year
72             Monday_of_Week
73             Nth_Weekday_of_Month_Year
74             Standard_to_Business
75             Business_to_Standard
76             Delta_Days
77             Delta_DHMS
78             Delta_YMD
79             Delta_YMDHMS
80             N_Delta_YMD
81             N_Delta_YMDHMS
82             Normalize_DHMS
83             Add_Delta_Days
84             Add_Delta_DHMS
85             Add_Delta_YM
86             Add_Delta_YMD
87             Add_Delta_YMDHMS
88             Add_N_Delta_YMD
89             Add_N_Delta_YMDHMS
90             System_Clock
91             Today
92             Now
93             Today_and_Now
94             This_Year
95             Gmtime
96             Localtime
97             Mktime
98             Timezone
99             Date_to_Time
100             Time_to_Date
101             Easter_Sunday
102             Decode_Month
103             Decode_Day_of_Week
104             Decode_Language
105             Decode_Date_EU
106             Decode_Date_US
107             Fixed_Window
108             Moving_Window
109             Compress
110             Uncompress
111             check_compressed
112             Compressed_to_Text
113             Date_to_Text
114             Date_to_Text_Long
115             English_Ordinal
116             Calendar
117             Month_to_Text
118             Day_of_Week_to_Text
119             Day_of_Week_Abbreviation
120             Language_to_Text
121             Language
122             Languages
123             Decode_Date_EU2
124             Decode_Date_US2
125             Parse_Date
126             ISO_LC
127             ISO_UC
128         );
129
130         use Date::Pcalc qw(:all);
131
132         Days_in_Year
133             $days = Days_in_Year($year,$month);
134
135         Days_in_Month
136             $days = Days_in_Month($year,$month);
137
138         Weeks_in_Year
139             $weeks = Weeks_in_Year($year);
140
141         leap_year
142             if (leap_year($year))
143
144         check_date
145             if (check_date($year,$month,$day))
146
147         check_time
148             if (check_time($hour,$min,$sec))
149
150         check_business_date
151             if (check_business_date($year,$week,$dow))
152
153         Day_of_Year
154             $doy = Day_of_Year($year,$month,$day);
155
156         Date_to_Days
157             $days = Date_to_Days($year,$month,$day);
158
159         Day_of_Week
160             $dow = Day_of_Week($year,$month,$day);
161
162         Week_Number
163             $week = Week_Number($year,$month,$day);          # DEPRECATED
164
165         Week_of_Year
166             ($week,$year) = Week_of_Year($year,$month,$day); # RECOMMENDED
167             $week = Week_of_Year($year,$month,$day);         # DANGEROUS
168
169         Monday_of_Week
170             ($year,$month,$day) = Monday_of_Week($week,$year);
171
172         Nth_Weekday_of_Month_Year
173             if (($year,$month,$day) =
174             Nth_Weekday_of_Month_Year($year,$month,$dow,$n))
175
176         Standard_to_Business
177             ($year,$week,$dow) =
178             Standard_to_Business($year,$month,$day);
179
180         Business_to_Standard
181             ($year,$month,$day) =
182             Business_to_Standard($year,$week,$dow);
183
184         Delta_Days
185             $Dd = Delta_Days($year1,$month1,$day1,
186                              $year2,$month2,$day2);
187
188         Delta_DHMS
189             ($Dd,$Dh,$Dm,$Ds) =
190             Delta_DHMS($year1,$month1,$day1, $hour1,$min1,$sec1,
191                        $year2,$month2,$day2, $hour2,$min2,$sec2);
192
193         Delta_YMD
194             ($Dy,$Dm,$Dd) =
195             Delta_YMD($year1,$month1,$day1,
196                       $year2,$month2,$day2);
197
198         Delta_YMDHMS
199             ($D_y,$D_m,$D_d, $Dh,$Dm,$Ds) =
200             Delta_YMDHMS($year1,$month1,$day1, $hour1,$min1,$sec1,
201                          $year2,$month2,$day2, $hour2,$min2,$sec2);
202
203         N_Delta_YMD
204             ($Dy,$Dm,$Dd) =
205             N_Delta_YMD($year1,$month1,$day1,
206                         $year2,$month2,$day2);
207
208         N_Delta_YMDHMS
209             ($D_y,$D_m,$D_d, $Dhh,$Dmm,$Dss) =
210             N_Delta_YMDHMS($year1,$month1,$day1, $hour1,$min1,$sec1,
211                            $year2,$month2,$day2, $hour2,$min2,$sec2);
212
213         Normalize_DHMS
214             ($Dd,$Dh,$Dm,$Ds) =
215             Normalize_DHMS($Dd,$Dh,$Dm,$Ds);
216
217         Add_Delta_Days
218             ($year,$month,$day) =
219             Add_Delta_Days($year,$month,$day,
220                            $Dd);
221
222         Add_Delta_DHMS
223             ($year,$month,$day, $hour,$min,$sec) =
224             Add_Delta_DHMS($year,$month,$day, $hour,$min,$sec,
225                            $Dd,$Dh,$Dm,$Ds);
226
227         Add_Delta_YM
228             ($year,$month,$day) =
229             Add_Delta_YM($year,$month,$day,
230                          $Dy,$Dm);
231
232         Add_Delta_YMD
233             ($year,$month,$day) =
234             Add_Delta_YMD($year,$month,$day,
235                           $Dy,$Dm,$Dd);
236
237         Add_Delta_YMDHMS
238             ($year,$month,$day, $hour,$min,$sec) =
239             Add_Delta_YMDHMS($year,$month,$day, $hour,$min,$sec,
240                              $D_y,$D_m,$D_d, $Dh,$Dm,$Ds);
241
242         Add_N_Delta_YMD
243             ($year,$month,$day) =
244             Add_N_Delta_YMD($year,$month,$day,
245                             $Dy,$Dm,$Dd);
246
247         Add_N_Delta_YMDHMS
248             ($year,$month,$day, $hour,$min,$sec) =
249             Add_N_Delta_YMDHMS($year,$month,$day, $hour,$min,$sec,
250                                $D_y,$D_m,$D_d, $Dhh,$Dmm,$Dss);
251
252         System_Clock
253             ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
254             System_Clock([$gmt]);
255
256         Today
257             ($year,$month,$day) = Today([$gmt]);
258
259         Now
260             ($hour,$min,$sec) = Now([$gmt]);
261
262         Today_and_Now
263             ($year,$month,$day, $hour,$min,$sec) = Today_and_Now([$gmt]);
264
265         This_Year
266             $year = This_Year([$gmt]);
267
268         Gmtime
269             ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
270             Gmtime([time]);
271
272         Localtime
273             ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
274             Localtime([time]);
275
276         Mktime
277             $time = Mktime($year,$month,$day, $hour,$min,$sec);
278
279         Timezone
280             ($D_y,$D_m,$D_d, $Dh,$Dm,$Ds, $dst) = Timezone([time]);
281
282         Date_to_Time
283             $time = Date_to_Time($year,$month,$day, $hour,$min,$sec);
284
285         Time_to_Date
286             ($year,$month,$day, $hour,$min,$sec) = Time_to_Date([time]);
287
288         Easter_Sunday
289             ($year,$month,$day) = Easter_Sunday($year);
290
291         Decode_Month
292             if ($month = Decode_Month($string[,$lang]))
293
294         Decode_Day_of_Week
295             if ($dow = Decode_Day_of_Week($string[,$lang]))
296
297         Decode_Language
298             if ($lang = Decode_Language($string))
299
300         Decode_Date_EU
301             if (($year,$month,$day) = Decode_Date_EU($string[,$lang]))
302
303         Decode_Date_US
304             if (($year,$month,$day) = Decode_Date_US($string[,$lang]))
305
306         Fixed_Window
307             $year = Fixed_Window($yy);
308
309         Moving_Window
310             $year = Moving_Window($yy);
311
312         Compress
313             $date = Compress($year,$month,$day);
314
315         Uncompress
316             if (($century,$year,$month,$day) = Uncompress($date))
317
318         check_compressed
319             if (check_compressed($date))
320
321         Compressed_to_Text
322             $string = Compressed_to_Text($date[,$lang]);
323
324         Date_to_Text
325             $string = Date_to_Text($year,$month,$day[,$lang]);
326
327         Date_to_Text_Long
328             $string = Date_to_Text_Long($year,$month,$day[,$lang]);
329
330         English_Ordinal
331             $string = English_Ordinal($number);
332
333         Calendar
334             $string = Calendar($year,$month[,$orthodox[,$lang]]);
335
336         Month_to_Text
337             $string = Month_to_Text($month[,$lang]);
338
339         Day_of_Week_to_Text
340             $string = Day_of_Week_to_Text($dow[,$lang]);
341
342         Day_of_Week_Abbreviation
343             $string = Day_of_Week_Abbreviation($dow[,$lang]);
344
345         Language_to_Text
346             $string = Language_to_Text($lang);
347
348         Language
349             $lang = Language();
350             Language($lang);               # DEPRECATED
351             $oldlang = Language($newlang); # DEPRECATED
352
353         Languages
354             $max_lang = Languages();
355
356         Decode_Date_EU2
357             if (($year,$month,$day) = Decode_Date_EU2($string[,$lang]))
358
359         Decode_Date_US2
360             if (($year,$month,$day) = Decode_Date_US2($string[,$lang]))
361
362         Parse_Date
363             if (($year,$month,$day) = Parse_Date($string[,$lang]))
364
365         ISO_LC
366             $lower = ISO_LC($string);
367
368         ISO_UC
369             $upper = ISO_UC($string);
370
371         Version
372             $string = Date::Pcalc::Version();
373

IMPORTANT NOTES

375       (See the section "RECIPES" at the bottom of this document for solutions
376       to common problems!)
377
378       • "Year 2000" ("Y2K") compliance
379
380         The upper limit for any year number in this module is only given by
381         the size of the largest positive integer that can be represented in a
382         scalar variable on your system, which is at least 32767, according to
383         the ANSI C standard, on which Perl is based (exceptions see below).
384
385         In order to simplify calculations, this module projects the gregorian
386         calendar back until the year 1 A.D. -- i.e., back BEYOND the year
387         1582 when this calendar was first decreed by the Catholic Pope
388         Gregory XIII!
389
390         Therefore, BE SURE TO ALWAYS SPECIFY "1998" WHEN YOU MEAN "1998", for
391         instance, and DO NOT WRITE "98" INSTEAD, because this will in fact
392         perform a calculation based on the year "98" A.D. and NOT "1998"!
393
394         An exception from this rule are the functions which contain the word
395         "compress" in their names (which can only handle years between 1970
396         and 2069 and also accept the abbreviations "00" to "99"), and the
397         functions whose names begin with "Decode_Date_" (which translate year
398         numbers below 100 using a technique known as "moving window").
399
400         If you want to convert a two-digit year number into a full-fledged,
401         four-digit (at least for some years to come ";-)") year number, use
402         the two functions "Fixed_Window()" and "Moving_Window()" (see their
403         description further below).
404
405         Note also that the following import/export functions (which are
406         interfaces to the POSIX functions "time()", "gmtime()", "localtime()"
407         and "mktime()" or (the last two) substitutes for the BSD function
408         "timegm()" and the POSIX function "gmtime()") have a very limited
409         range of representable dates (in contrast to all other functions in
410         this package, which cover virtually any date including and after
411         January 1st 1 A.D.):
412
413                       System_Clock()
414                       Today()
415                       Now()
416                       Today_and_Now()
417                       This_Year()
418                       Gmtime()
419                       Localtime()
420                       Mktime()
421                       Timezone()
422                       Date_to_Time()
423                       Time_to_Date()
424
425         These functions can only deal with dates in the range from
426         01-Jan-1970 00:00:00 GMT to 19-Jan-2038 03:14:07 GMT (the latter
427         limit is only authoritative on 32 bit systems, however, and can (in
428         principle, through a few code changes) be extended somewhat ":-)" on
429         64 bit systems).
430
431         On MacOS Classic, the valid range of dates is between (both included)
432         01-Jan-1904 00:00:00 (local time) to 06-Feb-2040 06:28:15 (local
433         time).
434
435         Note further that the function "Easter_Sunday()" can only be used for
436         years in the range 1583 to 2299.
437
438       • POSIX functions
439
440         Note that the following functions
441
442                       Gmtime()
443                       Localtime()
444                       Mktime()
445                       Timezone()
446
447         are actually wrappers around or based upon the corresponding POSIX
448         functions "time()", "gmtime()", "localtime()" and "mktime()".
449
450         As such, they depend on local settings of the underlying machine such
451         as e.g. the system clock, the time zone and the locale.
452
453         Their results can therefore sometimes be unexpected or counter-
454         intuitive.
455
456         Therefore, no support can be provided for these functions.
457
458         They are supplied "as is", purely for the sake of interoperability.
459
460         Use at your own risk. (You have been warned!)
461
462       • First index
463
464         ALL ranges in this module start with "1", NOT "0"!
465
466         I.e., the day of month, day of week, day of year, month of year, week
467         of year, first valid year number and language ALL start counting at
468         one, NOT zero!
469
470         The only exception is the function ""Week_Number()"", which may in
471         fact return "0" when the given date actually lies in the last week of
472         the PREVIOUS year, and of course the numbers for hours (0..23),
473         minutes (0..59) and seconds (0..59).
474
475       • Function naming conventions
476
477         Function names completely in lower case indicate a boolean return
478         value.
479
480       • Boolean values
481
482         Boolean values returned from functions in this module are always a
483         numeric zero ("0") for "false" and a numeric one ("1") for "true".
484
485       • Exception handling
486
487         The functions in this module will usually die with a corresponding
488         error message if their input parameters, intermediate results or
489         output values are out of range.
490
491         The following functions handle errors differently:
492
493           -  check_date()
494           -  check_time()
495           -  check_business_date()
496           -  check_compressed()
497
498         (which return a "false" return value when the given input does not
499         represent a valid date or time),
500
501           -  Nth_Weekday_of_Month_Year()
502
503         (which returns an empty list if the requested 5th day of week does
504         not exist),
505
506           -  Decode_Month()
507           -  Decode_Day_of_Week()
508           -  Decode_Language()
509           -  Fixed_Window()
510           -  Moving_Window()
511           -  Compress()
512
513         (which return "0" upon failure or invalid input), and
514
515           -  Decode_Date_EU()
516           -  Decode_Date_US()
517           -  Decode_Date_EU2()
518           -  Decode_Date_US2()
519           -  Parse_Date()
520           -  Uncompress()
521
522         (which return an empty list upon failure or invalid input).
523
524         Note that you can always catch an exception thrown by any of the
525         functions in this module and handle it yourself by enclosing the
526         function call in an ""eval"" with curly brackets and checking the
527         special variable "$@" (see "eval" in perlfunc(1) for details).
528

DESCRIPTION

530       • "use Date::Pcalc qw( Days_in_Year Days_in_Month ... );"
531
532       • "use Date::Pcalc qw(:all);"
533
534         You can either specify the functions you want to import explicitly by
535         enumerating them between the parentheses of the ""qw()"" operator, or
536         you can use the "":all"" tag instead to import ALL available
537         functions.
538
539       • "$days = Days_in_Year($year,$month);"
540
541         This function returns the sum of the number of days in the months
542         starting with January up to and including "$month" in the given year
543         "$year".
544
545         I.e., ""Days_in_Year(1998,1)"" returns "31", ""Days_in_Year(1998,2)""
546         returns "59", ""Days_in_Year(1998,3)"" returns "90", and so on.
547
548         Note that ""Days_in_Year($year,12)"" returns the number of days in
549         the given year "$year", i.e., either "365" or "366".
550
551       • "$days = Days_in_Month($year,$month);"
552
553         This function returns the number of days in the given month "$month"
554         of the given year "$year".
555
556         The year must always be supplied, even though it is only needed when
557         the month is February, in order to determine whether it is a leap
558         year or not.
559
560         I.e., ""Days_in_Month(1998,1)"" returns "31",
561         ""Days_in_Month(1998,2)"" returns "28", ""Days_in_Month(2000,2)""
562         returns "29", ""Days_in_Month(1998,3)"" returns "31", and so on.
563
564       • "$weeks = Weeks_in_Year($year);"
565
566         This function returns the number of weeks in the given year "$year",
567         i.e., either "52" or "53".
568
569       • "if (leap_year($year))"
570
571         This function returns "true" ("1") if the given year "$year" is a
572         leap year and "false" ("0") otherwise.
573
574       • "if (check_date($year,$month,$day))"
575
576         This function returns "true" ("1") if the given three numerical
577         values "$year", "$month" and "$day" constitute a valid date, and
578         "false" ("0") otherwise.
579
580       • "if (check_time($hour,$min,$sec))"
581
582         This function returns "true" ("1") if the given three numerical
583         values "$hour", "$min" and "$sec" constitute a valid time ("0 <=
584         $hour < 24", "0 <= $min < 60" and "0 <= $sec < 60"), and "false"
585         ("0") otherwise.
586
587       • "if (check_business_date($year,$week,$dow))"
588
589         This function returns "true" ("1") if the given three numerical
590         values "$year", "$week" and "$dow" constitute a valid date in
591         business format, and "false" ("0") otherwise.
592
593         Beware that this function does NOT compute whether a given date is a
594         business day (i.e., Monday to Friday)!
595
596         To do so, use ""(Day_of_Week($year,$month,$day) < 6)"" instead.
597
598       • "$doy = Day_of_Year($year,$month,$day);"
599
600         This function returns the (relative) number of the day of the given
601         date in the given year.
602
603         E.g., ""Day_of_Year($year,1,1)"" returns "1",
604         ""Day_of_Year($year,2,1)"" returns "32", and
605         ""Day_of_Year($year,12,31)"" returns either "365" or "366".
606
607         The day of year is sometimes also referred to as the Julian day (or
608         date), although it has nothing to do with the Julian calendar, the
609         calendar which was used before the Gregorian calendar.
610
611         In order to convert the number returned by this function back into a
612         date, use the function ""Add_Delta_Days()"" (described further
613         below), as follows:
614
615           $doy = Day_of_Year($year,$month,$day);
616           ($year,$month,$day) = Add_Delta_Days($year,1,1, $doy - 1);
617
618       • "$days = Date_to_Days($year,$month,$day);"
619
620         This function returns the (absolute) number of the day of the given
621         date, where counting starts at the 1st of January of the year 1 A.D.
622
623         I.e., ""Date_to_Days(1,1,1)"" returns "1", ""Date_to_Days(1,12,31)""
624         returns "365", ""Date_to_Days(2,1,1)"" returns "366",
625         ""Date_to_Days(1998,5,1)"" returns "729510", and so on.
626
627         This is sometimes also referred to (not quite correctly) as the
628         Julian date (or day). This may cause confusion, because also the
629         number of the day in a year (from 1 to 365 or 366) is frequently
630         called the "Julian day".
631
632         More confusing still, this has nothing to do with the Julian
633         calendar, which was used BEFORE the Gregorian calendar.
634
635         The Julian calendar was named after famous Julius Caesar, who had
636         instituted it in Roman times. The Julian calendar is less precise
637         than the Gregorian calendar because it has too many leap years
638         compared to the true mean length of a year (but the Gregorian
639         calendar also still has one day too much every 5000 years). Anyway,
640         the Julian calendar was better than what existed before, because
641         rulers had often changed the calendar used until then in arbitrary
642         ways, in order to lengthen their own reign, for instance.
643
644         In order to convert the number returned by this function back into a
645         date, use the function ""Add_Delta_Days()"" (described further
646         below), as follows:
647
648           $days = Date_to_Days($year,$month,$day);
649           ($year,$month,$day) = Add_Delta_Days(1,1,1, $days - 1);
650
651       • "$dow = Day_of_Week($year,$month,$day);"
652
653         This function returns the number of the day of week of the given
654         date.
655
656         The function returns "1" for Monday, "2" for Tuesday and so on until
657         "7" for Sunday.
658
659         Note that in the Hebrew calendar (on which the Christian calendar is
660         based), the week starts with Sunday and ends with the Sabbath or
661         Saturday (where according to the Genesis (as described in the Bible)
662         the Lord rested from creating the world).
663
664         In medieval times, Catholic Popes have decreed the Sunday to be the
665         official day of rest, in order to dissociate the Christian from the
666         Hebrew belief.
667
668         It appears that this actually happened with the Emperor Constantin,
669         who converted to Christianity but still worshipped the Sun god and
670         therefore moved the Christian sabbath to the day of the Sun.
671
672         Nowadays, the Sunday AND the Saturday are commonly considered (and
673         used as) days of rest, usually referred to as the "week-end".
674
675         Consistent with this practice, current norms and standards (such as
676         ISO/R 2015-1971, DIN 1355 and ISO 8601) define the Monday as the
677         first day of the week.
678
679       • "$week = Week_Number($year,$month,$day);"
680
681         This function returns the number of the week the given date lies in.
682
683         If the given date lies in the LAST week of the PREVIOUS year, "0" is
684         returned.
685
686         If the given date lies in the FIRST week of the NEXT year,
687         ""Weeks_in_Year($year) + 1"" is returned.
688
689       • "($week,$year) = Week_of_Year($year,$month,$day);"
690
691         This function returns the number of the week the given date lies in,
692         as well as the year that week belongs to.
693
694         I.e., if the given date lies in the LAST week of the PREVIOUS year,
695         ""(Weeks_in_Year($year-1), $year-1)"" is returned.
696
697         If the given date lies in the FIRST week of the NEXT year, ""(1,
698         $year+1)"" is returned.
699
700         Otherwise, ""(Week_Number($year,$month,$day), $year)"" is returned.
701
702       • "$week = Week_of_Year($year,$month,$day);"
703
704         In scalar context, this function returns just the week number. This
705         allows you to write ""$week = Week_of_Year($year,$month,$day);""
706         instead of ""($week) = Week_of_Year($year,$month,$day);"" (note the
707         parentheses around "$week").
708
709         If the given date lies in the LAST week of the PREVIOUS year,
710         ""Weeks_in_Year($year-1)"" is returned.
711
712         If the given date lies in the FIRST week of the NEXT year, "1" is
713         returned.
714
715         Otherwise the return value is identical with that of
716         ""Week_Number($year,$month,$day)"".
717
718         BEWARE that using this function in scalar context is a DANGEROUS
719         feature, because without knowing which year the week belongs to, you
720         might inadvertently assume the wrong one!
721
722         If for instance you are iterating through an interval of dates, you
723         might assume that the week always belongs to the same year as the
724         given date, which unfortunately is WRONG in some cases!
725
726         In many years, the 31st of December for instance belongs to week
727         number one of the FOLLOWING year. Assuming that the year is the same
728         as your date (31st of December, in this example), sends you back to
729         the first week of the CURRENT year - the Monday of which, by the way,
730         in case of bad luck, might actually lie in the year BEFORE the
731         current year!
732
733         This actually happens in 2002, for example.
734
735         So you always need to provide the correct corresponding year number
736         by other means, keeping track of it yourself.
737
738         In case you do not understand this, never mind, but then simply DO
739         NOT USE this function in scalar context!
740
741       • "($year,$month,$day) = Monday_of_Week($week,$year);"
742
743         This function returns the date of the first day of the given week,
744         i.e., the Monday.
745
746         "$year" must be greater than or equal to "1", and "$week" must lie in
747         the range "1" to ""Weeks_in_Year($year)"".
748
749         Note that you can write ""($year,$month,$day) =
750         Monday_of_Week(Week_of_Year($year,$month,$day));"" in order to
751         calculate the date of the Monday of the same week as the given date.
752
753         If you want to calculate any other day of week in the same week as a
754         given date, use
755
756           @date = Add_Delta_Days(Monday_of_Week(Week_of_Year(@date)),$offset);
757
758         where "$offset = 1" for Tuesday, 2 for Wednesday etc.
759
760       • "if (($year,$month,$day) =
761         Nth_Weekday_of_Month_Year($year,$month,$dow,$n))"
762
763         This function calculates the date of the "$n"th day of week "$dow" in
764         the given month "$month" and year "$year"; such as, for example, the
765         3rd Thursday of a given month and year.
766
767         This can be used to send a notification mail to the members of a
768         group which meets regularly on every 3rd Thursday of a month, for
769         instance.
770
771         (See the section "RECIPES" near the end of this document for a code
772         snippet to actually do so.)
773
774         "$year" must be greater than or equal to "1", "$month" must lie in
775         the range "1" to "12", "$dow" must lie in the range "1" to "7" and
776         "$n" must lie in the range "1" to "5", or a fatal error (with
777         appropriate error message) occurs.
778
779         The function returns an empty list when the 5th of a given day of
780         week does not exist in the given month and year.
781
782       • "($year,$week,$dow) = Standard_to_Business($year,$month,$day);"
783
784         This function converts a given date from standard notation (year,
785         month, day (of month)) to business notation (year, week, day of
786         week).
787
788       • "($year,$month,$day) = Business_to_Standard($year,$week,$dow);"
789
790         This function converts a given date from business notation (year,
791         week, day of week) to standard notation (year, month, day (of
792         month)).
793
794       • "$Dd = Delta_Days($year1,$month1,$day1, $year2,$month2,$day2);"
795
796         This function returns the difference in days between the two given
797         dates.
798
799         The result is positive if the two dates are in chronological order,
800         i.e., if date #1 comes chronologically BEFORE date #2, and negative
801         if the order of the two dates is reversed.
802
803         The result is zero if the two dates are identical.
804
805       • "($Dd,$Dh,$Dm,$Ds) = Delta_DHMS($year1,$month1,$day1,
806         $hour1,$min1,$sec1, $year2,$month2,$day2, $hour2,$min2,$sec2);"
807
808         This function returns the difference in days, hours, minutes and
809         seconds between the two given dates with times.
810
811         All four return values will be positive if the two dates are in
812         chronological order, i.e., if date #1 comes chronologically BEFORE
813         date #2, and negative (in all four return values!) if the order of
814         the two dates is reversed.
815
816         This is so that the two functions ""Delta_DHMS()"" and
817         ""Add_Delta_DHMS()"" (description see further below) are
818         complementary, i.e., mutually inverse:
819
820           Add_Delta_DHMS(@date1,@time1, Delta_DHMS(@date1,@time1, @date2,@time2))
821
822         yields ""(@date2,@time2)"" again, whereas
823
824           Add_Delta_DHMS(@date2,@time2,
825               map(-$_, Delta_DHMS(@date1,@time1, @date2,@time2)))
826
827         yields ""(@date1,@time1)"", and
828
829           Delta_DHMS(@date1,@time1, Add_Delta_DHMS(@date1,@time1, @delta))
830
831         yields "@delta" again.
832
833         The result is zero (in all four return values) if the two dates and
834         times are identical.
835
836       • "($Dy,$Dm,$Dd) = Delta_YMD($year1,$month1,$day1,
837         $year2,$month2,$day2);"
838
839         This function returns the vector
840
841             ( $year2 - $year1, $month2 - $month1, $day2 - $day1 )
842
843         This is called the "one-by-one" semantics.
844
845         Adding the result of this function to the first date always yields
846         the second date again, and adding the negative result (where the
847         signs of all elements of the result vector have been flipped) to the
848         second date gives the first date. See also the description of the
849         function "Add_Delta_YMD()" further below.
850
851         Example:
852
853           (6,2,-30) == Delta_YMD(1996,1,31, 2002,3,1]);
854
855           [1996,1,31] + ( 6, 2,-30) = [2002,3, 1]
856           [2002,3, 1] + (-6,-2, 30) = [1996,1,31]
857
858         An error occurs if any of the two given dates is invalid.
859
860       • "($D_y,$D_m,$D_d, $Dh,$Dm,$Ds) = Delta_YMDHMS($year1,$month1,$day1,
861         $hour1,$min1,$sec1, $year2,$month2,$day2, $hour2,$min2,$sec2);"
862
863         This function is based on the function "Delta_YMD()" above but
864         additionally calculates the time difference. When a carry over from
865         the time difference occurs, the value of "$D_d" is adjusted
866         accordingly, thus giving the correct total date/time difference.
867
868         Arguments are expected to be in chronological order to yield a
869         (usually) positive result.
870
871         In any case, adding the result of this function to the first
872         date/time value ("$year1,$month1,$day1," "$hour1,$min1,$sec1") always
873         gives the second date/time value ("$year2,$month2,$day2,"
874         "$hour2,$min2,$sec2") again, and adding the negative result (with the
875         signs of all elements of the result vector flipped) to the second
876         date/time value gives the first date/time value.
877
878         See the function "Add_Delta_YMDHMS()" further below for adding a
879         date/time value and a date/time difference.
880
881         An error occurs if any of the given two date/time values is invalid.
882
883       • "($Dy,$Dm,$Dd) = N_Delta_YMD($year1,$month1,$day1,
884         $year2,$month2,$day2);"
885
886         This function returns the difference between the two given dates in a
887         more intuitive way (as far as possible - more on that see a bit
888         further below) than the function "Delta_YMD()" described above.
889
890         The "N" which precedes its name is meant to signify "new" or
891         "normalized".
892
893         This function is loosely based on recipe #17 b) (see the section
894         "RECIPES" below near the end of this document).
895
896         However, the code of recipe #17 b) actually does not treat positive
897         and negative values symmetrically and consistently.
898
899         This new routine does.
900
901         The return values of this function are guaranteed to all have the
902         same sign (or to be zero). This is why this function is called
903         "normalized".
904
905         Moreover, the results are guaranteed to be "minimal", in the sense
906         that "|$Dm| < 12" and "|$Dd| < 31" (which is equivalent to $Dm lying
907         in the range "[-11..+11]" and $Dd lying in the range "[-30..+30]").
908
909         When the results are applied (i.e., added) to the first given date in
910         a left-to-right order, the second given date is guaranteed to be
911         obtained, provided that intermediary results are truncated, as done
912         by the function "Add_Delta_YM()" (see further below), i.e., that
913         invalid intermediate dates such as e.g. [2009,2,31] will
914         automatically be transformed into [2009,2,28] (and not "wrapped" into
915         the next month, e.g. to [2009,3,3]).
916
917         This is called the "left-to-right with truncation" semantics.
918
919         Note that reversing the order of the given dates and reversing the
920         sign of each of the result values will not always add up.
921
922         Consider the dates [2008,2,29] and [2009,2,1]: their difference is
923         (0,11,3) ([2008,2,29] plus 11 months is [2009,1,29], which plus 3
924         days is [2009,2,1]), but the difference between [2009,2,1] and
925         [2008,2,29] is (0,-11,-1), and not (0,-11,-3) ([2009,2,1] minus 11
926         months is [2008,3,1], which minus one day is [2008,2,29]).
927
928         Another example: The difference between [1996,2,29] and [1997,2,28]
929         is (1,0,0) (observe the truncation of the invalid date [1997,2,29] to
930         [1997,2,28] here!), whereas the difference between [1997,2,28] and
931         [1996,2,29] is (0,-11,-28) ([1997,2,28] minus 11 months is
932         [1996,3,28], which minus 28 days is not [1996,3,0] but of course
933         [1996,2,29]).
934
935         "Benign" examples such as for instance the difference between
936         [1964,1,3] and [2009,9,10] are completely symmetrical: The difference
937         in this example is (45,8,7), whereas the difference between
938         [2009,9,10] and [1964,1,3] is (-45,-8,-7), as would normally be
939         expected. In this example, the result is also the same as the one
940         returned by "Delta_YMD()".
941
942         All these counter-intuitive effects are due to the fact that months
943         (and due to leap years, also years) do not correspond to a fixed
944         number of days, so the semantics of "plus one month" or "plus one
945         year" are in fact undefined.
946
947         The present function is an attempt to provide a definition which is
948         intuitive most of the time, and at least consistent the rest of the
949         time.
950
951         Other definitions are of course possible, but most often lead to
952         contradictions (e.g., the results and the given first date do not add
953         up to the second given date).
954
955         See the file "datecalc.pl" in the "examples" subdirectory of this
956         distribution for a way to play around with this function, or go to
957         http://www.engelschall.com/u/sb/datecalc/ for the online version.
958
959         An error occurs if any of the two given dates is invalid, or if any
960         intermediate result leads to an invalid date (this does not apply to
961         truncation, however, as explained above).
962
963       • "($D_y,$D_m,$D_d, $Dhh,$Dmm,$Dss) =
964         N_Delta_YMDHMS($year1,$month1,$day1, $hour1,$min1,$sec1,
965         $year2,$month2,$day2, $hour2,$min2,$sec2);"
966
967         This function essentially does the same as the function
968         "N_Delta_YMD()" described immediately above, except that also the
969         difference in hours, minutes and seconds is taken into account.
970
971         This function is loosely based on recipe #17 a) (see the section
972         "RECIPES" below near the end of this document).
973
974         However, the code of recipe #17 a) actually does not treat positive
975         and negative values symmetrically and consistently.
976
977         This new routine does.
978
979         The return values of this function (including the time differences)
980         are guaranteed to all have the same sign (or to be zero). This is the
981         reason for the "N" that precedes the name of this function, which is
982         intended to mean "normalized" (or "new").
983
984         Moreover, the results are guaranteed to be "minimal", in the sense
985         that "|$D_m| < 12", "|$D_d| < 31", "|$Dhh| < 24", "|$Dmm| < 60" and
986         "|$Dss| < 60" (which is equivalent to $D_m lying in the range
987         "[-11..+11]", $D_d lying in the range "[-30..+30]", $Dhh lying in the
988         range "[-23..+23]", and $Dmm and $Dss both lying in the range
989         "[-59..+59]").
990
991       • "($Dd,$Dh,$Dm,$Ds) = Normalize_DHMS($Dd,$Dh,$Dm,$Ds);"
992
993         This function takes four arbitrary values for days, hours, minutes
994         and seconds (which may have different signs) and renormalizes them so
995         that the values for hours, minutes and seconds will lie in the ranges
996         "[-23..23]", "[-59..59]" and "[-59..59]", respectively, and so that
997         all four values have the same sign (or are zero).
998
999         The given values are left untouched, i.e., unchanged.
1000
1001       • "($year,$month,$day) = Add_Delta_Days($year,$month,$day, $Dd);"
1002
1003         This function has two principal uses:
1004
1005         First, it can be used to calculate a new date, given an initial date
1006         and an offset (which may be positive or negative) in days, in order
1007         to answer questions like "today plus 90 days -- which date gives
1008         that?".
1009
1010         (In order to add a weeks offset, simply multiply the weeks offset
1011         with "7" and use that as your days offset.)
1012
1013         Second, it can be used to convert the canonical representation of a
1014         date, i.e., the number of that day (where counting starts at the 1st
1015         of January in 1 A.D.), back into a date given as year, month and
1016         day.
1017
1018         Because counting starts at "1", you will actually have to subtract
1019         "1" from the canonical date in order to get back the original date:
1020
1021           $canonical = Date_to_Days($year,$month,$day);
1022
1023           ($year,$month,$day) = Add_Delta_Days(1,1,1, $canonical - 1);
1024
1025         Moreover, this function is the inverse of the function
1026         ""Delta_Days()"":
1027
1028           Add_Delta_Days(@date1, Delta_Days(@date1, @date2))
1029
1030         yields "@date2" again, whereas
1031
1032           Add_Delta_Days(@date2, -Delta_Days(@date1, @date2))
1033
1034         yields "@date1", and
1035
1036           Delta_Days(@date1, Add_Delta_Days(@date1, $delta))
1037
1038         yields "$delta" again.
1039
1040       • "($year,$month,$day, $hour,$min,$sec) =
1041         Add_Delta_DHMS($year,$month,$day, $hour,$min,$sec, $Dd,$Dh,$Dm,$Ds);"
1042
1043         This function serves to add a days, hours, minutes and seconds offset
1044         to a given date and time, in order to answer questions like "today
1045         and now plus 7 days but minus 5 hours and then plus 30 minutes, what
1046         date and time gives that?":
1047
1048           ($y,$m,$d,$H,$M,$S) = Add_Delta_DHMS(Today_and_Now(), +7,-5,+30,0);
1049
1050       • "($year,$month,$day) = Add_Delta_YM($year,$month,$day, $Dy,$Dm);"
1051
1052         This function can be used to add a year and/or month offset to a
1053         given date.
1054
1055         In contrast to the function described immediately below
1056         (""Add_Delta_YMD()""), this function does no "wrapping" into the next
1057         month if the day happens to lie outside the valid range for the
1058         resulting year and month (after adding the year and month offsets).
1059         Instead, it simply truncates the day to the last possible day of the
1060         resulting month.
1061
1062         Examples:
1063
1064         Adding an offset of 0 years, 1 month to the date [1999,1,31] would
1065         result in the (invalid) date [1999,2,31]. The function replaces this
1066         result by the (valid) date [1999,2,28].
1067
1068         Adding an offset of 1 year, 1 month to the same date [1999,1,31] as
1069         above would result in the (still invalid) date [2000,2,31]. The
1070         function replaces this result by the valid date [2000,2,29] (because
1071         2000 is a leap year).
1072
1073         Note that the year and month offsets can be negative, and that they
1074         can have different signs.
1075
1076         If you want to additionally add a days offset, use the function
1077         ""Add_Delta_Days()"" before or after calling ""Add_Delta_YM()"":
1078
1079           @date2 = Add_Delta_Days( Add_Delta_YM(@date1, $Dy,$Dm), $Dd );
1080           @date2 = Add_Delta_YM( Add_Delta_Days(@date1, $Dd), $Dy,$Dm );
1081
1082         Note that your result may depend on the order in which you call these
1083         two functions!
1084
1085         Consider the date [1999,2,28] and the offsets 0 years, 1 month and 1
1086         day:
1087
1088         [1999,2,28] plus one month is [1999,3,28], plus one day is
1089         [1999,3,29]. [1999,2,28] plus one day is [1999,3,1], plus one month
1090         is [1999,4,1].
1091
1092         (Which is also the reason why the ""Add_Delta_YM()"" function does
1093         not allow to add a days offset, because this would actually require
1094         TWO functions: One for adding the days offset BEFORE and one for
1095         adding it AFTER applying the year/month offsets.)
1096
1097         An error occurs if the initial date is not valid.
1098
1099         Note that ""Add_Delta_YM( Add_Delta_YM(@date, $Dy,$Dm), -$Dy,-$Dm
1100         );"" will not, in general, return the original date "@date" (consider
1101         the examples given above!).
1102
1103       • "($year,$month,$day) = Add_Delta_YMD($year,$month,$day,
1104         $Dy,$Dm,$Dd);"
1105
1106         This function serves to add a years, months and days offset to a
1107         given date.
1108
1109         (In order to add a weeks offset, simply multiply the weeks offset
1110         with "7" and add this number to your days offset.)
1111
1112         Note that the three offsets for years, months and days are applied
1113         independently from each other. This also allows them to have
1114         different signs.
1115
1116         The years and months offsets are applied first, and the days offset
1117         is applied last.
1118
1119         If the resulting date happens to fall on a day after the end of the
1120         resulting month, like the 32nd of April or the 30th of February, then
1121         the date is simply counted forward into the next month (possibly also
1122         into the next year) by the number of excessive days (e.g., the 32nd
1123         of April will become the 2nd of May).
1124
1125         BEWARE that this behaviour differs from that of previous versions of
1126         this module! In previous versions, the day was simply truncated to
1127         the maximum number of days in the resulting month.
1128
1129         If you want the previous behaviour, use the new function
1130         ""Add_Delta_YM()"" (described immediately above) plus the function
1131         ""Add_Delta_Days()"" instead.
1132
1133         BEWARE also that because a year and a month offset is not equivalent
1134         to a fixed number of days, the transformation performed by this
1135         function is NOT ALWAYS REVERSIBLE!
1136
1137         This is in contrast to the functions ""Add_Delta_Days()"" and
1138         ""Add_Delta_DHMS()"", which are fully and truly reversible (with the
1139         help of the functions ""Delta_Days()"" and ""Delta_DHMS()"", for
1140         instance).
1141
1142         Note that for this same reason,
1143
1144           @date = Add_Delta_YMD(
1145                   Add_Delta_YMD(@date, $Dy,$Dm,$Dd), -$Dy,-$Dm,-$Dd);
1146
1147         will in general NOT return the initial date "@date", even though
1148
1149           @date2 = Add_Delta_YMD( @date1, Delta_YMD(@date1, @date2) );
1150
1151         will always return the second date "@date2", and
1152
1153           @date1 = Add_Delta_YMD( @date2, map(-$_, Delta_YMD(@date1, @date2)) );
1154
1155         which is the same as
1156
1157           @date1 = Add_Delta_YMD( @date2, Delta_YMD(@date2, @date1) );
1158
1159         will always return the first date "@date1".
1160
1161         Examples:
1162
1163           [1996,1,31] + ( 6, 1,-2) = [2002,3,1]
1164           [2002,3, 1] + (-6,-1, 2) = [1996,2,3] # EXPECTED: [1996,1,31]
1165
1166           (6,2,-30) == Delta_YMD(1996,1,31, 2002,3,1);
1167
1168           [1996,1,31] + ( 6, 2,-30) = [2002,3, 1]
1169           [2002,3, 1] + (-6,-2, 30) = [1996,1,31] # OK
1170
1171           (6,1,-2) == Delta_YMD(1996,2,3, 2002,3,1);
1172
1173           [1996,2,3] + ( 6, 1,-2) = [2002,3,1]
1174           [2002,3,1] + (-6,-1, 2) = [1996,2,3] # OK
1175
1176         Note that this is NOT a program bug but NECESSARILY so, because of
1177         the variable lengths of years and months, and hence because of the
1178         ambiguity of the difference between two dates in terms of years,
1179         months and days, i.e., the fact that the difference between two dates
1180         can be expressed in more than one way:
1181
1182           [1996,1,31] + (6,1, -2) = [2002,3,1]
1183           [1996,1,31] + (6,2,-30) = [2002,3,1]
1184
1185       • "($year,$month,$day, $hour,$min,$sec) =
1186         Add_Delta_YMDHMS($year,$month,$day, $hour,$min,$sec, $D_y,$D_m,$D_d,
1187         $Dh,$Dm,$Ds);"
1188
1189         Same as the function above, except that a time offset may be given in
1190         addition to the year, month and day offset.
1191
1192       • "($year,$month,$day) = Add_N_Delta_YMD($year,$month,$day,
1193         $Dy,$Dm,$Dd);"
1194
1195         This function is actually a shortcut for applying the function
1196         "Add_Delta_YM()" first, followed by the function "Add_Delta_Days()",
1197         i.e., this function does exactly the same as
1198
1199          ($year,$month,$day) = Add_Delta_Days( Add_Delta_YM($year,$month,$day,$Dy,$Dm), $Dd );
1200
1201         Beware that, if necessary, the function "Add_Delta_YM()" truncates
1202         the resulting day of the month to the largest allowable value for
1203         that month, i.e., the (invalid) result [2009,2,31] is automatically
1204         transformed into [2009,2,28].
1205
1206         For more details on this truncation, see the description of the
1207         function "Add_Delta_YM()" further above.
1208
1209         This function is meant to be complementary with the function
1210         "N_Delta_YMD()" described further above.
1211
1212         This means that it is guaranteed that the result returned by
1213
1214           Add_N_Delta_YMD( @date1, N_Delta_YMD(@date1, @date2) );
1215
1216         is always identical with the given date "@date2".
1217
1218         Note however that unlike with function "Add_Delta_YMD()", the reverse
1219         is not true here, i.e.,
1220
1221           ($Dy,$Dm,$Dd) = N_Delta_YMD(@date1,@date2);
1222           @date = Add_N_Delta_YMD(@date2, -$Dy,-$Dm,-$Dd);
1223
1224         will NOT always return the initial date "@date1".
1225
1226         Example:
1227
1228           (0,11,3) == N_Delta_YMD(2008,2,29, 2009,2,1);
1229
1230           [2008,2,29] + (0, 11, 3) = [2009,2, 1]
1231           [2009,2, 1] + (0,-11,-3) = [2008,2,27] # EXPECTED: [2008,2,29]
1232
1233       • "($year,$month,$day, $hour,$min,$sec) =
1234         Add_N_Delta_YMDHMS($year,$month,$day, $hour,$min,$sec,
1235         $D_y,$D_m,$D_d, $Dhh,$Dmm,$Dss);"
1236
1237         This function essentially does the same as the function
1238         "Add_N_Delta_YMD()" described immediately above, except that also the
1239         difference in hours, minutes and seconds is taken into account.
1240
1241       • "($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
1242         System_Clock([$gmt]);"
1243
1244         If your operating system supports the corresponding system calls
1245         (""time()"" and ""localtime()"" or ""gmtime()""), this function will
1246         return the information provided by your system clock, i.e., the
1247         current date and time, the number of the day of year, the number of
1248         the day of week and a flag signaling whether daylight savings time is
1249         currently in effect or not.
1250
1251         The ranges of values returned (and their meanings) are as follows:
1252
1253                 $year   :   1970..2038 (or more)  [Unix etc.]
1254                 $year   :   1904..2040            [MacOS Classic]
1255
1256                 $month  :   1..12
1257                 $day    :   1..31
1258                 $hour   :   0..23
1259                 $min    :   0..59
1260                 $sec    :   0..59    (0..61 on some systems)
1261                 $doy    :   1..366
1262                 $dow    :   1..7
1263                 $dst    :  -1..1
1264
1265         "$doy" is the day of year, sometimes also referred to as the "julian
1266         date", which starts at "1" and goes up to the number of days in that
1267         year.
1268
1269         The day of week ("$dow") will be "1" for Monday, "2" for Tuesday and
1270         so on until "7" for Sunday.
1271
1272         The daylight savings time flag ("$dst") will be ""-1"" if this
1273         information is not available on your system, "0" for no daylight
1274         savings time (i.e., winter time) and "1" when daylight savings time
1275         is in effect.
1276
1277         If your operating system does not provide the necessary system calls,
1278         calling this function will result in a fatal "not available on this
1279         system" error message.
1280
1281         If you want to handle this exception yourself, use ""eval"" as
1282         follows:
1283
1284           eval { ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
1285             System_Clock(); };
1286
1287           if ($@)
1288           {
1289               # Handle missing system clock
1290               # (For instance, ask user to enter this information manually)
1291           }
1292
1293         Note that curlies ("{" and "}") are used here to delimit the
1294         statement to be "eval"ed (which is the way to catch exceptions in
1295         Perl), and not quotes (which is a way to evaluate Perl expressions at
1296         runtime).
1297
1298         If the optional (boolean) input parameter "$gmt" is given, a "true"
1299         value ("1") will cause ""gmtime()"" to be used instead of
1300         ""localtime()"", internally, thus returning Greenwich Mean Time (GMT,
1301         or UTC) instead of local time.
1302
1303       • "($year,$month,$day) = Today([$gmt]);"
1304
1305         This function returns a subset of the values returned by the function
1306         ""System_Clock()"" (see above for details), namely the current year,
1307         month and day.
1308
1309         A fatal "not available on this system" error message will appear if
1310         the corresponding system calls are not supported by your current
1311         operating system.
1312
1313         If the optional (boolean) input parameter "$gmt" is given, a "true"
1314         value ("1") will cause ""gmtime()"" to be used instead of
1315         ""localtime()"", internally, thus returning Greenwich Mean Time (GMT,
1316         or UTC) instead of local time.
1317
1318       • "($hour,$min,$sec) = Now([$gmt]);"
1319
1320         This function returns a subset of the values returned by the function
1321         ""System_Clock()"" (see above for details), namely the current time
1322         (hours, minutes and full seconds).
1323
1324         A fatal "not available on this system" error message will appear if
1325         the corresponding system calls are not supported by your current
1326         operating system.
1327
1328         If the optional (boolean) input parameter "$gmt" is given, a "true"
1329         value ("1") will cause ""gmtime()"" to be used instead of
1330         ""localtime()"", internally, thus returning Greenwich Mean Time (GMT,
1331         or UTC) instead of local time.
1332
1333       • "($year,$month,$day, $hour,$min,$sec) = Today_and_Now([$gmt]);"
1334
1335         This function returns a subset of the values returned by the function
1336         ""System_Clock()"" (see above for details), namely the current date
1337         (year, month, day) and time (hours, minutes and full seconds).
1338
1339         A fatal "not available on this system" error message will appear if
1340         the corresponding system calls are not supported by your current
1341         operating system.
1342
1343         If the optional (boolean) input parameter "$gmt" is given, a "true"
1344         value ("1") will cause ""gmtime()"" to be used instead of
1345         ""localtime()"", internally, thus returning Greenwich Mean Time (GMT,
1346         or UTC) instead of local time.
1347
1348       • "$year = This_Year([$gmt]);"
1349
1350         This function returns the current year, according to local time.
1351
1352         A fatal "not available on this system" error message will appear if
1353         the corresponding system calls are not supported by your current
1354         operating system.
1355
1356         If the optional (boolean) input parameter "$gmt" is given, a "true"
1357         value ("1") will cause ""gmtime()"" to be used instead of
1358         ""localtime()"", internally, thus returning Greenwich Mean Time (GMT,
1359         or UTC) instead of local time. However, this will only make a
1360         difference within a few hours around New Year (unless you are on a
1361         Pacific island, where this can be almost 24 hours).
1362
1363       • "($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
1364         Gmtime([time]);"
1365
1366         This is Date::Pcalc's equivalent of Perl's built-in "gmtime()"
1367         function.  See also "gmtime" in perlfunc(1).
1368
1369         With the optional argument "time" (i.e., seconds since the epoch),
1370         this function will return the corresponding values for that
1371         particular time (instead of the current time when this parameter is
1372         omitted).
1373
1374         The ranges of values returned (and their meanings) are as follows:
1375
1376                 $year   :   1970..2038 (or more)  [Unix etc.]
1377                 $year   :   1904..2040            [MacOS Classic]
1378
1379                 $month  :   1..12
1380                 $day    :   1..31
1381                 $hour   :   0..23
1382                 $min    :   0..59
1383                 $sec    :   0..59
1384                 $doy    :   1..366
1385                 $dow    :   1..7
1386                 $dst    :  -1..1
1387
1388         "$doy" is the day of year, sometimes also referred to as the "julian
1389         date", which starts at "1" and goes up to the number of days in that
1390         year.
1391
1392         The day of week ("$dow") will be "1" for Monday, "2" for Tuesday and
1393         so on until "7" for Sunday.
1394
1395         The daylight savings time flag ("$dst") will be ""-1"" if this
1396         information is not available on your system, "0" for no daylight
1397         savings time (i.e., winter time) and "1" when daylight savings time
1398         is in effect.
1399
1400         A fatal "time out of range" error will occur if the given time value
1401         is out of range "[0..(~0>>1)]".
1402
1403         If the time value is omitted, the "time()" function is called
1404         instead, internally.
1405
1406       • "($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
1407         Localtime([time]);"
1408
1409         This is Date::Pcalc's equivalent of Perl's built-in "localtime()"
1410         function.  See also "localtime" in perlfunc(1).
1411
1412         The ranges of values returned (and their meanings) are as follows:
1413
1414                 $year   :   1970..2038 (or more)  [Unix etc.]
1415                 $year   :   1904..2040            [MacOS Classic]
1416
1417                 $month  :   1..12
1418                 $day    :   1..31
1419                 $hour   :   0..23
1420                 $min    :   0..59
1421                 $sec    :   0..59
1422                 $doy    :   1..366
1423                 $dow    :   1..7
1424                 $dst    :  -1..1
1425
1426         "$doy" is the day of year, sometimes also referred to as the "julian
1427         date", which starts at "1" and goes up to the number of days in that
1428         year.
1429
1430         The day of week ("$dow") will be "1" for Monday, "2" for Tuesday and
1431         so on until "7" for Sunday.
1432
1433         The daylight savings time flag ("$dst") will be ""-1"" if this
1434         information is not available on your system, "0" for no daylight
1435         savings time (i.e., winter time) and "1" when daylight savings time
1436         is in effect.
1437
1438         A fatal "time out of range" error will occur if the given time value
1439         is out of range "[0..(~0>>1)]".
1440
1441         If the time value is omitted, the "time()" function is called
1442         instead, internally.
1443
1444       • "$time = Mktime($year,$month,$day, $hour,$min,$sec);"
1445
1446         This function converts a date into a time value, i.e., into the
1447         number of seconds since whatever moment in time your system considers
1448         to be the "epoch". On Unix and most other systems this is the number
1449         of seconds since January 1st 1970 at midnight (GMT). On MacOS Classic
1450         this is the number of seconds since January 1st 1904 at midnight
1451         (local time).
1452
1453         The function is similar to the "POSIX::mktime()" function (see
1454         "mktime" in POSIX(1) for more details), but in contrast to the
1455         latter, it expects dates in the usual ranges used throughout this
1456         module: The year 2001 stays year 2001, and months are numbered from 1
1457         to 12.
1458
1459         A fatal "date out of range" error will occur if the given date cannot
1460         be expressed in terms of seconds since the epoch (this happens for
1461         instance when the date lies before the epoch, or if it is later than
1462         19-Jan-2038 03:14:07 GMT on 32 bit Unix systems, or later than
1463         06-Feb-2040 06:28:15 (local time) on a Macintosh with MacOS
1464         Classic).
1465
1466         Just like the "POSIX::mktime()" function, this function uses the
1467         "mktime()" system call, internally.
1468
1469         This means that the given date and time is considered to be in local
1470         time, and that the value returned by this function will depend on
1471         your machine's local settings such as the time zone, whether daylight
1472         savings time is (or was, at the time) in effect, and the system clock
1473         itself.
1474
1475         BEWARE that "mktime()" does not always return the same time value as
1476         fed into "localtime()", when you feed the output of "localtime()"
1477         back into "mktime()", on some systems!
1478
1479         I.e., ""Mktime((Localtime($time))[0..5])"" will not always return the
1480         same value as given in "$time"!
1481
1482         Note that since Perl does not provide any access to the internal
1483         system call "mktime()", in this pure Perl version, "Mktime()" is
1484         calculated as follows:
1485
1486           Date_to_Time(Add_Delta_YMDHMS(@_,map(-$_,(Timezone(Date_to_Time(@_)))[0..5])));
1487
1488         This may or may not yield the same result as "mktime()".
1489
1490         No guarantees whatsoever are given here for that!  Use at your own
1491         risk!
1492
1493       • "($D_y,$D_m,$D_d, $Dh,$Dm,$Ds, $dst) = Timezone([time]);"
1494
1495         This function returns the difference between ""localtime(time)"" and
1496         ""gmtime(time)"", which is the timezone offset in effect for the
1497         current location and the given ""time"".
1498
1499         This offset is positive if you are located to the east of Greenwich,
1500         and is usually negative (except during daylight savings time, in some
1501         locations) if you are located to the west of Greenwich.
1502
1503         Note that this offset is influenced by all of the relevant system
1504         settings and parameters on your machine; such as locales, environment
1505         variables (e.g. ""TZ"") and the system clock itself. See the relevant
1506         documentation on your system for more details.
1507
1508         If the ""time"" is omitted, the ""time()"" function will be called
1509         automatically, internally (similar to the built-in functions
1510         ""localtime()"" and ""gmtime()"" in Perl).
1511
1512         A fatal "time out of range" error will occur if the given time value
1513         is out of range "[0..(~0>>1)]".
1514
1515         The last item of the returned list is a flag which indicates whether
1516         daylight savings time is currently in effect. This flag is negative
1517         (-1) if this information is not available on your system. It is zero
1518         (0) when daylight savings time is off, and positive (+1) when
1519         daylight savings time is on.
1520
1521         Thus you can check very quickly whether daylight savings time is
1522         currently in effect by evaluating this function in scalar context (in
1523         scalar context, Perl returns the last item of a list):
1524
1525           if (scalar Timezone > 0) { # yes, daylight savings time
1526
1527         However, a slightly more efficient way would be this:
1528
1529           if (scalar System_Clock > 0) { # yes, daylight savings time
1530
1531       • "$time = Date_to_Time($year,$month,$day, $hour,$min,$sec);"
1532
1533         This function is a replacement for the BSD function "timegm()" (which
1534         is not available on all Unix systems), which converts a given date
1535         and time into a time value, i.e., into the number of seconds since
1536         whatever moment in time your system considers to be the "epoch". On
1537         Unix and most other systems this is the number of seconds since
1538         January 1st 1970 at midnight (GMT). On MacOS Classic this is the
1539         number of seconds since January 1st 1904 at midnight (local time).
1540
1541         Under Unix, the date and time are considered to be in UTC ("Universal
1542         Time Coordinated", and so is the resulting time value.
1543
1544         UTC is almost the same as GMT (or "Greenwich Mean Time"), except that
1545         UTC has leap seconds (in order to account for small variations in the
1546         rotation of the earth, for instance), whereas GMT does not.
1547
1548         Under MacOS Classic, however, both input and output are considered to
1549         be in local time.
1550
1551         The ranges of year and month follow the same rules as throughout the
1552         rest of this module (and not the contorted rules of its Unix
1553         equivalent), i.e., the year "2001" stays "2001" and the month ranges
1554         from 1 to 12.
1555
1556         A fatal "date out of range" error will occur if the given date cannot
1557         be expressed in terms of seconds since the epoch (this happens for
1558         instance when the date lies before the epoch, or if it is later than
1559         19-Jan-2038 03:14:07 GMT on 32 bit Unix systems, or later than
1560         06-Feb-2040 06:28:15 (local time) on a Macintosh with MacOS
1561         Classic).
1562
1563         This function should be very fast, because it is implemented in a
1564         very straightforward manner and doesn't use any internal system
1565         calls.
1566
1567         Moreover, the functions "Date_to_Time()" and "Time_to_Date()" are
1568         guaranteed to be complementary, i.e., that
1569         ""Date_to_Time(Time_to_Date($time))"" and
1570         ""Time_to_Date(Date_to_Time($year,$month,$day, $hour,$min,$sec))""
1571         will always return the initial values.
1572
1573       • "($year,$month,$day, $hour,$min,$sec) = Time_to_Date([time]);"
1574
1575         This function is an alternative to the POSIX "gmtime()" function (and
1576         its built-in Perl equivalent), which converts a given time value into
1577         the corresponding date and time. The given time value must be the
1578         number of seconds since whatever moment in time your system considers
1579         to be the "epoch". On Unix and most other systems this is the number
1580         of seconds since January 1st 1970 at midnight (GMT). On MacOS Classic
1581         this is the number of seconds since January 1st 1904 at midnight
1582         (local time).
1583
1584         Under Unix, the given time value is considered to be in UTC
1585         ("Universal Time Coordinated", and so is the resulting date and time.
1586
1587         UTC is almost the same as GMT (or "Greenwich Mean Time"), except that
1588         UTC has leap seconds (in order to account for small variations in the
1589         rotation of the earth, for instance), whereas GMT does not.
1590
1591         Under MacOS Classic, however, both input and output are considered to
1592         be in local time.
1593
1594         If the input value ""time"" is omitted, the ""time()"" function will
1595         be called automatically, internally (similar to the built-in
1596         functions ""localtime()"" and ""gmtime()"" in Perl).
1597
1598         A fatal "time out of range" error will occur if the given time value
1599         is negative.
1600
1601         This function should be very fast, because it is implemented in a
1602         very straightforward manner and doesn't use any internal system calls
1603         (except for "time()", if the input value is omitted).
1604
1605         Moreover, the functions "Date_to_Time()" and "Time_to_Date()" are
1606         guaranteed to be complementary, i.e., that
1607         ""Date_to_Time(Time_to_Date($time))"" and
1608         ""Time_to_Date(Date_to_Time($year,$month,$day, $hour,$min,$sec))""
1609         will always return the initial values.
1610
1611       • "($year,$month,$day) = Easter_Sunday($year);"
1612
1613         This function calculates the date of Easter Sunday for all years in
1614         the range from 1583 to 2299 (all other year numbers will result in a
1615         fatal "year out of range" error message) using the method known as
1616         the "Gaussian Rule".
1617
1618         Some related christian feast days which depend on the date of Easter
1619         Sunday:
1620
1621           Carnival Monday / Rosenmontag / Veille du Mardi Gras   =  -48 days
1622           Mardi Gras / Karnevalsdienstag / Mardi Gras            =  -47 days
1623           Ash Wednesday / Aschermittwoch / Mercredi des Cendres  =  -46 days
1624           Palm Sunday / Palmsonntag / Dimanche des Rameaux       =   -7 days
1625           Easter Friday / Karfreitag / Vendredi Saint            =   -2 days
1626           Easter Saturday / Ostersamstag / Samedi de Paques      =   -1 day
1627           Easter Monday / Ostermontag / Lundi de Paques          =   +1 day
1628           Ascension of Christ / Christi Himmelfahrt / Ascension  =  +39 days
1629           Whitsunday / Pfingstsonntag / Dimanche de Pentecote    =  +49 days
1630           Whitmonday / Pfingstmontag / Lundi de Pentecote        =  +50 days
1631           Feast of Corpus Christi / Fronleichnam / Fete-Dieu     =  +60 days
1632
1633         Use the offsets shown above to calculate the date of the
1634         corresponding feast day as follows:
1635
1636           ($year,$month,$day) = Add_Delta_Days(Easter_Sunday($year), $offset));
1637
1638       • "if ($month = Decode_Month($string[,$lang]))"
1639
1640         This function takes a string as its argument, which should contain
1641         the name of a month in the given or currently selected language (see
1642         further below for details about the multi-language support of this
1643         package), or any uniquely identifying abbreviation of a month's name
1644         (i.e., the first few letters), and returns the corresponding number
1645         (1..12) upon a successful match, or "0" otherwise (therefore, the
1646         return value can also be used as the conditional expression in an
1647         "if" statement).
1648
1649         Note that the input string may not contain any other characters which
1650         do not pertain to the month's name, especially no leading or trailing
1651         whitespace.
1652
1653         Note also that matching is performed in a case-insensitive manner
1654         (this may depend on the "locale" setting on your current system,
1655         though!)
1656
1657         With "1" ("English") as the given language, the following examples
1658         will all return the value "9":
1659
1660           $month = Decode_Month("s",1);
1661           $month = Decode_Month("Sep",1);
1662           $month = Decode_Month("septemb",1);
1663           $month = Decode_Month("September",1);
1664
1665       • "if ($dow = Decode_Day_of_Week($string[,$lang]))"
1666
1667         This function takes a string as its argument, which should contain
1668         the name of a day of week in the given or currently selected language
1669         (see further below for details about the multi-language support of
1670         this package), or any uniquely identifying abbreviation of the name
1671         of a day of week (i.e., the first few letters), and returns the
1672         corresponding number (1..7) upon a successful match, or "0" otherwise
1673         (therefore, the return value can also be used as the conditional
1674         expression in an "if" statement).
1675
1676         Note that the input string may not contain any other characters which
1677         do not pertain to the name of the day of week, especially no leading
1678         or trailing whitespace.
1679
1680         Note also that matching is performed in a case-insensitive manner
1681         (this may depend on the "locale" setting on your current system,
1682         though!)
1683
1684         With "1" ("English") as the given language, the following examples
1685         will all return the value "3":
1686
1687           $dow = Decode_Day_of_Week("w",1);
1688           $dow = Decode_Day_of_Week("Wed",1);
1689           $dow = Decode_Day_of_Week("wednes",1);
1690           $dow = Decode_Day_of_Week("Wednesday",1);
1691
1692       • "if ($lang = Decode_Language($string))"
1693
1694         This function takes a string as its argument, which should contain
1695         the name of one of the languages supported by this package (IN THIS
1696         VERY LANGUAGE ITSELF), or any uniquely identifying abbreviation of
1697         the name of a language (i.e., the first few letters), and returns its
1698         corresponding internal number (1..14 in the original distribution)
1699         upon a successful match, or "0" otherwise (therefore, the return
1700         value can also be used as the conditional expression in an "if"
1701         statement).
1702
1703         Note that the input string may not contain any other characters which
1704         do not pertain to the name of a language, especially no leading or
1705         trailing whitespace.
1706
1707         Note also that matching is performed in a case-insensitive manner
1708         (this may depend on the "locale" setting on your current system,
1709         though!)
1710
1711         The original distribution supports the following fourteen languages:
1712
1713                     English                    ==>    1    (default)
1714                     Français    (French)       ==>    2
1715                     Deutsch     (German)       ==>    3
1716                     Español     (Spanish)      ==>    4
1717                     Português   (Portuguese)   ==>    5
1718                     Nederlands  (Dutch)        ==>    6
1719                     Italiano    (Italian)      ==>    7
1720                     Norsk       (Norwegian)    ==>    8
1721                     Svenska     (Swedish)      ==>    9
1722                     Dansk       (Danish)       ==>   10
1723                     suomi       (Finnish)      ==>   11
1724                     Magyar      (Hungarian)    ==>   12
1725                     polski      (Polish)       ==>   13
1726                     Romaneste   (Romanian)     ==>   14
1727
1728         See the section "How to install additional languages" in the file
1729         "INSTALL.txt" in this distribution for how to add more languages to
1730         this package.
1731
1732         In the original distribution (no other languages installed), the
1733         following examples will all return the value "3":
1734
1735           $lang = Decode_Language("d");
1736           $lang = Decode_Language("de");
1737           $lang = Decode_Language("Deutsch");
1738
1739         Note that you may not be able to enter the special international
1740         characters in some of the languages' names over the keyboard directly
1741         on some systems.
1742
1743         This should never be a problem, though; just enter an abbreviation of
1744         the name of the language consisting of the first few letters up to
1745         the character before the first special international character.
1746
1747       • "if (($year,$month,$day) = Decode_Date_EU($string[,$lang]))"
1748
1749         This function scans a given string and tries to parse any date which
1750         might be embedded in it.
1751
1752         The function returns an empty list if it can't successfully extract a
1753         valid date from its input string, or else it returns the date found.
1754
1755         The function accepts almost any format, as long as the date is given
1756         in the european order (hence its name) day-month-year.
1757
1758         Thereby, zero or more NON-NUMERIC characters may PRECEDE the day and
1759         FOLLOW the year.
1760
1761         Moreover, zero or more NON-ALPHANUMERIC characters are permitted
1762         BETWEEN these three items (i.e., between day and month and between
1763         month and year).
1764
1765         The month may be given either numerically (i.e., a number from "1" to
1766         "12"), or alphanumerically, i.e., as the name of the month in the
1767         given or currently selected language, or any uniquely identifying
1768         abbreviation thereof.
1769
1770         (See further below for details about the multi-language support of
1771         this package!)
1772
1773         If the year is given as one or two digits only (i.e., if the year is
1774         less than 100), it is mapped to a "window" of +/- 50 years around the
1775         current year, as described by the "Moving_Window()" function (see
1776         further below).
1777
1778         If the day, month and year are all given numerically but WITHOUT any
1779         delimiting characters between them, this string of digits will be
1780         mapped to the day, month and year as follows:
1781
1782                         Length:        Mapping:
1783                           3              dmy
1784                           4              dmyy
1785                           5              dmmyy
1786                           6              ddmmyy
1787                           7              dmmyyyy
1788                           8              ddmmyyyy
1789
1790         (Where "d" stands for "day", "m" stands for "month" and "y" stands
1791         for "year".)
1792
1793         All other strings consisting purely of digits (without any
1794         intervening delimiters) are rejected, i.e., not recognized.
1795
1796         Examples:
1797
1798           "3.1.64"
1799           "3 1 64"
1800           "03.01.64"
1801           "03/01/64"
1802           "3. Jan 1964"
1803           "Birthday: 3. Jan '64 in Backnang/Germany"
1804           "03-Jan-64"
1805           "3.Jan1964"
1806           "3Jan64"
1807           "030164"
1808           "3ja64"
1809           "3164"
1810
1811         Experiment! (See the corresponding example applications in the
1812         "examples" subdirectory of this distribution in order to do so.)
1813
1814       • "if (($year,$month,$day) = Decode_Date_US($string[,$lang]))"
1815
1816         This function scans a given string and tries to parse any date which
1817         might be embedded in it.
1818
1819         The function returns an empty list if it can't successfully extract a
1820         valid date from its input string, or else it returns the date found.
1821
1822         The function accepts almost any format, as long as the date is given
1823         in the U.S. american order (hence its name) month-day-year.
1824
1825         Thereby, zero or more NON-ALPHANUMERIC characters may PRECEDE and
1826         FOLLOW the month (i.e., precede the month and separate it from the
1827         day which follows behind).
1828
1829         Moreover, zero or more NON-NUMERIC characters are permitted BETWEEN
1830         the day and the year, as well as AFTER the year.
1831
1832         The month may be given either numerically (i.e., a number from "1" to
1833         "12"), or alphanumerically, i.e., as the name of the month in the
1834         given or currently selected language, or any uniquely identifying
1835         abbreviation thereof.
1836
1837         (See further below for details about the multi-language support of
1838         this package!)
1839
1840         If the year is given as one or two digits only (i.e., if the year is
1841         less than 100), it is mapped to a "window" of +/- 50 years around the
1842         current year, as described by the "Moving_Window()" function (see
1843         further below).
1844
1845         If the month, day and year are all given numerically but WITHOUT any
1846         delimiting characters between them, this string of digits will be
1847         mapped to the month, day and year as follows:
1848
1849                         Length:        Mapping:
1850                           3              mdy
1851                           4              mdyy
1852                           5              mddyy
1853                           6              mmddyy
1854                           7              mddyyyy
1855                           8              mmddyyyy
1856
1857         (Where "m" stands for "month", "d" stands for "day" and "y" stands
1858         for "year".)
1859
1860         All other strings consisting purely of digits (without any
1861         intervening delimiters) are rejected, i.e., not recognized.
1862
1863         If only the day and the year form a contiguous string of digits, they
1864         will be mapped as follows:
1865
1866                         Length:        Mapping:
1867                           2              dy
1868                           3              dyy
1869                           4              ddyy
1870                           5              dyyyy
1871                           6              ddyyyy
1872
1873         (Where "d" stands for "day" and "y" stands for "year".)
1874
1875         Examples:
1876
1877           "1 3 64"
1878           "01/03/64"
1879           "Jan 3 '64"
1880           "Jan 3 1964"
1881           "===> January 3rd 1964 (birthday)"
1882           "Jan31964"
1883           "Jan364"
1884           "ja364"
1885           "1364"
1886
1887         Experiment! (See the corresponding example applications in the
1888         "examples" subdirectory of this distribution in order to do so.)
1889
1890       • "$year = Fixed_Window($yy);"
1891
1892         This function applies a "fixed window" strategy to two-digit year
1893         numbers in order to convert them into four-digit year numbers.
1894
1895         All other year numbers are passed through unchanged, except for
1896         negative year numbers, which cause the function to return zero ("0")
1897         instead.
1898
1899         Two-digit year numbers ""yy"" below 70 are converted to ""20yy"",
1900         whereas year numbers equal to or greater than 70 (but less than 100)
1901         are converted to ""19yy"".
1902
1903         In the original distribution of this package, the base century is set
1904         to "1900" and the base year to "70" (which is a standard on UNIX
1905         systems), but these constants (also called the "epoch") can actually
1906         be chosen at will.
1907
1908       • "$year = Moving_Window($yy);"
1909
1910         This function applies a "moving window" strategy to two-digit year
1911         numbers in order to convert them into four-digit year numbers,
1912         provided the necessary system calls (system clock) are available.
1913         Otherwise the function falls back to the "fixed window" strategy
1914         described in the function above.
1915
1916         All other year numbers are passed through unchanged, except for
1917         negative year numbers, which cause the function to return zero ("0")
1918         instead.
1919
1920         Two-digit year numbers are mapped according to a "window" of 50 years
1921         in both directions (past and future) around the current year.
1922
1923         That is, two-digit year numbers are first mapped to the same century
1924         as the current year. If the resulting year is smaller than the
1925         current year minus 50, then one more century is added to the result.
1926         If the resulting year is equal to or greater than the current year
1927         plus 50, then a century is subtracted from the result.
1928
1929       • "$date = Compress($year,$month,$day);"
1930
1931         WARNING: This function is legacy code, its use is deprecated!
1932
1933         This function encodes a date in 16 bits, which is the value being
1934         returned.
1935
1936         The encoding scheme is as follows:
1937
1938                     Bit number:    FEDCBA9 8765 43210
1939                     Contents:      yyyyyyy mmmm ddddd
1940
1941         (Where the "yyyyyyy" contain the number of the year, "mmmm" the
1942         number of the month and "ddddd" the number of the day.)
1943
1944         The function returns "0" if the given input values do not represent a
1945         valid date. Therefore, the return value of this function can also be
1946         used as the conditional expression in an "if" statement, in order to
1947         check whether the given input values constitute a valid date).
1948
1949         Through this special encoding scheme, it is possible to COMPARE
1950         compressed dates for equality and order (less than/greater than)
1951         WITHOUT any previous DECODING!
1952
1953         Note however that contiguous dates do NOT necessarily have contiguous
1954         compressed representations!
1955
1956         I.e., incrementing the compressed representation of a date MAY OR MAY
1957         NOT yield a valid new date!
1958
1959         Note also that this function can only handle dates within one
1960         century.
1961
1962         This century can be chosen at will (at compile time of this module)
1963         by defining a base century and year (also called the "epoch"). In the
1964         original distribution of this package, the base century is set to
1965         "1900" and the base year to "70" (which is standard on UNIX systems).
1966
1967         This allows this function to handle dates from "1970" up to "2069".
1968
1969         If the given year is equal to, say, "95", this package will
1970         automatically assume that you really meant "1995" instead. However,
1971         if you specify a year number which is SMALLER than 70, like "64", for
1972         instance, this package will assume that you really meant "2064".
1973
1974         You are not confined to two-digit (abbreviated) year numbers, though.
1975
1976         The function also accepts "full-length" year numbers, provided that
1977         they lie in the supported range (i.e., from "1970" to "2069", in the
1978         original configuration of this package).
1979
1980         Note that this function is maintained mainly for backward
1981         compatibility, and that its use is not recommended.
1982
1983       • "if (($century,$year,$month,$day) = Uncompress($date))"
1984
1985         WARNING: This function is legacy code, its use is deprecated!
1986
1987         This function decodes dates that were encoded previously using the
1988         function ""Compress()"".
1989
1990         It returns the century, year, month and day of the date encoded in
1991         "$date" if "$date" represents a valid date, or an empty list
1992         otherwise.
1993
1994         The year returned in "$year" is actually a two-digit year number
1995         (i.e., the year number taken modulo 100), and only the expression
1996         ""$century + $year"" yields the "full-length" year number (for
1997         example, "1900 + 95 = 1995").
1998
1999         Note that this function is maintained mainly for backward
2000         compatibility, and that its use is not recommended.
2001
2002       • "if (check_compressed($date))"
2003
2004         WARNING: This function is legacy code, its use is deprecated!
2005
2006         This function returns "true" ("1") if the given input value
2007         constitutes a valid compressed date, and "false" ("0") otherwise.
2008
2009         Note that this function is maintained mainly for backward
2010         compatibility, and that its use is not recommended.
2011
2012       • "$string = Compressed_to_Text($date[,$lang]);"
2013
2014         WARNING: This function is legacy code, its use is deprecated!
2015
2016         This function returns a string of fixed length (always 9 characters
2017         long) containing a textual representation of the compressed date
2018         encoded in "$date".
2019
2020         This string has the form "dd-Mmm-yy", where "dd" is the two-digit
2021         number of the day, "Mmm" are the first three letters of the name of
2022         the month in the given or currently selected language (see further
2023         below for details about the multi-language support of this package),
2024         and "yy" is the two-digit year number (i.e., the year number taken
2025         modulo 100).
2026
2027         If "$date" does not represent a valid date, the string "??-???-??" is
2028         returned instead.
2029
2030         Note that this function is maintained mainly for backward
2031         compatibility, and that its use is not recommended.
2032
2033       • "$string = Date_to_Text($year,$month,$day[,$lang]);"
2034
2035         This function returns a string containing a textual representation of
2036         the given date of the form "www dd-Mmm-yyyy", where "www" are the
2037         first three letters of the name of the day of week in the given or
2038         currently selected language, or a special abbreviation, if special
2039         abbreviations have been defined for the given or currently selected
2040         language (see further below for details about the multi-language
2041         support of this package), "dd" is the day (one or two digits), "Mmm"
2042         are the first three letters of the name of the month in the given or
2043         currently selected language, and "yyyy" is the number of the year in
2044         full length.
2045
2046         If the given input values do not constitute a valid date, a fatal
2047         "not a valid date" error occurs.
2048
2049         (See the section "RECIPES" near the end of this document for a code
2050         snippet for how to print dates in any format you like.)
2051
2052       • "$string = Date_to_Text_Long($year,$month,$day[,$lang]);"
2053
2054         This function returns a string containing a textual representation of
2055         the given date roughly of the form "Wwwwww, dd Mmmmmm yyyy", where
2056         "Wwwwww" is the name of the day of week in the given or currently
2057         selected language (see further below for details about the multi-
2058         language support of this package), "dd" is the day (one or two
2059         digits), "Mmmmmm" is the name of the month in the given or currently
2060         selected language, and "yyyy" is the number of the year in full
2061         length.
2062
2063         The exact format of the output string depends on the given or
2064         currently selected language. In the original distribution of this
2065         package, these formats are defined as follows:
2066
2067           1  English    :  "Wwwwww, Mmmmmm ddth yyyy"
2068           2  French     :  "Wwwwww dd mmmmmm yyyy"
2069           3  German     :  "Wwwwww, den dd. Mmmmmm yyyy"
2070           4  Spanish    :  "Wwwwww, dd de mmmmmm de yyyy"
2071           5  Portuguese :  "Wwwwww, dia dd de mmmmmm de yyyy"
2072           6  Dutch      :  "Wwwwww, dd mmmmmm yyyy"
2073           7  Italian    :  "Wwwwww, dd Mmmmmm yyyy"
2074           8  Norwegian  :  "wwwwww, dd. mmmmmm yyyy"
2075           9  Swedish    :  "wwwwww, dd mmmmmm yyyy"
2076          10  Danish     :  "wwwwww, dd. mmmmmm yyyy"
2077          11  Finnish    :  "wwwwww, dd. mmmmmmta yyyy"
2078          12  Hungarian  :  "dd. Mmmmmm yyyy., wwwwww"
2079          13  Polish     :  "Wwwwww, dd Mmmmmm yyyy"
2080          14  Romanian   :  "Wwwwww dd Mmmmmm yyyy"
2081
2082         (You can change these formats in the file "Pcalc.pm" before
2083         installing this module in order to suit your personal preferences.)
2084
2085         If the given input values do not constitute a valid date, a fatal
2086         "not a valid date" error occurs.
2087
2088         In order to capitalize the day of week at the beginning of the string
2089         in Norwegian, use
2090         ""ucfirst(Date_to_Text_Long($year,$month,$day,8));"".
2091
2092         (See the section "RECIPES" near the end of this document for an
2093         example on how to print dates in any format you like.)
2094
2095       • "$string = English_Ordinal($number);"
2096
2097         This function returns a string containing the (english) abbreviation
2098         of the ordinal number for the given (cardinal) number "$number".
2099
2100         I.e.,
2101
2102             0  =>  '0th'    10  =>  '10th'    20  =>  '20th'
2103             1  =>  '1st'    11  =>  '11th'    21  =>  '21st'
2104             2  =>  '2nd'    12  =>  '12th'    22  =>  '22nd'
2105             3  =>  '3rd'    13  =>  '13th'    23  =>  '23rd'
2106             4  =>  '4th'    14  =>  '14th'    24  =>  '24th'
2107             5  =>  '5th'    15  =>  '15th'    25  =>  '25th'
2108             6  =>  '6th'    16  =>  '16th'    26  =>  '26th'
2109             7  =>  '7th'    17  =>  '17th'    27  =>  '27th'
2110             8  =>  '8th'    18  =>  '18th'    28  =>  '28th'
2111             9  =>  '9th'    19  =>  '19th'    29  =>  '29th'
2112
2113         etc.
2114
2115       • "$string = Calendar($year,$month[,$orthodox[,$lang]]);"
2116
2117         This function returns a calendar of the given month in the given year
2118         (somewhat similar to the UNIX ""cal"" command), in the given or
2119         currently selected language (see further below for details about the
2120         multi-language support of this package).
2121
2122         Example:
2123
2124           print Calendar(1998,5);
2125
2126         This will print:
2127
2128                    May 1998
2129           Mon Tue Wed Thu Fri Sat Sun
2130                             1   2   3
2131             4   5   6   7   8   9  10
2132            11  12  13  14  15  16  17
2133            18  19  20  21  22  23  24
2134            25  26  27  28  29  30  31
2135
2136         If the optional boolean parameter "$orthodox" is given and true, the
2137         calendar starts on Sunday instead of Monday.
2138
2139       • "$string = Month_to_Text($month[,$lang]);"
2140
2141         This function returns the name of the given month in the given or
2142         currently selected language (see further below for details about the
2143         multi-language support of this package).
2144
2145         If the given month lies outside of the valid range from "1" to "12",
2146         a fatal "month out of range" error will occur.
2147
2148       • "$string = Day_of_Week_to_Text($dow[,$lang]);"
2149
2150         This function returns the name of the given day of week in the given
2151         or currently selected language (see further below for details about
2152         the multi-language support of this package).
2153
2154         If the given day of week lies outside of the valid range from "1" to
2155         "7", a fatal "day of week out of range" error will occur.
2156
2157       • "$string = Day_of_Week_Abbreviation($dow[,$lang]);"
2158
2159         This function returns the special abbreviation of the name of the
2160         given day of week, IF such special abbreviations have been defined
2161         for the given or currently selected language (see further below for
2162         details about the multi-language support of this package).
2163
2164         (In the original distribution of this package, this was only true for
2165         Portuguese. Starting with version 5.1, abbreviations for Polish have
2166         also been introduced. Starting with version 5.7, the abbreviations
2167         for Portuguese have been disabled. So Polish is currently the only
2168         language to define such special abbreviations.)
2169
2170         If not, the first three letters of the name of the day of week in the
2171         given or currently selected language are returned instead.
2172
2173         If the given day of week lies outside of the valid range from "1" to
2174         "7", a fatal "day of week out of range" error will occur.
2175
2176         Currently, this table of special abbreviations is only used by the
2177         functions ""Date_to_Text()"" and ""Calendar()"", internally.
2178
2179       • "$string = Language_to_Text($lang);"
2180
2181         This function returns the name of any language supported by this
2182         package when the internal number representing that language is given
2183         as input.
2184
2185         The original distribution supports the following fourteen languages:
2186
2187                     1   ==>   English                     (default)
2188                     2   ==>   Français    (French)
2189                     3   ==>   Deutsch     (German)
2190                     4   ==>   Español     (Spanish)
2191                     5   ==>   Português   (Portuguese)
2192                     6   ==>   Nederlands  (Dutch)
2193                     7   ==>   Italiano    (Italian)
2194                     8   ==>   Norsk       (Norwegian)
2195                     9   ==>   Svenska     (Swedish)
2196                    10   ==>   Dansk       (Danish)
2197                    11   ==>   suomi       (Finnish)
2198                    12   ==>   Magyar      (Hungarian)
2199                    13   ==>   polski      (Polish)
2200                    14   ==>   Romaneste   (Romanian)
2201
2202         See the section "How to install additional languages" in the file
2203         "INSTALL.txt" in this distribution for how to add more languages to
2204         this package.
2205
2206         See the description of the function ""Languages()"" further below to
2207         determine how many languages are actually available in a given
2208         installation of this package.
2209
2210       • "$lang = Language();"
2211
2212       • "Language($lang); # DEPRECATED"
2213
2214       • "$oldlang = Language($newlang); # DEPRECATED"
2215
2216         This function can be used to determine which language is currently
2217         selected, and to change the selected language (this latter use is
2218         deprecated, because this global setting may cause conflicts between
2219         threads or modules running concurrently).
2220
2221         Thereby, each language has a unique internal number.
2222
2223         The original distribution contains the following fourteen languages:
2224
2225                     1   ==>   English                     (default)
2226                     2   ==>   Français    (French)
2227                     3   ==>   Deutsch     (German)
2228                     4   ==>   Español     (Spanish)
2229                     5   ==>   Português   (Portuguese)
2230                     6   ==>   Nederlands  (Dutch)
2231                     7   ==>   Italiano    (Italian)
2232                     8   ==>   Norsk       (Norwegian)
2233                     9   ==>   Svenska     (Swedish)
2234                    10   ==>   Dansk       (Danish)
2235                    11   ==>   suomi       (Finnish)
2236                    12   ==>   Magyar      (Hungarian)
2237                    13   ==>   polski      (Polish)
2238                    14   ==>   Romaneste   (Romanian)
2239
2240         See the section "How to install additional languages" in the file
2241         "INSTALL.txt" in this distribution for how to add more languages to
2242         this package.
2243
2244         See the description of the function ""Languages()"" further below to
2245         determine how many languages are actually available in a given
2246         installation of this package.
2247
2248         BEWARE that in order for your programs to be portable, you should
2249         NEVER actually use the internal number of a language in this package
2250         EXPLICITLY, because the same number could mean different languages on
2251         different systems, depending on what languages have been added to any
2252         given installation of this package.
2253
2254         Therefore, you should always use a statement such as
2255
2256           Language(Decode_Language("Name_of_Language")); # DEPRECATED
2257
2258         or
2259
2260           DateCalc_Function(@parameters,Decode_Language("Name_of_Language")); # RECOMMENDED
2261
2262         to select the desired language, and
2263
2264           $language = Language_to_Text(Language());
2265
2266         or
2267
2268           $old_language = Language_to_Text(Language("Name_of_new_Language")); # DEPRECATED
2269
2270         to determine the (previously) selected language.
2271
2272         If the so chosen language is not available in the current
2273         installation, this will result in an appropriate error message,
2274         instead of silently using the wrong (a random) language (which just
2275         happens to have the same internal number in the other installation).
2276
2277         BEWARE that when using the function ""Language()"", the selected
2278         language is a global setting, shared by all threads or modules you
2279         might be running concurrently, thus possibly causing conflicts
2280         between them.
2281
2282         In order to avoid these conflicts, you should NEVER use the function
2283         ""Language()"", but should ALWAYS pass a language number (as returned
2284         by the function ""Decode_Language()"") to the functions which are
2285         language-dependent, which are:
2286
2287         "Decode_Month()", "Decode_Day_of_Week()", "Compressed_to_Text()",
2288         "Date_to_Text()", "Date_to_Text_Long()", "Calendar()",
2289         "Month_to_Text()", "Day_of_Week_to_Text()",
2290         "Day_of_Week_Abbreviation()", "Decode_Date_EU()", "Decode_Date_US()",
2291         "Decode_Date_EU2()", "Decode_Date_US2()", "Parse_Date()".
2292
2293         Note that when you pass an invalid number, such as e.g. zero, or no
2294         language parameter at all, these functions will revert to their
2295         behaviour in the versions of this module prior to 6.0, which means
2296         that the global setting (as set by ""Language()"") becomes active
2297         again (only in case of an invalid or missing language parameter!).
2298
2299       • "$max_lang = Languages();"
2300
2301         This function returns the (maximum) number of languages which are
2302         currently available in your installation of this package.
2303
2304         (This may vary from installation to installation.)
2305
2306         See the section "How to install additional languages" in the file
2307         "INSTALL.txt" in this distribution for how to add more languages to
2308         this package.
2309
2310         In the original distribution of this package there are fourteen
2311         built-in languages, therefore the value returned by this function
2312         will be "14" if no other languages have been added to your particular
2313         installation.
2314
2315       • "if (($year,$month,$day) = Decode_Date_EU2($string[,$lang))"
2316
2317         This function is the more "Perlish" equivalent of the function
2318         ""Decode_Date_EU()"" (translated from C), included here merely as an
2319         example to demonstrate how easy it is to write your own routine in
2320         Perl (using regular expressions) adapted to your own special needs,
2321         should the necessity arise, and intended primarily as a basis for
2322         your own development.
2323
2324         In one particular case this more "Perlish" version is actually
2325         slightly more permissive than its equivalent (translated from C), as
2326         far as the class of permitted intervening (i.e., delimiting)
2327         characters is concerned.
2328
2329         (Can you tell the subtle, almost insignificant difference by looking
2330         at the code? Or by experimenting? Hint: Try the string "a3b1c64d"
2331         with both functions.)
2332
2333       • "if (($year,$month,$day) = Decode_Date_US2($string[,$lang))"
2334
2335         This function is the more "Perlish" equivalent of the function
2336         ""Decode_Date_US()"" (translated from C), included here merely as an
2337         example to demonstrate how easy it is to write your own routine in
2338         Perl (using regular expressions) adapted to your own special needs,
2339         should the necessity arise, and intended primarily as a basis for
2340         your own development.
2341
2342         In one particular case this more "Perlish" version is actually
2343         slightly more permissive than its equivalent (translated from C).
2344
2345         (Hint: This is the same difference as with the ""Decode_Date_EU()""
2346         and ""Decode_Date_EU2()"" pair of functions.)
2347
2348         In a different case, the version translated from C is a little bit
2349         more permissive than its Perl equivalent.
2350
2351         (Can you tell the difference by looking at the code? Or by
2352         experimenting?  Hint: Try the string "(1/364)" with both functions.)
2353
2354       • "if (($year,$month,$day) = Parse_Date($string[,$lang))"
2355
2356         This function is useful for parsing dates as returned by the UNIX
2357         ""date"" command or as found in the headers of e-mail (in order to
2358         determine the date at which some e-mail has been sent or received,
2359         for instance).
2360
2361         Example #1:
2362
2363           ($year,$month,$day) = Parse_Date(`/bin/date`);
2364
2365         Example #2:
2366
2367           while (<MAIL>)
2368           {
2369               if (/^From \S/)
2370               {
2371                   ($year,$month,$day) = Parse_Date($_);
2372                   ...
2373               }
2374               ...
2375           }
2376
2377         The function returns an empty list if it can't extract a valid date
2378         from the input string.
2379
2380       • "$lower = ISO_LC($string);"
2381
2382         Returns a copy of the given string where all letters of the
2383         ISO-Latin-1 character set have been replaced by their lower case
2384         equivalents.
2385
2386         Similar to Perl's built-in function ""lc()"" (see "lc" in
2387         perlfunc(1)) but for the whole ISO-Latin-1 character set, not just
2388         plain ASCII.
2389
2390       • "$upper = ISO_UC($string);"
2391
2392         Returns a copy of the given string where all letters of the
2393         ISO-Latin-1 character set have been replaced by their upper case
2394         equivalents.
2395
2396         Similar to Perl's built-in function ""uc()"" (see "uc" in
2397         perlfunc(1)) but for the whole ISO-Latin-1 character set, not just
2398         plain ASCII.
2399
2400       • "$string = Date::Pcalc::Version();"
2401
2402         This function returns a string with the (numeric) version number of
2403         the file "Pcalc.pm" at the core of this package.
2404
2405         Note that under all normal circumstances, this version number should
2406         be identical with the one found in the Perl variable
2407         "$Date::Pcalc::VERSION" (the version number of the "Pcalc.pm" file).
2408
2409         Since this function is not exported, you always have to qualify it
2410         explicitly, i.e., ""Date::Pcalc::Version()"".
2411
2412         This is to avoid possible name space conflicts with version functions
2413         from other modules.
2414

RECIPES

2416       1)  How do I compare two dates?
2417
2418           Solution #1:
2419
2420             use Date::Pcalc qw( Date_to_Days );
2421
2422             if (Date_to_Days($year1,$month1,$day1)  <
2423                 Date_to_Days($year2,$month2,$day2))
2424
2425             if (Date_to_Days($year1,$month1,$day1)  <=
2426                 Date_to_Days($year2,$month2,$day2))
2427
2428             if (Date_to_Days($year1,$month1,$day1)  >
2429                 Date_to_Days($year2,$month2,$day2))
2430
2431             if (Date_to_Days($year1,$month1,$day1)  >=
2432                 Date_to_Days($year2,$month2,$day2))
2433
2434             if (Date_to_Days($year1,$month1,$day1)  ==
2435                 Date_to_Days($year2,$month2,$day2))
2436
2437             if (Date_to_Days($year1,$month1,$day1)  !=
2438                 Date_to_Days($year2,$month2,$day2))
2439
2440             $cmp = (Date_to_Days($year1,$month1,$day1)  <=>
2441                     Date_to_Days($year2,$month2,$day2));
2442
2443           Solution #2:
2444
2445             use Date::Pcalc qw( Delta_Days );
2446
2447             if (Delta_Days($year1,$month1,$day1,
2448                            $year2,$month2,$day2) > 0)
2449
2450             if (Delta_Days($year1,$month1,$day1,
2451                            $year2,$month2,$day2) >= 0)
2452
2453             if (Delta_Days($year1,$month1,$day1,
2454                            $year2,$month2,$day2) < 0)
2455
2456             if (Delta_Days($year1,$month1,$day1,
2457                            $year2,$month2,$day2) <= 0)
2458
2459             if (Delta_Days($year1,$month1,$day1,
2460                            $year2,$month2,$day2) == 0)
2461
2462             if (Delta_Days($year1,$month1,$day1,
2463                            $year2,$month2,$day2) != 0)
2464
2465       2)  How do I check whether a given date lies within a certain range of
2466           dates?
2467
2468             use Date::Pcalc qw( Date_to_Days );
2469
2470             $lower = Date_to_Days($year1,$month1,$day1);
2471             $upper = Date_to_Days($year2,$month2,$day2);
2472
2473             $date = Date_to_Days($year,$month,$day);
2474
2475             if (($date >= $lower) && ($date <= $upper))
2476             {
2477                 # ok
2478             }
2479             else
2480             {
2481                 # not ok
2482             }
2483
2484       3)  How do I compare two dates with times? How do I check whether two
2485           dates and times lie more or less than a given time interval apart?
2486
2487           Solution #1:
2488
2489             use Date::Pcalc qw( Add_Delta_DHMS Date_to_Days );
2490
2491             @date1 = (2002,8,31,23,59,1);
2492             @date2 = (2002,9,1,11,30,59); # ==> less than 12 hours
2493
2494             #@date1 = (2002,8,31,22,59,1);
2495             #@date2 = (2002,9,1,11,30,59); # ==> more than 12 hours
2496
2497             # Omit the next line if you just want to compare the two dates
2498             # (and change @date3 and @d3 to @date1 and @d1, respectively):
2499
2500             @date3 = Add_Delta_DHMS(@date1, 0,12,0,0); # ==> is the difference within 12 hours?
2501
2502             @d2 = ( Date_to_Days(@date2[0..2]), ($date2[3]*60+$date2[4])*60+$date2[5] );
2503             @d3 = ( Date_to_Days(@date3[0..2]), ($date3[3]*60+$date3[4])*60+$date3[5] );
2504
2505             @diff = ( $d2[0]-$d3[0], $d2[1]-$d3[1] );
2506
2507             if ($diff[0] > 0 and $diff[1] < 0) { $diff[0]--; $diff[1] += 86400; }
2508             if ($diff[0] < 0 and $diff[1] > 0) { $diff[0]++; $diff[1] -= 86400; }
2509
2510             if (($diff[0] || $diff[1]) >= 0) { print "More than 12 hours.\n"; }
2511             else                             { print "Less than 12 hours.\n"; }
2512
2513           Solution #2:
2514
2515           This solution is only feasible if your dates are guaranteed to lie
2516           within the range given by your system's epoch and overflow date and
2517           time!
2518
2519                Unix:    1-Jan-1970 00:00:00  to  19-Jan-2038 03:14:07
2520                MacOS:   1-Jan-1904 00:00:00  to   6-Feb-2040 06:28:15
2521
2522             use Date::Pcalc qw( Date_to_Time );
2523
2524             @date1 = (2002,8,31,23,59,1);
2525             @date2 = (2002,9,1,11,30,59); # ==> less than 12 hours
2526
2527             #@date1 = (2002,8,31,22,59,1);
2528             #@date2 = (2002,9,1,11,30,59); # ==> more than 12 hours
2529
2530             $d1 = Date_to_Time(@date1);
2531             $d2 = Date_to_Time(@date2);
2532
2533             if ($d1 <= $d2) { print "The two dates are in chronological order.\n"; }
2534             else            { print "The two dates are in reversed order.\n"; }
2535
2536             if ($d1 + 12*60*60 <= $d2) { print "More than 12 hours.\n"; }
2537             else                       { print "Less than 12 hours.\n"; }
2538
2539       4)  How do I verify whether someone has a certain age?
2540
2541             use Date::Pcalc qw( Decode_Date_EU Today leap_year Delta_Days );
2542
2543             $date = <STDIN>; # get birthday
2544
2545             ($year1,$month1,$day1) = Decode_Date_EU($date);
2546
2547             ($year2,$month2,$day2) = Today();
2548
2549             if (($day1 == 29) && ($month1 == 2) && !leap_year($year2))
2550                 { $day1--; }
2551
2552             if ( (($year2 - $year1) >  18) ||
2553                ( (($year2 - $year1) == 18) &&
2554                (Delta_Days($year2,$month1,$day1, $year2,$month2,$day2) >= 0) ) )
2555             {
2556                 print "Ok - you are over 18.\n";
2557             }
2558             else
2559             {
2560                 print "Sorry - you aren't 18 yet!\n";
2561             }
2562
2563             Or, alternatively (substituting the last "if" statement above):
2564
2565             if (($year1+18 <=> $year2 || $month1 <=> $month2 || $day1 <=> $day2) <= 0)
2566                 { print "Ok - you are over 18.\n"; }
2567             else
2568                 { print "Sorry - you aren't 18 yet!\n"; }
2569
2570       5)  How do I calculate the number of the week of month the current date
2571           lies in?
2572
2573           For example:
2574
2575                       April 1998
2576               Mon Tue Wed Thu Fri Sat Sun
2577                         1   2   3   4   5  =  week #1
2578                 6   7   8   9  10  11  12  =  week #2
2579                13  14  15  16  17  18  19  =  week #3
2580                20  21  22  23  24  25  26  =  week #4
2581                27  28  29  30              =  week #5
2582
2583           Solution:
2584
2585             use Date::Pcalc qw( Today Day_of_Week );
2586
2587             ($year,$month,$day) = Today();
2588
2589             $week = int(($day + Day_of_Week($year,$month,1) - 2) / 7) + 1;
2590
2591       6)  How do I calculate whether a given date is the 1st, 2nd, 3rd, 4th
2592           or 5th of that day of week in the given month?
2593
2594           For example:
2595
2596                      October 2000
2597               Mon Tue Wed Thu Fri Sat Sun
2598                                         1
2599                 2   3   4   5   6   7   8
2600                 9  10  11  12  13  14  15
2601                16  17  18  19  20  21  22
2602                23  24  25  26  27  28  29
2603                30  31
2604
2605           Is Sunday, the 15th of October 2000, the 1st, 2nd, 3rd, 4th or 5th
2606           Sunday of that month?
2607
2608           Solution:
2609
2610             use Date::Pcalc qw( Day_of_Week Delta_Days
2611                                 Nth_Weekday_of_Month_Year
2612                                 Date_to_Text_Long English_Ordinal
2613                                 Day_of_Week_to_Text Month_to_Text );
2614
2615             ($year,$month,$day) = (2000,10,15);
2616
2617             $dow = Day_of_Week($year,$month,$day);
2618
2619             $n = int( Delta_Days(
2620                       Nth_Weekday_of_Month_Year($year,$month,$dow,1),
2621                       $year,$month,$day)
2622                       / 7) + 1;
2623
2624             printf("%s is the %s %s in %s %d.\n",
2625                 Date_to_Text_Long($year,$month,$day),
2626                 English_Ordinal($n),
2627                 Day_of_Week_to_Text($dow),
2628                 Month_to_Text($month),
2629                 $year);
2630
2631           This prints:
2632
2633             Sunday, October 15th 2000 is the 3rd Sunday in October 2000.
2634
2635       7)  How do I calculate the date of the Wednesday of the same week as
2636           the current date?
2637
2638           Solution #1:
2639
2640             use Date::Pcalc qw( Today Day_of_Week Add_Delta_Days );
2641
2642             $searching_dow = 3; # 3 = Wednesday
2643
2644             @today = Today();
2645
2646             $current_dow = Day_of_Week(@today);
2647
2648             @date = Add_Delta_Days(@today, $searching_dow - $current_dow);
2649
2650           Solution #2:
2651
2652             use Date::Pcalc qw( Today Add_Delta_Days
2653                                 Monday_of_Week Week_of_Year );
2654
2655             $searching_dow = 3; # 3 = Wednesday
2656
2657             @today = Today();
2658
2659             @date = Add_Delta_Days( Monday_of_Week( Week_of_Year(@today) ),
2660                                     $searching_dow - 1 );
2661
2662           Solution #3:
2663
2664             use Date::Pcalc qw( Standard_to_Business Today
2665                                 Business_to_Standard );
2666
2667             @business = Standard_to_Business(Today());
2668
2669             $business[2] = 3; # 3 = Wednesday
2670
2671             @date = Business_to_Standard(@business);
2672
2673       8)  How can I add a week offset to a business date (including across
2674           year boundaries)?
2675
2676             use Date::Pcalc qw( Business_to_Standard Add_Delta_Days
2677                                 Standard_to_Business );
2678
2679             @temp = Business_to_Standard($year,$week,$dow);
2680
2681             @temp = Add_Delta_Days(@temp, $week_offset * 7);
2682
2683             ($year,$week,$dow) = Standard_to_Business(@temp);
2684
2685       9)  How do I calculate the last and the next Saturday for any given
2686           date?
2687
2688             use Date::Pcalc qw( Today Day_of_Week Add_Delta_Days
2689                                 Day_of_Week_to_Text Date_to_Text );
2690
2691             $searching_dow = 6; # 6 = Saturday
2692
2693             @today = Today();
2694
2695             $current_dow = Day_of_Week(@today);
2696
2697             if ($searching_dow == $current_dow)
2698             {
2699                 @prev = Add_Delta_Days(@today,-7);
2700                 @next = Add_Delta_Days(@today,+7);
2701             }
2702             else
2703             {
2704                 if ($searching_dow > $current_dow)
2705                 {
2706                     @next = Add_Delta_Days(@today,
2707                               $searching_dow - $current_dow);
2708                     @prev = Add_Delta_Days(@next,-7);
2709                 }
2710                 else
2711                 {
2712                     @prev = Add_Delta_Days(@today,
2713                               $searching_dow - $current_dow);
2714                     @next = Add_Delta_Days(@prev,+7);
2715                 }
2716             }
2717
2718             $dow = Day_of_Week_to_Text($searching_dow);
2719
2720             print "Today is:      ", ' ' x length($dow),
2721                                          Date_to_Text(@today), "\n";
2722             print "Last $dow was:     ", Date_to_Text(@prev),  "\n";
2723             print "Next $dow will be: ", Date_to_Text(@next),  "\n";
2724
2725           This will print something like:
2726
2727             Today is:              Sun 12-Apr-1998
2728             Last Saturday was:     Sat 11-Apr-1998
2729             Next Saturday will be: Sat 18-Apr-1998
2730
2731       10) How can I calculate the last business day (payday!) of a month?
2732
2733           Solution #1 (holidays NOT taken into account):
2734
2735             use Date::Pcalc qw( Days_in_Month Day_of_Week Add_Delta_Days );
2736
2737             $day = Days_in_Month($year,$month);
2738             $dow = Day_of_Week($year,$month,$day);
2739             if ($dow > 5)
2740             {
2741                 ($year,$month,$day) =
2742                     Add_Delta_Days($year,$month,$day, 5-$dow);
2743             }
2744
2745           Solution #2 (holidays taken into account):
2746
2747           This solution expects a multi-dimensional array "@holiday", which
2748           contains all holidays, as follows: ""$holiday[$year][$month][$day]
2749           = 1;"".
2750
2751           (See the description of the function ""Easter_Sunday()"" further
2752           above for how to calculate the moving (variable) christian feast
2753           days!)
2754
2755           Days which are not holidays remain undefined or should have a value
2756           of zero in this array.
2757
2758             use Date::Pcalc qw( Days_in_Month Add_Delta_Days Day_of_Week );
2759
2760             $day = Days_in_Month($year,$month);
2761             while (1)
2762             {
2763                 while ($holiday[$year][$month][$day])
2764                 {
2765                     ($year,$month,$day) =
2766                         Add_Delta_Days($year,$month,$day, -1);
2767                 }
2768                 $dow = Day_of_Week($year,$month,$day);
2769                 if ($dow > 5)
2770                 {
2771                     ($year,$month,$day) =
2772                         Add_Delta_Days($year,$month,$day, 5-$dow);
2773                 }
2774                 else { last; }
2775             }
2776
2777           Solution #3 (holidays taken into account, more comfortable, but
2778           requires Date::Pcalendar(3) and Date::Pcalc::Object(3)):
2779
2780             use Date::Pcalc::Object qw( Today Add_Delta_YM Date_to_Text_Long );
2781             use Date::Pcalendar::Profiles qw($Profiles);
2782             use Date::Pcalendar;
2783
2784             $calendar = Date::Pcalendar->new( $Profiles->{'DE-BW'} );
2785
2786             @today = Today();
2787             @nextmonth = Add_Delta_YM(@today[0,1],1, 0,1);
2788
2789             $workaround = $calendar->add_delta_workdays(@nextmonth,+1);
2790             $payday     = $calendar->add_delta_workdays($workaround,-2);
2791
2792             print "Pay day = ", Date_to_Text_Long($payday->date()), "\n";
2793
2794           The "workaround" is necessary due to a bug in the method
2795           "add_delta_workdays()" when adding a negative number of workdays.
2796
2797       11) How do I convert a MS Visual Basic "DATETIME" value into its date
2798           and time constituents?
2799
2800             use Date::Pcalc qw( Add_Delta_DHMS Date_to_Text );
2801
2802             $datetime = "35883.121653";
2803
2804             ($Dd,$Dh,$Dm,$Ds) = ($datetime =~ /^(\d+)\.(\d\d)(\d\d)(\d\d)$/);
2805
2806             ($year,$month,$day, $hour,$min,$sec) =
2807                 Add_Delta_DHMS(1900,1,1, 0,0,0, $Dd,$Dh,$Dm,$Ds);
2808
2809             printf("The given date is %s %02d:%02d:%02d\n",
2810                 Date_to_Text($year,$month,$day), $hour, $min, $sec);
2811
2812           This prints:
2813
2814             The given date is Tue 31-Mar-1998 12:16:53
2815
2816           Since I do not have or use Visual Basic, I can't guarantee that the
2817           number format assumed here is really the one used by Visual Basic -
2818           but you get the general idea. ":-)"
2819
2820           Moreover, consider the following:
2821
2822           Morten Sickel <Morten.Sickel@nrpa.no> wrote:
2823
2824           I discovered a bug in Excel (2000): Excel thinks that 1900 was a
2825           leap year. Users should use 31-Dec-1899 as the date to add an Excel
2826           date value to in order to get the correct date.
2827
2828           I found out on the web that this bug originated in Lotus 123, which
2829           made 29-Feb-1900 an "industrial standard". MS chose to keep the bug
2830           in order to be compatible with Lotus 123. But they have not
2831           mentioned anything about it in the help files.
2832
2833       12) How can I send a reminder to members of a group on the day before a
2834           meeting which occurs every first Friday of a month?
2835
2836             use Date::Pcalc qw( Today Date_to_Days Add_Delta_YMD
2837                                 Nth_Weekday_of_Month_Year );
2838
2839             ($year,$month,$day) = Today();
2840
2841             $tomorrow = Date_to_Days($year,$month,$day) + 1;
2842
2843             $dow = 5; # 5 = Friday
2844             $n   = 1; # 1 = First of that day of week
2845
2846             $meeting_this_month = Date_to_Days(
2847                 Nth_Weekday_of_Month_Year($year,$month,$dow,$n) );
2848
2849             ($year,$month,$day) = Add_Delta_YMD($year,$month,$day, 0,1,0);
2850
2851             $meeting_next_month = Date_to_Days(
2852                 Nth_Weekday_of_Month_Year($year,$month,$dow,$n) );
2853
2854             if (($tomorrow == $meeting_this_month) ||
2855                 ($tomorrow == $meeting_next_month))
2856             {
2857                 # Send reminder e-mail!
2858             }
2859
2860       13) How can I print a date in a different format than provided by the
2861           functions ""Date_to_Text()"", ""Date_to_Text_Long()"" or
2862           ""Compressed_to_Text()""?
2863
2864             use Date::Pcalc qw( Today Day_of_Week_to_Text
2865                                 Day_of_Week Month_to_Text
2866                                 English_Ordinal );
2867
2868             ($year,$month,$day) = Today();
2869
2870           For example with leading zeros for the day: "Fri 03-Jan-1964"
2871
2872             printf("%.3s %02d-%.3s-%d\n",
2873                 Day_of_Week_to_Text(Day_of_Week($year,$month,$day)),
2874                 $day,
2875                 Month_to_Text($month),
2876                 $year);
2877
2878           For example in U.S. american format: "April 12th, 1998"
2879
2880             $string = sprintf("%s %s, %d",
2881                           Month_to_Text($month),
2882                           English_Ordinal($day),
2883                           $year);
2884
2885           For example in one of the possible formats as specified by
2886           ISO 8601:
2887
2888             @date = ($year,$month,$day,$hour,$min,$sec);
2889             $date = sprintf("%d-%02d-%02d %02d:%02d:%02d", @date);
2890
2891           (See also "printf" in perlfunc(1) and/or "sprintf" in perlfunc(1)!)
2892
2893       14) How can I iterate through a range of dates?
2894
2895             use Date::Pcalc qw( Delta_Days Add_Delta_Days );
2896
2897             @start = (1999,5,27);
2898             @stop  = (1999,6,1);
2899
2900             $j = Delta_Days(@start,@stop);
2901
2902             for ( $i = 0; $i <= $j; $i++ )
2903             {
2904                 @date = Add_Delta_Days(@start,$i);
2905                 printf("%4d/%02d/%02d\n", @date);
2906             }
2907
2908           Note that the loop can be improved; see also the recipe below.
2909
2910       15) How can I create a (Perl) list of dates in a certain range?
2911
2912             use Date::Pcalc qw( Delta_Days Add_Delta_Days Date_to_Text );
2913
2914             sub date_range
2915             {
2916                 my(@date) = (@_)[0,1,2];
2917                 my(@list);
2918                 my($i);
2919
2920                 $i = Delta_Days(@_);
2921                 while ($i-- >= 0)
2922                 {
2923                     push( @list, [ @date ] );
2924                     @date = Add_Delta_Days(@date, 1) if ($i >= 0);
2925                 }
2926                 return(@list);
2927             }
2928
2929             @range = &date_range(1999,11,3, 1999,12,24); # in chronological order
2930
2931             foreach $date (@range)
2932             {
2933                 print Date_to_Text(@{$date}), "\n";
2934             }
2935
2936           Note that you probably shouldn't use this one, because it is much
2937           more efficient to iterate through all the dates (as shown in the
2938           recipe immediately above) than to construct such an array and then
2939           to loop through it. Also, it is much more space-efficient not to
2940           create this array.
2941
2942       16) How can I calculate the difference in days between dates, but
2943           without counting Saturdays and Sundays?
2944
2945             sub Delta_Business_Days
2946             {
2947                 my(@date1) = (@_)[0,1,2];
2948                 my(@date2) = (@_)[3,4,5];
2949                 my($minus,$result,$dow1,$dow2,$diff,$temp);
2950
2951                 $minus  = 0;
2952                 $result = Delta_Days(@date1,@date2);
2953                 if ($result != 0)
2954                 {
2955                     if ($result < 0)
2956                     {
2957                         $minus = 1;
2958                         $result = -$result;
2959                         $dow1 = Day_of_Week(@date2);
2960                         $dow2 = Day_of_Week(@date1);
2961                     }
2962                     else
2963                     {
2964                         $dow1 = Day_of_Week(@date1);
2965                         $dow2 = Day_of_Week(@date2);
2966                     }
2967                     $diff = $dow2 - $dow1;
2968                     $temp = $result;
2969                     if ($diff != 0)
2970                     {
2971                         if ($diff < 0)
2972                         {
2973                             $diff += 7;
2974                         }
2975                         $temp -= $diff;
2976                         $dow1 += $diff;
2977                         if ($dow1 > 6)
2978                         {
2979                             $result--;
2980                             if ($dow1 > 7)
2981                             {
2982                                 $result--;
2983                             }
2984                         }
2985                     }
2986                     if ($temp != 0)
2987                     {
2988                         $temp /= 7;
2989                         $result -= ($temp << 1);
2990                     }
2991                 }
2992                 if ($minus) { return -$result; }
2993                 else        { return  $result; }
2994             }
2995
2996           This solution is probably of little practical value, however,
2997           because it doesn't take legal holidays into account.
2998
2999           See Date::Pcalendar(3) for how to do that.
3000
3001       17) How can I "normalize" the output of the "Delta_YMDHMS()" (or
3002           "Delta_YMD()") function so that it contains only positive values?
3003
3004           I.e., how can I show a difference in date (and time) in a more
3005           human-readable form, for example in order to show how much time
3006           until (or since) the expiration of something (e.g. an account, a
3007           domain, a credit card, etc.) is left (has passed)?
3008
3009           Correct solution: Use the functions "N_Delta_YMDHMS()" and
3010           "N_Delta_YMD()" instead!
3011
3012           The following gives a rudimentary sketch of a (much inferior)
3013           solution, which is maintained here only for historical reasons of
3014           this module:
3015
3016           a) Delta_YMDHMS():
3017
3018             #!perl
3019             use strict;
3020             use Date::Pcalc qw(Today_and_Now Delta_YMDHMS Add_Delta_YMDHMS Delta_DHMS Date_to_Text);
3021
3022             my $today = [Today_and_Now()];
3023             my $target = [2005,1,1,0,0,0];
3024
3025             my $sign = "until";
3026             my $delta = Normalize_Delta_YMDHMS($today,$target);
3027             if ($delta->[0] < 0)
3028             {
3029                 $sign = "since";
3030                 $delta = Normalize_Delta_YMDHMS($target,$today);
3031             }
3032             printf("Today is %s %02d:%02d:%02d\n", Date_to_Text(@{$today}[0..2]), @{$today}[3..5]);
3033             printf
3034             (
3035                 "%d year%s, %d month%s, %d day%s, %d hour%s, %d minute%s, %d second%s %s %s %02d:%02d:%02d\n",
3036                 $delta->[0], (($delta->[0]==1)?'':'s'),
3037                 $delta->[1], (($delta->[1]==1)?'':'s'),
3038                 $delta->[2], (($delta->[2]==1)?'':'s'),
3039                 $delta->[3], (($delta->[3]==1)?'':'s'),
3040                 $delta->[4], (($delta->[4]==1)?'':'s'),
3041                 $delta->[5], (($delta->[5]==1)?'':'s'),
3042                 $sign,
3043                 Date_to_Text(@{$target}[0..2]),
3044                 @{$target}[3..5]
3045             );
3046
3047             sub Normalize_Delta_YMDHMS
3048             {
3049                 my($date1,$date2) = @_;
3050                 my(@delta);
3051
3052                 @delta = Delta_YMDHMS(@$date1,@$date2);
3053                 while ($delta[1] < 0 or
3054                        $delta[2] < 0 or
3055                        $delta[3] < 0 or
3056                        $delta[4] < 0 or
3057                        $delta[5] < 0)
3058                 {
3059                     if ($delta[1] < 0) { $delta[0]--; $delta[1] += 12; }
3060                     if ($delta[2] < 0)
3061                     {
3062                         $delta[1]--;
3063                         @delta[2..5] = (0,0,0,0);
3064                         @delta[2..5] = Delta_DHMS(Add_Delta_YMDHMS(@$date1,@delta),@$date2);
3065                     }
3066                     if ($delta[3] < 0) { $delta[2]--; $delta[3] += 24; }
3067                     if ($delta[4] < 0) { $delta[3]--; $delta[4] += 60; }
3068                     if ($delta[5] < 0) { $delta[4]--; $delta[5] += 60; }
3069                 }
3070                 return \@delta;
3071             }
3072
3073           b) Delta_YMD():
3074
3075             #!perl
3076             use strict;
3077             use Date::Pcalc qw(Today Delta_YMD Add_Delta_YM Delta_Days Date_to_Text);
3078
3079             my($sign,$delta);
3080             my $today = [Today()];
3081             my $target = [2005,1,1];
3082
3083             if (Delta_Days(@$today,@$target) < 0)
3084             {
3085                 $sign = "since";
3086                 $delta = Normalize_Delta_YMD($target,$today);
3087             }
3088             else
3089             {
3090                 $sign = "until";
3091                 $delta = Normalize_Delta_YMD($today,$target);
3092             }
3093             print "Today is ", Date_to_Text(@$today), "\n";
3094             printf
3095             (
3096                 "%d year%s, %d month%s, %d day%s %s %s\n",
3097                 $delta->[0], (($delta->[0]==1)?'':'s'),
3098                 $delta->[1], (($delta->[1]==1)?'':'s'),
3099                 $delta->[2], (($delta->[2]==1)?'':'s'),
3100                 $sign,
3101                 Date_to_Text(@$target)
3102             );
3103
3104             sub Normalize_Delta_YMD
3105             {
3106                 my($date1,$date2) = @_;
3107                 my(@delta);
3108
3109                 @delta = Delta_YMD(@$date1,@$date2);
3110                 while ($delta[1] < 0 or $delta[2] < 0)
3111                 {
3112                     if ($delta[1] < 0) { $delta[0]--; $delta[1] += 12; }
3113                     if ($delta[2] < 0)
3114                     {
3115                         $delta[1]--;
3116                         $delta[2] = Delta_Days(Add_Delta_YM(@$date1,@delta[0,1]),@$date2);
3117                     }
3118                 }
3119                 return \@delta;
3120             }
3121
3122           Note that for normalizing just a time vector, you can use the
3123           built-in function "Normalize_DHMS()". However, this will yield
3124           either all positive OR all negative values, NOT all positive values
3125           as above.
3126

SEE ALSO

3128       Date::Calc(3), Date::Calc::Util(3), Date::Pcalc::Object(3),
3129       Date::Pcalendar(3), Date::Pcalendar::Year(3),
3130       Date::Pcalendar::Profiles(3).
3131
3132         "The Calendar FAQ":
3133         http://www.tondering.dk/claus/calendar.html
3134         by Claus Tondering <claus@tondering.dk>
3135

BEWARE

3137       When you are using the (deprecated) function "Language()", the language
3138       setting is stored in a global variable.
3139
3140       This may cause conflicts between threads or modules running
3141       concurrently.
3142
3143       Therefore, in order to avoid such conflicts, NEVER use the function
3144       "Language()", but ALWAYS pass a language parameter to the functions
3145       which are language-dependent.
3146

VERSION

3148       This man page documents "Date::Pcalc" version 6.1.
3149

AUTHOR

3151         Steffen Beyer
3152         mailto:STBEY@cpan.org
3153         http://www.engelschall.com/u/sb/download/
3154
3156       Copyright (c) 1995 - 2009 by Steffen Beyer. All rights reserved.
3157

LICENSE

3159       This package is free software; you can redistribute it and/or modify it
3160       under the same terms as Perl itself, i.e., under the terms of the
3161       "Artistic License" or the "GNU General Public License".
3162
3163       Please refer to the files "Artistic.txt" and "GNU_GPL.txt" in this
3164       distribution for details!
3165

DISCLAIMER

3167       This package is distributed in the hope that it will be useful, but
3168       WITHOUT ANY WARRANTY; without even the implied warranty of
3169       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
3170
3171       See the "GNU General Public License" for more details.
3172

POD ERRORS

3174       Hey! The above document had some coding errors, which are explained
3175       below:
3176
3177       Around line 1777:
3178           Non-ASCII character seen before =encoding in 'Français'. Assuming
3179           CP1252
3180
3181
3182
3183perl v5.34.0                      2022-01-21                          Pcalc(3)
Impressum