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

NAME

6       Date::Pcalc - Gregorian calendar date calculations
7

PREFACE

9       This package consists of a Perl module for all kinds of date calcula‐
10       tions based on the Gregorian calendar (the one used in all western
11       countries today), thereby complying with all relevant norms and stan‐
12       dards: ISO/R 2015-1971, DIN 1355 and, to some extent, ISO 8601 (where
13       applicable).
14
15       (See also http://www.engelschall.com/u/sb/download/Date-Calc/DIN1355/
16       for a scan of part of the "DIN 1355" document (in German)).
17
18       This module is a direct translation of Steffen Beyer's excellent
19       Date::Calc module to Perl.
20
21       The module of course handles year numbers of 2000 and above correctly
22       ("Year 2000" or "Y2K" compliance) -- actually all year numbers from 1
23       to the largest positive integer representable on your system (which is
24       at least 32767) can be dealt with.
25
26       Note that this package EXTRAPOLATES the Gregorian calendar BACK until
27       the year 1 A.D. -- even though the Gregorian calendar was only adopted
28       in 1582 by most (not all) European countries, in obedience to the cor‐
29       responding decree of catholic pope Gregor I in that year.
30
31       Some (mainly protestant) countries continued to use the Julian calendar
32       (used until then) until as late as the beginning of the 20th century.
33
34       Finally, note that this package is not intended to do everything you
35       could ever imagine automagically for you; it is rather intended to
36       serve as a toolbox (in the best of UNIX spirit and traditions) which
37       should, however, always get you where you want to go.
38
39       If nevertheless you can't figure out how to solve a particular problem,
40       please let me know! (See e-mail address at the bottom of this docu‐
41       ment.)
42

SYNOPSIS

44         use Date::Pcalc qw(
45             Days_in_Year
46             Days_in_Month
47             Weeks_in_Year
48             leap_year
49             check_date
50             check_business_date
51             Day_of_Year
52             Date_to_Days
53             Day_of_Week
54             Week_Number
55             Week_of_Year
56             Monday_of_Week
57             Nth_Weekday_of_Month_Year
58             Standard_to_Business
59             Business_to_Standard
60             Delta_Days
61             Delta_DHMS
62             Add_Delta_Days
63             Add_Delta_DHMS
64             Add_Delta_YMD
65             System_Clock
66             Today
67             Now
68             Today_and_Now
69             Easter_Sunday
70             Decode_Month
71             Decode_Day_of_Week
72             Decode_Language
73             Decode_Date_EU
74             Decode_Date_US
75             Compress
76             Uncompress
77             check_compressed
78             Compressed_to_Text
79             Date_to_Text
80             Date_to_Text_Long
81             English_Ordinal
82             Calendar
83             Month_to_Text
84             Day_of_Week_to_Text
85             Day_of_Week_Abbreviation
86             Language_to_Text
87             Language
88             Languages
89             Decode_Date_EU2
90             Decode_Date_US2
91             Parse_Date
92         );
93
94         use Date::Pcalc qw(:all);
95
96         Days_in_Year
97             $days = Days_in_Year($year,$month);
98
99         Days_in_Month
100             $days = Days_in_Month($year,$month);
101
102         Weeks_in_Year
103             $weeks = Weeks_in_Year($year);
104
105         leap_year
106             if (leap_year($year))
107
108         check_date
109             if (check_date($year,$month,$day))
110
111         check_business_date
112             if (check_business_date($year,$week,$dow))
113
114         Day_of_Year
115             $doy = Day_of_Year($year,$month,$day);
116
117         Date_to_Days
118             $days = Date_to_Days($year,$month,$day);
119
120         Day_of_Week
121             $dow = Day_of_Week($year,$month,$day);
122
123         Week_Number
124             $week = Week_Number($year,$month,$day);
125
126         Week_of_Year
127             ($week,$year) = Week_of_Year($year,$month,$day);
128
129         Monday_of_Week
130             ($year,$month,$day) = Monday_of_Week($week,$year);
131
132         Nth_Weekday_of_Month_Year
133             if (($year,$month,$day) =
134             Nth_Weekday_of_Month_Year($year,$month,$dow,$n))
135
136         Standard_to_Business
137             ($year,$week,$dow) =
138             Standard_to_Business($year,$month,$day);
139
140         Business_to_Standard
141             ($year,$month,$day) =
142             Business_to_Standard($year,$week,$dow);
143
144         Delta_Days
145             $Dd = Delta_Days($year1,$month1,$day1,
146                              $year2,$month2,$day2);
147
148         Delta_DHMS
149             ($Dd,$Dh,$Dm,$Ds) =
150             Delta_DHMS($year1,$month1,$day1, $hour1,$min1,$sec1,
151                        $year2,$month2,$day2, $hour2,$min2,$sec2);
152
153         Add_Delta_Days
154             ($year,$month,$day) =
155             Add_Delta_Days($year,$month,$day,
156                            $Dd);
157
158         Add_Delta_DHMS
159             ($year,$month,$day, $hour,$min,$sec) =
160             Add_Delta_DHMS($year,$month,$day, $hour,$min,$sec,
161                            $Dd,$Dh,$Dm,$Ds);
162
163         Add_Delta_YMD
164             ($year,$month,$day) =
165             Add_Delta_YMD($year,$month,$day,
166                           $Dy,$Dm,$Dd);
167
168         System_Clock
169             ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
170             System_Clock();
171
172         Today
173             ($year,$month,$day) = Today();
174
175         Now
176             ($hour,$min,$sec) = Now();
177
178         Today_and_Now
179             ($year,$month,$day, $hour,$min,$sec) = Today_and_Now();
180
181         Easter_Sunday
182             ($year,$month,$day) = Easter_Sunday($year);
183
184         Decode_Month
185             if ($month = Decode_Month($string))
186
187         Decode_Day_of_Week
188             if ($dow = Decode_Day_of_Week($string))
189
190         Decode_Language
191             if ($lang = Decode_Language($string))
192
193         Decode_Date_EU
194             if (($year,$month,$day) = Decode_Date_EU($string))
195
196         Decode_Date_US
197             if (($year,$month,$day) = Decode_Date_US($string))
198
199         Compress
200             $date = Compress($year,$month,$day);
201
202         Uncompress
203             if (($century,$year,$month,$day) = Uncompress($date))
204
205         check_compressed
206             if (check_compressed($date))
207
208         Compressed_to_Text
209             $string = Compressed_to_Text($date);
210
211         Date_to_Text
212             $string = Date_to_Text($year,$month,$day);
213
214         Date_to_Text_Long
215             $string = Date_to_Text_Long($year,$month,$day);
216
217         English_Ordinal
218             $string = English_Ordinal($number);
219
220         Calendar
221             $string = Calendar($year,$month);
222
223         Month_to_Text
224             $string = Month_to_Text($month);
225
226         Day_of_Week_to_Text
227             $string = Day_of_Week_to_Text($dow);
228
229         Day_of_Week_Abbreviation
230             $string = Day_of_Week_Abbreviation($dow);
231
232         Language_to_Text
233             $string = Language_to_Text($lang);
234
235         Language
236             $lang = Language();
237             Language($lang);
238             $oldlang = Language($newlang);
239
240         Languages
241             $max_lang = Languages();
242
243         Decode_Date_EU2
244             if (($year,$month,$day) = Decode_Date_EU2($string))
245
246         Decode_Date_US2
247             if (($year,$month,$day) = Decode_Date_US2($string))
248
249         Parse_Date
250             if (($year,$month,$day) = Parse_Date($string))
251
252         Version
253             $string = Date::Pcalc::Version();
254

IMPORTANT NOTES

256       (See the section "RECIPES" at the bottom of this document for solutions
257       to common problems!)
258
259       · "Year 2000" ("Y2K") compliance
260
261         The upper limit for any year number in this module is only given by
262         the size of the largest positive integer that can be represented in a
263         variable of the C type "int" on your system, which is at least 32767,
264         according to the ANSI C standard (exceptions see below).
265
266         Note that this package projects the Gregorian calendar back until the
267         year 1 A.D. -- even though the Gregorian calendar was only adopted in
268         1582 by most (not all) European countries, in obedience to the corre‐
269         sponding decree of catholic pope Gregor I in that year.
270
271         Therefore, BE SURE TO ALWAYS SPECIFY "1998" WHEN YOU MEAN "1998", for
272         instance, and DO NOT WRITE "98" INSTEAD, because this will in fact
273         perform a calculation based on the year "98" A.D. and NOT "1998"!
274
275         The only exceptions from this rule are the functions which contain
276         the word "compress" in their names (which only handle years between
277         1970 and 2069 and also accept the abbreviations "00" to "99"), and
278         the functions whose names begin with "Decode_Date_" (which map year
279         numbers below 100 to the range 1970 - 2069, using a technique known
280         as "windowing").
281
282       · First index
283
284         ALL ranges in this module start with "1", NOT "0"!
285
286         I.e., the day of month, day of week, day of year, month of year, week
287         of year, first valid year number and language ALL start counting at
288         one, NOT zero!
289
290         The only exception is the function ""Week_Number()"", which may in
291         fact return "0" when the given date actually lies in the last week of
292         the PREVIOUS year.
293
294       · Function naming conventions
295
296         Function names completely in lower case indicate a boolean return
297         value.
298
299       · Boolean values
300
301         Boolean values in this module are always a numeric zero ("0") for
302         "false" and a numeric one ("1") for "true".
303
304       · Exception handling
305
306         The functions in this module will usually die with a corresponding
307         error message if their input parameters, intermediate results or out‐
308         put values are out of range.
309
310         The following functions handle errors differently:
311
312           -  check_date()
313           -  check_business_date()
314           -  check_compressed()
315
316         (which return a "false" return value when the given input does not
317         represent a valid date),
318
319           -  Nth_Weekday_of_Month_Year()
320
321         (which returns an empty list if the requested 5th day of week does
322         not exist),
323
324           -  Decode_Month()
325           -  Decode_Day_of_Week()
326           -  Decode_Language()
327           -  Compress()
328
329         (which return "0" upon failure or invalid input), and
330
331           -  Decode_Date_EU()
332           -  Decode_Date_US()
333           -  Decode_Date_EU2()
334           -  Decode_Date_US2()
335           -  Parse_Date()
336           -  Uncompress()
337
338         (which return an empty list upon failure or invalid input).
339
340         Note that you can always catch an exception thrown by any of the
341         functions in this module and handle it yourself by enclosing the
342         function call in an ""eval"" with curly brackets and checking the
343         special variable "$@" (see "eval" in perlfunc(1) for details).
344

DESCRIPTION

346       · "use Date::Pcalc qw( Days_in_Year Days_in_Month ... );"
347
348       · "use Date::Pcalc qw(:all);"
349
350         You can either specify the functions you want to import explicitly by
351         enumerating them between the parentheses of the ""qw()"" operator, or
352         you can use the "":all"" tag instead to import ALL available func‐
353         tions.
354
355       · "$days = Days_in_Year($year,$month);"
356
357         This function returns the sum of the number of days in the months
358         starting with January up to and including "$month" in the given year
359         "$year".
360
361         I.e., ""Days_in_Year(1998,1)"" returns "31", ""Days_in_Year(1998,2)""
362         returns "59", ""Days_in_Year(1998,3)"" returns "90", and so on.
363
364         Note that ""Days_in_Year($year,12)"" returns the number of days in
365         the given year "$year", i.e., either "365" or "366".
366
367       · "$days = Days_in_Month($year,$month);"
368
369         This function returns the number of days in the given month "$month"
370         of the given year "$year".
371
372         The year must always be supplied, even though it is only needed when
373         the month is February, in order to determine wether it is a leap year
374         or not.
375
376         I.e., ""Days_in_Month(1998,1)"" returns "31",
377         ""Days_in_Month(1998,2)"" returns "28", ""Days_in_Month(2000,2)""
378         returns "29", ""Days_in_Month(1998,3)"" returns "31", and so on.
379
380       · "$weeks = Weeks_in_Year($year);"
381
382         This function returns the number of weeks in the given year "$year",
383         i.e., either "52" or "53".
384
385       · "if (leap_year($year))"
386
387         This function returns "true" ("1") if the given year "$year" is a
388         leap year and "false" ("0") otherwise.
389
390       · "if (check_date($year,$month,$day))"
391
392         This function returns "true" ("1") if the given three numerical val‐
393         ues "$year", "$month" and "$day" constitute a valid date, and "false"
394         ("0") otherwise.
395
396       · "if (check_business_date($year,$week,$dow))"
397
398         This function returns "true" ("1") if the given three numerical val‐
399         ues "$year", "$week" and "$dow" constitute a valid date in business
400         format, and "false" ("0") otherwise.
401
402         Beware that this function does NOT compute whether a given date is a
403         business day (i.e., Monday to Friday)!
404
405       · "$doy = Day_of_Year($year,$month,$day);"
406
407         This function returns the (relative) number of the day of the given
408         date in the given year.
409
410         E.g., ""Day_of_Year($year,1,1)"" returns "1",
411         ""Day_of_Year($year,2,1)"" returns "32", and
412         ""Day_of_Year($year,12,31)"" returns either "365" or "366".
413
414       · "$days = Date_to_Days($year,$month,$day);"
415
416         This function returns the (absolute) number of the day of the given
417         date, where counting starts at the 1st of January of the year 1 A.D.
418
419         I.e., ""Date_to_Days(1,1,1)"" returns "1", ""Date_to_Days(1,12,31)""
420         returns "365", ""Date_to_Days(2,1,1)"" returns "366",
421         ""Date_to_Days(1998,5,1)"" returns "729510", and so on.
422
423       · "$dow = Day_of_Week($year,$month,$day);"
424
425         This function returns the number of the day of week of the given
426         date.
427
428         The function returns "1" for Monday, "2" for Tuesday and so on until
429         "7" for Sunday.
430
431         Note that in the Hebrew calendar (on which the Christian calendar is
432         based), the week starts with Sunday and ends with the Sabbath or Sat‐
433         urday (where according to the Genesis (as described in the Bible) the
434         Lord rested from creating the world).
435
436         In medieval times, Catholic popes decreed the Sunday to be the offi‐
437         cial day of rest, in order to dissociate the Christian from the
438         Hebrew belief.
439
440         Nowadays, Sunday AND Saturday are commonly considered (and used as)
441         days of rest, usually referred to as the "week-end".
442
443         Consistent with this practice, current norms and standards (such as
444         ISO/R 2015-1971, DIN 1355 and ISO 8601) define Monday as the first
445         day of the week.
446
447       · "$week = Week_Number($year,$month,$day);"
448
449         This function returns the number of the week the given date lies in.
450
451         If the given date lies in the LAST week of the PREVIOUS year, "0" is
452         returned.
453
454         If the given date lies in the FIRST week of the NEXT year,
455         ""Weeks_in_Year($year) + 1"" is returned.
456
457       · "($week,$year) = Week_of_Year($year,$month,$day);"
458
459         This function returns the number of the week the given date lies in,
460         as well as the year that week belongs to.
461
462         I.e., if the given date lies in the LAST week of the PREVIOUS year,
463         ""(Weeks_in_Year($year-1), $year-1)"" is returned.
464
465         If the given date lies in the FIRST week of the NEXT year, ""(1,
466         $year+1)"" is returned.
467
468         Otherwise, ""(Week_Number($year,$month,$day), $year)"" is returned.
469
470       · "($year,$month,$day) = Monday_of_Week($week,$year);"
471
472         This function returns the date of the first day of the given week,
473         i.e., the Monday.
474
475         "$year" must be greater than or equal to "1", and "$week" must lie in
476         the range "1" to ""Weeks_in_Year($year)"".
477
478         Note that you can write ""($year,$month,$day) = Mon‐
479         day_of_Week(Week_of_Year($year,$month,$day));"" in order to calculate
480         the date of the Monday of the same week as the given date.
481
482       · "if (($year,$month,$day) = Nth_Week‐
483         day_of_Month_Year($year,$month,$dow,$n))"
484
485         This function calculates the date of the "$n"th day of week "$dow" in
486         the given month "$month" and year "$year"; such as, for example, the
487         3rd Thursday of a given month and year.
488
489         This can be used to send a notification mail to the members of a
490         group which meets regularly on every 3rd Thursday of a month, for
491         instance.
492
493         (See the section "RECIPES" near the end of this document for a code
494         snippet to actually do so.)
495
496         "$year" must be greater than or equal to "1", "$month" must lie in
497         the range "1" to "12", "$dow" must lie in the range "1" to "7" and
498         "$n" must lie in the range "1" to "5", or a fatal error (with appro‐
499         priate error message) occurs.
500
501         The function returns an empty list when the 5th of a given day of
502         week does not exist in the given month and year.
503
504       · "($year,$week,$dow) = Standard_to_Business($year,$month,$day);"
505
506         This function converts a given date from standard notation (year,
507         month, day (of month)) to business notation (year, week, day of
508         week).
509
510       · "($year,$month,$day) = Business_to_Standard($year,$week,$dow);"
511
512         This function converts a given date from business notation (year,
513         week, day of week) to standard notation (year, month, day (of
514         month)).
515
516       · "$Dd = Delta_Days($year1,$month1,$day1, $year2,$month2,$day2);"
517
518         This function returns the difference in days between the two given
519         dates.
520
521         The result is positive if the two dates are in chronological order,
522         i.e., if date #1 comes chronologically BEFORE date #2, and negative
523         if the order of the two dates is reversed.
524
525         The result is zero if the two dates are identical.
526
527       · "($Dd,$Dh,$Dm,$Ds) = Delta_DHMS($year1,$month1,$day1,
528         $hour1,$min1,$sec1, $year2,$month2,$day2, $hour2,$min2,$sec2);"
529
530         This function returns the difference in days, hours, minutes and sec‐
531         onds between the two given dates with times.
532
533         All four return values will be positive if the two dates are in
534         chronological order, i.e., if date #1 comes chronologically BEFORE
535         date #2, and negative (in all four return values!) if the order of
536         the two dates is reversed.
537
538         This is so that the two functions ""Delta_DHMS()"" and
539         ""Add_Delta_DHMS()"" (description see further below) are complemen‐
540         tary, i.e., mutually inverse:
541
542           Add_Delta_DHMS(@date1,@time1, Delta_DHMS(@date1,@time1, @date2,@time2))
543
544         yields ""(@date2,@time2)"" again, whereas
545
546           Add_Delta_DHMS(@date2,@time2,
547               map(-$_, Delta_DHMS(@date1,@time1, @date2,@time2)))
548
549         yields ""(@date1,@time1)"", and
550
551           Delta_DHMS(@date1,@time1, Add_Delta_DHMS(@date1,@time1, @delta))
552
553         yields "@delta" again.
554
555         The result is zero (in all four return values) if the two dates and
556         times are identical.
557
558       · "($year,$month,$day) = Add_Delta_Days($year,$month,$day, $Dd);"
559
560         This function has two principal uses:
561
562         First, it can be used to calculate a new date, given an initial date
563         and an offset (which may be positive or negative) in days, in order
564         to answer questions like "today plus 90 days -- which date gives
565         that?".
566
567         (In order to add a weeks offset, simply multiply the weeks offset
568         with "7" and use that as your days offset.)
569
570         Second, it can be used to convert the canonical representation of a
571         date, i.e., the number of that day (where counting starts at the 1st
572         of January in 1 A.D.), back into a date given as year, month and day.
573
574         Because counting starts at "1", you will actually have to subtract
575         "1" from the canonical date in order to get back the original date:
576
577           $canonical = Date_to_Days($year,$month,$day);
578
579           ($year,$month,$day) = Add_Delta_Days(1,1,1, $canonical - 1);
580
581         Moreover, this function is the inverse of the function
582         ""Delta_Days()"":
583
584           Add_Delta_Days(@date1, Delta_Days(@date1, @date2))
585
586         yields "@date2" again, whereas
587
588           Add_Delta_Days(@date2, -Delta_Days(@date1, @date2))
589
590         yields "@date1", and
591
592           Delta_Days(@date1, Add_Delta_Days(@date1, $delta))
593
594         yields "$delta" again.
595
596       · "($year,$month,$day, $hour,$min,$sec) =
597         Add_Delta_DHMS($year,$month,$day, $hour,$min,$sec, $Dd,$Dh,$Dm,$Ds);"
598
599         This function serves to add a days, hours, minutes and seconds offset
600         to a given date and time, in order to answer questions like "today
601         and now plus 7 days but minus 5 hours and then plus 30 minutes, what
602         date and time gives that?":
603
604           ($y,$m,$d,$H,$M,$S) = Add_Delta_DHMS(Today_and_Now(), +7,-5,+30,0);
605
606       · "($year,$month,$day) = Add_Delta_YMD($year,$month,$day,
607         $Dy,$Dm,$Dd);"
608
609         This function serves to add a years, months and days offset to a
610         given date.
611
612         (In order to add a weeks offset, simply multiply the weeks offset
613         with "7" and add this number to your days offset.)
614
615         Note that the three offsets for years, months and days are applied
616         separately from each other, in reverse order.
617
618         (This also allows them to have opposite signs.)
619
620         In other words, first the days offset is applied (using the function
621         ""Add_Delta_Days()"", internally), then the months offset, and
622         finally the years offset.
623
624         If the resulting date happens to fall on a day beyond the end of the
625         resulting month, like the 31st of April or the 29th of February (in
626         non-leap years), then the day is replaced by the last valid day of
627         that month in that year (e.g., the 30th of April or 28th of Febru‐
628         ary).
629
630         BEWARE that this behaviour differs from that of previous versions of
631         this module!
632
633         (Formerly, only the 29th of February in non-leap years was checked
634         for (which - in contrast to the current version - was replaced by the
635         1st of March). Other possible invalid dates were not checked (and
636         returned unwittingly), constituting a severe bug of previous ver‐
637         sions.)
638
639         BEWARE also that because of this replacement, but even more because a
640         year and a month offset is not equivalent to a fixed number of days,
641         the transformation performed by this function is NOT REVERSIBLE!
642
643         This is in contrast to the functions ""Add_Delta_Days()"" and
644         ""Add_Delta_DHMS()"", which for this very reason have inverse func‐
645         tions (namely ""Delta_Days()"" and ""Delta_DHMS()""), whereas there
646         exists no inverse for this function.
647
648         Note that for this same reason, even
649
650           @date = Add_Delta_YMD(
651                   Add_Delta_YMD(@date, $Dy,$Dm,$Dd), -$Dy,-$Dm,-$Dd);
652
653         will (in general!) NOT return the initial date "@date"!
654
655         (This might work in some cases, though.)
656
657         Note that this is NOT a program bug but NECESSARILY so because of the
658         varying lengths of years and months!
659
660       · "($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) = Sys‐
661         tem_Clock();"
662
663         If your operating system supports the corresponding system calls
664         (""time()"" and ""localtime()""), this function will return the
665         information provided by your system clock, i.e., the current date and
666         time, the number of the day of year, the number of the day of week
667         and a flag signaling wether daylight savings time is currently in
668         effect or not.
669
670         The ranges of values returned (and their meanings) are as follows:
671
672                         $year   :   should at least cover 1900..2038
673                         $month  :   1..12
674                         $day    :   1..31
675                         $hour   :   0..23
676                         $min    :   0..59
677                         $sec    :   0..59    (0..61 on some systems)
678                         $doy    :   1..366
679                         $dow    :   1..7
680                         $dst    :  -1..1
681
682         The day of week ("$dow") will be "1" for Monday, "2" for Tuesday and
683         so on until "7" for Sunday.
684
685         The daylight savings time flag ("$dst") will be ""-1"" if this infor‐
686         mation is not available on your system, "0" for no daylight savings
687         time (i.e., normal time) and "1" when daylight savings time is in
688         effect.
689
690         If your operating system does not provide the necessary system calls,
691         calling this function will result in a fatal "not available on this
692         system" error message.
693
694         If you want to handle this exception yourself, use ""eval"" as fol‐
695         lows:
696
697           eval { ($year,$month,$day, $hour,$min,$sec, $doy,$dow,$dst) =
698             System_Clock(); };
699
700           if ($@)
701           {
702               # Handle missing system clock
703               # (For instance, ask user to enter this information manually)
704           }
705
706         Note that curlies ("{" and "}") are used here to delimit the state‐
707         ment to be "eval"ed (which is the way to catch exceptions in Perl),
708         and not quotes (which is a way to evaluate Perl expressions at run‐
709         time).
710
711       · "($year,$month,$day) = Today();"
712
713         This function returns a subset of the values returned by the function
714         ""System_Clock()"" (see above for details), namely the current year,
715         month and day.
716
717         A fatal "not available on this system" error message will appear if
718         the corresponding system calls are not supported by your current
719         operating system.
720
721       · "($hour,$min,$sec) = Now();"
722
723         This function returns a subset of the values returned by the function
724         ""System_Clock()"" (see above for details), namely the current time
725         (hours, minutes and full seconds).
726
727         A fatal "not available on this system" error message will appear if
728         the corresponding system calls are not supported by your current
729         operating system.
730
731       · "($year,$month,$day, $hour,$min,$sec) = Today_and_Now();"
732
733         This function returns a subset of the values returned by the function
734         ""System_Clock()"" (see above for details), namely the current date
735         (year, month, day) and time (hours, minutes and full seconds).
736
737         A fatal "not available on this system" error message will appear if
738         the corresponding system calls are not supported by your current
739         operating system.
740
741       · "($year,$month,$day) = Easter_Sunday($year);"
742
743         This function calculates the date of easter sunday for all years in
744         the range from 1583 to 2299 (all other year numbers will result in a
745         fatal "year out of range" error message) using the method known as
746         the "Gaussian Rule".
747
748         Some related christian feast days which depend on the date of easter
749         sunday:
750
751           Carnival Monday / Rosenmontag / Veille du Mardi Gras   =  -48 days
752           Mardi Gras / Karnevalsdienstag / Mardi Gras            =  -47 days
753           Ash Wednesday / Aschermittwoch / Mercredi des Cendres  =  -46 days
754           Palm Sunday / Palmsonntag / Dimanche des Rameaux       =   -7 days
755           Easter Friday / Karfreitag / Vendredi Saint            =   -2 days
756           Easter Saturday / Ostersamstag / Samedi de Paques      =   -1 day
757           Easter Monday / Ostermontag / Lundi de Paques          =   +1 day
758           Ascension of Christ / Christi Himmelfahrt / Ascension  =  +39 days
759           Whitsunday / Pfingstsonntag / Dimanche de Pentecote    =  +49 days
760           Whitmonday / Pfingstmontag / Lundi de Pentecote        =  +50 days
761           Feast of Corpus Christi / Fronleichnam / Fete-Dieu     =  +60 days
762
763         Use the offsets shown above to calculate the date of the correspond‐
764         ing feast day as follows:
765
766           ($year,$month,$day) = Add_Delta_Days(Easter_Sunday($year), $offset));
767
768       · "if ($month = Decode_Month($string))"
769
770         This function takes a string as its argument, which should contain
771         the name of a month IN THE CURRENTLY SELECTED LANGUAGE (see further
772         below for details about multi-language support by this package), or
773         any uniquely identifying abbreviation of a month's name (i.e., the
774         first few letters), and returns the corresponding number (1..12) upon
775         a successful match, or "0" otherwise (therefore, the return value can
776         also be used as the conditional expression in an "if" statement).
777
778         Note that the input string may not contain any other characters which
779         do not pertain to the month's name, especially no leading or trailing
780         whitespace.
781
782         Note also that matching is performed in a case-insensitive manner
783         (this may depend on the "locale" setting on your current system,
784         though!)
785
786         With "English" as the currently selected language (which is the
787         default), the following examples will all return the value "9":
788
789           $month = Decode_Month("s");
790           $month = Decode_Month("Sep");
791           $month = Decode_Month("septemb");
792           $month = Decode_Month("September");
793
794       · "if ($dow = Decode_Day_of_Week($string))"
795
796         This function takes a string as its argument, which should contain
797         the name of a day of week IN THE CURRENTLY SELECTED LANGUAGE (see
798         further below for details about multi-language support by this pack‐
799         age), or any uniquely identifying abbreviation of the name of a day
800         of week (i.e., the first few letters), and returns the corresponding
801         number (1..7) upon a successful match, or "0" otherwise (therefore,
802         the return value can also be used as the conditional expression in an
803         "if" statement).
804
805         Note that the input string may not contain any other characters which
806         do not pertain to the name of the day of week, especially no leading
807         or trailing whitespace.
808
809         Note also that matching is performed in a case-insensitive manner
810         (this may depend on the "locale" setting on your current system,
811         though!)
812
813         With "English" as the currently selected language (which is the
814         default), the following examples will all return the value "3":
815
816           $dow = Decode_Day_of_Week("w");
817           $dow = Decode_Day_of_Week("Wed");
818           $dow = Decode_Day_of_Week("wednes");
819           $dow = Decode_Day_of_Week("Wednesday");
820
821       · "if ($lang = Decode_Language($string))"
822
823         This function takes a string as its argument, which should contain
824         the name of one of the languages supported by this package (IN THIS
825         VERY LANGUAGE ITSELF), or any uniquely identifying abbreviation of
826         the name of a language (i.e., the first few letters), and returns its
827         corresponding internal number (1..7 in the original distribution)
828         upon a successful match, or "0" otherwise (therefore, the return
829         value can also be used as the conditional expression in an "if"
830         statement).
831
832         Note that the input string may not contain any other characters which
833         do not pertain to the name of a language, especially no leading or
834         trailing whitespace.
835
836         Note also that matching is performed in a case-insensitive manner
837         (this may depend on the "locale" setting on your current system,
838         though!)
839
840         The original distribution supports the following seven languages:
841
842                     English                    ==>   1    (default)
843                     Français    (French)       ==>   2
844                     Deutsch     (German)       ==>   3
845                     Español     (Spanish)      ==>   4
846                     Português   (Portuguese)   ==>   5
847                     Nederlands  (Dutch)        ==>   6
848                     Italiano    (Italian)      ==>   7
849
850         See the section "How to install additional languages" in the file
851         "INSTALL.txt" in this distribution for how to add more languages to
852         this package.
853
854         In the original distribution (no other languages installed), the fol‐
855         lowing examples will all return the value "3":
856
857           $lang = Decode_Language("d");
858           $lang = Decode_Language("de");
859           $lang = Decode_Language("Deutsch");
860
861         Note that you may not be able to enter the special international
862         characters in some of the languages' names over the keyboard directly
863         on some systems.
864
865         This should never be a problem, though; just enter an abbreviation of
866         the name of the language consisting of the first few letters up to
867         the character before the first special international character.
868
869       · "if (($year,$month,$day) = Decode_Date_EU($string))"
870
871         This function scans a given string and tries to parse any date which
872         might be embedded in it. In the original module this was a C routine;
873         now it is simply a call to the perl subroutine Decode_Date_EU2 (see
874         below).
875
876         The function returns an empty list if it can't successfully extract a
877         valid date from its input string, or else it returns the date found.
878
879         The function accepts almost any format, as long as the date is given
880         in the european order (hence its name) day-month-year.
881
882         Thereby, zero or more NON-NUMERIC characters may PRECEDE the day and
883         FOLLOW the year.
884
885         Moreover, zero or more NON-ALPHANUMERIC characters are permitted
886         BETWEEN these three items (i.e., between day and month and between
887         month and year).
888
889         The month may be given either numerically (i.e., a number from "1" to
890         "12"), or alphanumerically, i.e., as the name of the month IN THE
891         CURRENTLY SELECTED LANGUAGE, or any uniquely identifying abbreviation
892         thereof.
893
894         (See further below for details about multi-language support by this
895         package!)
896
897         If the year is given as one or two digits only (i.e., if the year is
898         less than 100), it is mapped to the window ""1970 - 2069"" as fol‐
899         lows:
900
901            0 E<lt>= $year E<lt>  70  ==>  $year += 2000;
902           70 E<lt>= $year E<lt> 100  ==>  $year += 1900;
903
904         If the day, month and year are all given numerically but WITHOUT any
905         delimiting characters between them, this string of digits will be
906         mapped to the day, month and year as follows:
907
908                         Length:        Mapping:
909                           3              dmy
910                           4              dmyy
911                           5              dmmyy
912                           6              ddmmyy
913                           7              dmmyyyy
914                           8              ddmmyyyy
915
916         (Where "d" stands for "day", "m" stands for "month" and "y" stands
917         for "year".)
918
919         All other strings consisting purely of digits (without any interven‐
920         ing delimiters) are rejected, i.e., not recognized.
921
922         Examples:
923
924           "3.1.64"
925           "3 1 64"
926           "03.01.64"
927           "03/01/64"
928           "3. Jan 1964"
929           "Birthday: 3. Jan '64 in Backnang/Germany"
930           "03-Jan-64"
931           "3.Jan1964"
932           "3Jan64"
933           "030164"
934           "3ja64"
935           "3164"
936
937         Experiment! (See the corresponding example applications in the "exam‐
938         ples" subdirectory of this distribution in order to do so.)
939
940       · "if (($year,$month,$day) = Decode_Date_US($string))"
941
942         This function scans a given string and tries to parse any date which
943         might be embedded in it. In the original module, this was a C rou‐
944         tine. Now it is simply a call to the perl subroutine Decode_Date_US2
945         (see below).
946
947         The function returns an empty list if it can't successfully extract a
948         valid date from its input string, or else it returns the date found.
949
950         The function accepts almost any format, as long as the date is given
951         in the U.S. american order (hence its name) month-day-year.
952
953         Thereby, zero or more NON-ALPHANUMERIC characters may PRECEDE and
954         FOLLOW the month (i.e., precede the month and separate it from the
955         day which follows behind).
956
957         Moreover, zero or more NON-NUMERIC characters are permitted BETWEEN
958         the day and the year, as well as AFTER the year.
959
960         The month may be given either numerically (i.e., a number from "1" to
961         "12"), or alphanumerically, i.e., as the name of the month IN THE
962         CURRENTLY SELECTED LANGUAGE, or any uniquely identifying abbreviation
963         thereof.
964
965         (See further below for details about multi-language support by this
966         package!)
967
968         If the year is given as one or two digits only (i.e., if the year is
969         less than 100), it is mapped to the window ""1970 - 2069"" as fol‐
970         lows:
971
972            0 E<lt>= $year E<lt>  70  ==>  $year += 2000;
973           70 E<lt>= $year E<lt> 100  ==>  $year += 1900;
974
975         If the month, day and year are all given numerically but WITHOUT any
976         delimiting characters between them, this string of digits will be
977         mapped to the month, day and year as follows:
978
979                         Length:        Mapping:
980                           3              mdy
981                           4              mdyy
982                           5              mddyy
983                           6              mmddyy
984                           7              mddyyyy
985                           8              mmddyyyy
986
987         (Where "m" stands for "month", "d" stands for "day" and "y" stands
988         for "year".)
989
990         All other strings consisting purely of digits (without any interven‐
991         ing delimiters) are rejected, i.e., not recognized.
992
993         If only the day and the year form a contiguous string of digits, they
994         will be mapped as follows:
995
996                         Length:        Mapping:
997                           2              dy
998                           3              dyy
999                           4              ddyy
1000                           5              dyyyy
1001                           6              ddyyyy
1002
1003         (Where "d" stands for "day" and "y" stands for "year".)
1004
1005         Examples:
1006
1007           "1 3 64"
1008           "01/03/64"
1009           "Jan 3 '64"
1010           "Jan 3 1964"
1011           "===> January 3rd 1964 (birthday)"
1012           "Jan31964"
1013           "Jan364"
1014           "ja364"
1015           "1364"
1016
1017         Experiment! (See the corresponding example applications in the "exam‐
1018         ples" subdirectory of this distribution in order to do so.)
1019
1020       · "$date = Compress($year,$month,$day);"
1021
1022         This function encodes a date in 16 bits, which is the value being
1023         returned.
1024
1025         The encoding scheme is as follows:
1026
1027                     Bit number:    FEDCBA9 8765 43210
1028                     Contents:      yyyyyyy mmmm ddddd
1029
1030         (Where the "yyyyyyy" contain the number of the year, "mmmm" the num‐
1031         ber of the month and "ddddd" the number of the day.)
1032
1033         The function returns "0" if the given input values do not represent a
1034         valid date. Therefore, the return value of this function can also be
1035         used as the conditional expression in an "if" statement, in order to
1036         check wether the given input values constitute a valid date).
1037
1038         Through this special encoding scheme, it is possible to COMPARE com‐
1039         pressed dates for equality and order (less than/greater than) WITHOUT
1040         any previous DECODING!
1041
1042         Note however that contiguous dates do NOT necessarily have contiguous
1043         compressed representations!
1044
1045         I.e., incrementing the compressed representation of a date MAY OR MAY
1046         NOT yield a valid new date!
1047
1048         Note also that this function can only handle dates within one cen‐
1049         tury.
1050
1051         This century can be chosen at random by defining a base century and
1052         year (also called the "epoch"). In the original distribution of this
1053         package, the base century is set to "1900" and the base year to "70"
1054         (which is standard on UNIX systems).
1055
1056         This allows this function to handle dates from "1970" up to "2069".
1057
1058         If the given year is equal to, say, "95", this package will automati‐
1059         cally assume that you really mean "1995" instead. However, if you
1060         specify a year number which is SMALLER than 70, like "64", for
1061         instance, this package will assume that you really mean "2064".
1062
1063         You are not confined to two-digit (abbreviated) year numbers, though.
1064
1065         The function also accepts "full-length" year numbers, provided that
1066         they lie in the supported range (i.e., from "1970" to "2069", in the
1067         original configuration of this package).
1068
1069         Note that this function is maintained mainly for backward compatibil‐
1070         ity, and that its use is not recommended.
1071
1072       · "if (($century,$year,$month,$day) = Uncompress($date))"
1073
1074         This function decodes dates that were encoded previously using the
1075         function ""Compress()"".
1076
1077         It returns the century, year, month and day of the date encoded in
1078         "$date" if "$date" represents a valid date, or an empty list other‐
1079         wise.
1080
1081         The year returned in "$year" is actually a two-digit year number
1082         (i.e., the year number taken modulo 100), and only the expression
1083         ""$century + $year"" yields the "full-length" year number (for exam‐
1084         ple, "1900 + 95 = 1995").
1085
1086         Note that this function is maintained mainly for backward compatibil‐
1087         ity, and that its use is not recommended.
1088
1089       · "if (check_compressed($date))"
1090
1091         This function returns "true" ("1") if the given input value consti‐
1092         tutes a valid compressed date, and "false" ("0") otherwise.
1093
1094         Note that this function is maintained mainly for backward compatibil‐
1095         ity, and that its use is not recommended.
1096
1097       · "$string = Compressed_to_Text($date);"
1098
1099         This function returns a string of fixed length (always 9 characters
1100         long) containing a textual representation of the compressed date
1101         encoded in "$date".
1102
1103         This string has the form "dd-Mmm-yy", where "dd" is the two-digit
1104         number of the day, "Mmm" are the first three letters of the name of
1105         the month in the currently selected language (see further below for
1106         details about multi-language support by this package), and "yy" is
1107         the two-digit year number (i.e., the year number taken modulo 100).
1108
1109         If "$date" does not represent a valid date, the string "??-???-??" is
1110         returned instead.
1111
1112         Note that this function is maintained mainly for backward compatibil‐
1113         ity, and that its use is not recommended.
1114
1115       · "$string = Date_to_Text($year,$month,$day);"
1116
1117         This function returns a string containing a textual representation of
1118         the given date of the form "www dd-Mmm-yyyy", where "www" are the
1119         first three letters of the name of the day of week in the currently
1120         selected language, or a special abbreviation, if special abbrevia‐
1121         tions have been defined for the currently selected language (see fur‐
1122         ther below for details about multi-language support by this package),
1123         "dd" is the day (one or two digits), "Mmm" are the first three let‐
1124         ters of the name of the month in the currently selected language, and
1125         "yyyy" is the number of the year in full length.
1126
1127         If the given input values do not constitute a valid date, a fatal
1128         "not a valid date" error occurs.
1129
1130         (See the section "RECIPES" near the end of this document for a code
1131         snippet for how to print dates in any format you like.)
1132
1133       · "$string = Date_to_Text_Long($year,$month,$day);"
1134
1135         This function returns a string containing a textual representation of
1136         the given date roughly of the form "Wwwwww, dd Mmmmmm yyyy", where
1137         "Wwwwww" is the name of the day of week in the currently selected
1138         language (see further below for details about the multi-language sup‐
1139         port of this package), "dd" is the day (one or two digits), "Mmmmmm"
1140         is the name of the month in the currently selected language, and
1141         "yyyy" is the number of the year in full length.
1142
1143         The exact format of the output string depends on the currently
1144         selected language. In the original distribution of this package,
1145         these formats are defined as follows:
1146
1147           1  English    :  "Wwwwww, Mmmmmm ddth yyyy"
1148           2  French     :  "Wwwwww, le dd Mmmmmm yyyy"
1149           3  German     :  "Wwwwww, den dd. Mmmmmm yyyy"
1150           4  Spanish    :  "Wwwwww, dd de Mmmmmm de yyyy"
1151           5  Portuguese :  "Wwwwww, dia dd de Mmmmmm de yyyy"
1152           6  Dutch      :  "Wwwwww, dd. Mmmmmm yyyy"
1153           7  Italian    :  "Wwwwww, dd Mmmmmm yyyy"
1154
1155         (You can change these formats in the file "DateCalc.c" before build‐
1156         ing this module in order to suit your personal preferences.)
1157
1158         If the given input values do not constitute a valid date, a fatal
1159         "not a valid date" error occurs.
1160
1161         (See the section "RECIPES" near the end of this document for a code
1162         snippet for how to print dates in any format you like.)
1163
1164       · "$string = English_Ordinal($number);"
1165
1166         This function returns a string containing the (english) abbreviation
1167         of the ordinal number for the given (cardinal) number "$number".
1168
1169         I.e.,
1170
1171             0  =>  '0th'    10  =>  '10th'    20  =>  '20th'
1172             1  =>  '1st'    11  =>  '11th'    21  =>  '21st'
1173             2  =>  '2nd'    12  =>  '12th'    22  =>  '22nd'
1174             3  =>  '3rd'    13  =>  '13th'    23  =>  '23rd'
1175             4  =>  '4th'    14  =>  '14th'    24  =>  '24th'
1176             5  =>  '5th'    15  =>  '15th'    25  =>  '25th'
1177             6  =>  '6th'    16  =>  '16th'    26  =>  '26th'
1178             7  =>  '7th'    17  =>  '17th'    27  =>  '27th'
1179             8  =>  '8th'    18  =>  '18th'    28  =>  '28th'
1180             9  =>  '9th'    19  =>  '19th'    29  =>  '29th'
1181
1182         etc.
1183
1184       · "$string = Calendar($year,$month);"
1185
1186         This function returns a calendar of the given month in the given year
1187         (somewhat similar to the UNIX "cal" command), IN THE CURRENTLY
1188         SELECTED LANGUAGE (see further below for details about multi-language
1189         support by this package).
1190
1191         Example:
1192
1193           print Calendar(1998,5);
1194
1195         This will print:
1196
1197                    May 1998
1198           Mon Tue Wed Thu Fri Sat Sun
1199                             1   2   3
1200             4   5   6   7   8   9  10
1201            11  12  13  14  15  16  17
1202            18  19  20  21  22  23  24
1203            25  26  27  28  29  30  31
1204
1205       · "$string = Month_to_Text($month);"
1206
1207         This function returns the name of the given month in the currently
1208         selected language (see further below for details about multi-language
1209         support by this package).
1210
1211         If the given month lies outside of the valid range from "1" to "12",
1212         a fatal "month out of range" error will occur.
1213
1214       · "$string = Day_of_Week_to_Text($dow);"
1215
1216         This function returns the name of the given day of week in the cur‐
1217         rently selected language (see further below for details about multi-
1218         language support by this package).
1219
1220         If the given day of week lies outside of the valid range from "1" to
1221         "7", a fatal "day of week out of range" error will occur.
1222
1223       · "$string = Day_of_Week_Abbreviation($dow);"
1224
1225         This function returns the special abbreviation of the name of the
1226         given day of week, IF such special abbreviations have been defined
1227         for the currently selected language (see further below for details
1228         about multi-language support by this package).
1229
1230         (In the original distribution of this package, this is only true for
1231         Portuguese.)
1232
1233         If not, the first three letters of the name of the day of week in the
1234         currently selected language are returned instead.
1235
1236         If the given day of week lies outside of the valid range from "1" to
1237         "7", a fatal "day of week out of range" error will occur.
1238
1239         Currently, this table of special abbreviations is only used by the
1240         functions ""Date_to_Text()"" and ""Calendar()"", internally.
1241
1242       · "$string = Language_to_Text($lang);"
1243
1244         This function returns the name of any language supported by this
1245         package when the internal number representing that language is given
1246         as input.
1247
1248         The original distribution supports the following seven languages:
1249
1250                     1   ==>   English     (default)
1251                     2   ==>   Français    (French)
1252                     3   ==>   Deutsch     (German)
1253                     4   ==>   Español     (Spanish)
1254                     5   ==>   Português   (Portuguese)
1255                     6   ==>   Nederlands  (Dutch)
1256                     7   ==>   Italiano    (Italian)
1257
1258         See the section "How to install additional languages" in the file
1259         "INSTALL.txt" in this distribution for how to add more languages to
1260         this package.
1261
1262         See the description of the function ""Languages()"" further below to
1263         determine how many languages are actually available in a given
1264         installation of this package.
1265
1266       · "$lang = Language();"
1267
1268       · "Language($lang);"
1269
1270       · "$oldlang = Language($newlang);"
1271
1272         This function can be used to determine which language is currently
1273         selected, and to change the selected language.
1274
1275         Thereby, each language has a unique internal number.
1276
1277         The original distribution contains the following seven languages:
1278
1279                     1   ==>   English     (default)
1280                     2   ==>   Français    (French)
1281                     3   ==>   Deutsch     (German)
1282                     4   ==>   Español     (Spanish)
1283                     5   ==>   Português   (Portuguese)
1284                     6   ==>   Nederlands  (Dutch)
1285                     7   ==>   Italiano    (Italian)
1286
1287         See the section "How to install additional languages" in the file
1288         "INSTALL.txt" in this distribution for how to add more languages to
1289         this package.
1290
1291         See the description of the function ""Languages()"" further below to
1292         determine how many languages are actually available in a given
1293         installation of this package.
1294
1295         BEWARE that in order for your programs to be portable, you should
1296         NEVER actually use the internal number of a language in this package
1297         EXPLICITLY, because the same number could mean different languages on
1298         different systems, depending on what languages have been added to any
1299         given installation of this package.
1300
1301         Therefore, you should always use a statement such as
1302
1303           Language(Decode_Language("Name_of_Language"));
1304
1305         to select the desired language, and
1306
1307           $language = Language_to_Text(Language());
1308
1309         or
1310
1311           $old_language = Language_to_Text(Language("Name_of_new_Language"));
1312
1313         to determine the (previously) selected language.
1314
1315         If the so chosen language is not available in the current installa‐
1316         tion, this will result in an appropriate error message, instead of
1317         silently using the wrong (a random) language (which just happens to
1318         have the same internal number in the other installation).
1319
1320         Note that in the current implementation of this package, the selected
1321         language is a global setting valid for ALL functions that use the
1322         names of months, days of week or languages internally, valid for ALL
1323         PROCESSES using the same copy of the "Date::Pcalc" shared library in
1324         memory!
1325
1326         This may have surprising side-effects in a multi-user environment,
1327         and even more so when Perl will be capable of multi-threading in some
1328         future release.
1329
1330       · "$max_lang = Languages();"
1331
1332         This function returns the (maximum) number of languages which are
1333         currently available in your installation of this package.
1334
1335         (This may vary from installation to installation.)
1336
1337         See the section "How to install additional languages" in the file
1338         "INSTALL.txt" in this distribution for how to add more languages to
1339         this package.
1340
1341         In the original distribution of this package there are seven built-in
1342         languages, therefore the value returned by this function will be "7"
1343         if no other languages have been added to your particular installa‐
1344         tion.
1345
1346       · "if (($year,$month,$day) = Decode_Date_EU2($string))"
1347
1348         This function is the Perl equivalent of the function
1349         ""Decode_Date_EU()"" (implemented in C), included here merely as an
1350         example to demonstrate how easy it is to write your own routine in
1351         Perl (using regular expressions) adapted to your own special needs,
1352         should the necessity arise, and intended primarily as a basis for
1353         your own development.
1354
1355         In one particular case this Perl version is actually slightly more
1356         permissive than its C equivalent, as far as the class of permitted
1357         intervening (i.e., delimiting) characters is concerned.
1358
1359         (Can you tell the subtle, almost insignificant difference by looking
1360         at the code? Or by experimenting? Hint: Try the string "a3b1c64d"
1361         with both functions.)
1362
1363       · "if (($year,$month,$day) = Decode_Date_US2($string))"
1364
1365         This function is the Perl equivalent of the function
1366         ""Decode_Date_US()"" (implemented in C), included here merely as an
1367         example to demonstrate how easy it is to write your own routine in
1368         Perl (using regular expressions) adapted to your own special needs,
1369         should the necessity arise, and intended primarily as a basis for
1370         your own development.
1371
1372         In one particular case this Perl version is actually slightly more
1373         permissive than its C equivalent.
1374
1375         (Hint: This is the same difference as with the ""Decode_Date_EU()""
1376         and ""Decode_Date_EU2()"" pair of functions.)
1377
1378         In a different case, the C version is a little bit more permissive
1379         than its Perl equivalent.
1380
1381         (Can you tell the difference by looking at the code? Or by experi‐
1382         menting?  Hint: Try the string "(1/364)" with both functions.)
1383
1384       · "if (($year,$month,$day) = Parse_Date($string))"
1385
1386         This function is useful for parsing dates as returned by the UNIX
1387         ""date"" command or as found in the headers of e-mail (in order to
1388         determine the date at which some e-mail has been sent or received,
1389         for instance).
1390
1391         Example #1:
1392
1393           ($year,$month,$day) = Parse_Date(`/bin/date`);
1394
1395         Example #2:
1396
1397           while (<MAIL>)
1398           {
1399               if (/^From \S/)
1400               {
1401                   ($year,$month,$day) = Parse_Date($_);
1402                   ...
1403               }
1404               ...
1405           }
1406
1407         The function returns an empty list if it can't extract a valid date
1408         from the input string.
1409
1410       · "$string = Date::Pcalc::Version();"
1411
1412         This function returns a string with the (numeric) version number of
1413         the C library ("DateCalc.c") at the core of this package (which is
1414         also (automatically) the version number of the "Calc.xs" file).
1415
1416         Note that under all normal circumstances, this version number should
1417         be identical with the one found in the Perl variable
1418         "$Date::Pcalc::VERSION" (the version number of the "Calc.pm" file).
1419
1420         Since this function is not exported, you always have to qualify it
1421         explicitly, i.e., ""Date::Pcalc::Version()"".
1422
1423         This is to avoid possible name space conflicts with version functions
1424         from other modules.
1425

RECIPES

1427       1)  How do I compare two dates?
1428
1429           Solution #1:
1430
1431             use Date::Pcalc qw( Date_to_Days );
1432
1433             if (Date_to_Days($year1,$month1,$day1)  <
1434                 Date_to_Days($year2,$month2,$day2))
1435
1436             if (Date_to_Days($year1,$month1,$day1)  <=
1437                 Date_to_Days($year2,$month2,$day2))
1438
1439             if (Date_to_Days($year1,$month1,$day1)  >
1440                 Date_to_Days($year2,$month2,$day2))
1441
1442             if (Date_to_Days($year1,$month1,$day1)  >=
1443                 Date_to_Days($year2,$month2,$day2))
1444
1445             if (Date_to_Days($year1,$month1,$day1)  ==
1446                 Date_to_Days($year2,$month2,$day2))
1447
1448             if (Date_to_Days($year1,$month1,$day1)  !=
1449                 Date_to_Days($year2,$month2,$day2))
1450
1451             $cmp = (Date_to_Days($year1,$month1,$day1)  <=>
1452                     Date_to_Days($year2,$month2,$day2));
1453
1454           Solution #2:
1455
1456             use Date::Pcalc qw( Delta_Days );
1457
1458             if (Delta_Days($year1,$month1,$day1,
1459                            $year2,$month2,$day2) > 0)
1460
1461             if (Delta_Days($year1,$month1,$day1,
1462                            $year2,$month2,$day2) >= 0)
1463
1464             if (Delta_Days($year1,$month1,$day1,
1465                            $year2,$month2,$day2) < 0)
1466
1467             if (Delta_Days($year1,$month1,$day1,
1468                            $year2,$month2,$day2) <= 0)
1469
1470             if (Delta_Days($year1,$month1,$day1,
1471                            $year2,$month2,$day2) == 0)
1472
1473             if (Delta_Days($year1,$month1,$day1,
1474                            $year2,$month2,$day2) != 0)
1475
1476       2)  How do I check wether a given date lies within a certain range of
1477           dates?
1478
1479             use Date::Pcalc qw( Date_to_Days );
1480
1481             $lower = Date_to_Days($year1,$month1,$day1);
1482             $upper = Date_to_Days($year2,$month2,$day2);
1483
1484             $date = Date_to_Days($year,$month,$day);
1485
1486             if (($date >= $lower) && ($date <= $upper))
1487             {
1488                 # ok
1489             }
1490             else
1491             {
1492                 # not ok
1493             }
1494
1495       3)  How do I verify wether someone has a certain age?
1496
1497             use Date::Pcalc qw( Decode_Date_EU Today leap_year Delta_Days );
1498
1499             $date = <STDIN>; # get birthday
1500
1501             ($year1,$month1,$day1) = Decode_Date_EU($date);
1502
1503             ($year2,$month2,$day2) = Today();
1504
1505             if (($day1 == 29) && ($month1 == 2) && !leap_year($year2))
1506                 { $day1--; }
1507
1508             if ( (($year2 - $year1) >  18) ⎪⎪
1509                ( (($year2 - $year1) == 18) &&
1510                (Delta_Days($year2,$month1,$day1, $year2,$month2,$day2) >= 0) ) )
1511             {
1512                 print "Ok - you are over 18.\n";
1513             }
1514             else
1515             {
1516                 print "Sorry - you aren't 18 yet!\n";
1517             }
1518
1519       4)  How do I calculate the number of the week of month the current date
1520           lies in?
1521
1522           For example:
1523
1524                       April 1998
1525               Mon Tue Wed Thu Fri Sat Sun
1526                         1   2   3   4   5  =  week #1
1527                 6   7   8   9  10  11  12  =  week #2
1528                13  14  15  16  17  18  19  =  week #3
1529                20  21  22  23  24  25  26  =  week #4
1530                27  28  29  30              =  week #5
1531
1532           Solution:
1533
1534             use Date::Pcalc qw( Today Day_of_Week );
1535
1536             ($year,$month,$day) = Today();
1537
1538             $week = int(($day + Day_of_Week($year,$month,1) - 2) / 7) + 1;
1539
1540       5)  How do I calculate wether a given date is the 1st, 2nd, 3rd, 4th or
1541           5th of that day of week in the given month?
1542
1543           For example:
1544
1545                      October 2000
1546               Mon Tue Wed Thu Fri Sat Sun
1547                                         1
1548                 2   3   4   5   6   7   8
1549                 9  10  11  12  13  14  15
1550                16  17  18  19  20  21  22
1551                23  24  25  26  27  28  29
1552                30  31
1553
1554           Is Sunday, the 15th of October 2000, the 1st, 2nd, 3rd, 4th or 5th
1555           Sunday of that month?
1556
1557           Solution:
1558
1559             use Date::Pcalc qw( Day_of_Week Delta_Days
1560                                Nth_Weekday_of_Month_Year
1561                                Date_to_Text_Long English_Ordinal
1562                                Day_of_Week_to_Text Month_to_Text );
1563
1564             ($year,$month,$day) = (2000,10,15);
1565
1566             $dow = Day_of_Week($year,$month,$day);
1567
1568             $n = int( Delta_Days(
1569                       Nth_Weekday_of_Month_Year($year,$month,$dow,1),
1570                       $year,$month,$day)
1571                       / 7) + 1;
1572
1573             printf("%s is the %s %s in %s %d.\n",
1574                 Date_to_Text_Long($year,$month,$day),
1575                 English_Ordinal($n),
1576                 Day_of_Week_to_Text($dow),
1577                 Month_to_Text($month),
1578                 $year);
1579
1580           This prints:
1581
1582             Sunday, October 15th 2000 is the 3rd Sunday in October 2000.
1583
1584       6)  How do I calculate the date of the Wednesday of the same week as
1585           the current date?
1586
1587           Solution #1:
1588
1589             use Date::Pcalc qw( Today Day_of_Week Add_Delta_Days );
1590
1591             $searching_dow = 3; # 3 = Wednesday
1592
1593             @today = Today();
1594
1595             $current_dow = Day_of_Week(@today);
1596
1597             @date = Add_Delta_Days(@today, $searching_dow - $current_dow);
1598
1599           Solution #2:
1600
1601             use Date::Pcalc qw( Today Add_Delta_Days
1602                                Monday_of_Week Week_of_Year );
1603
1604             $searching_dow = 3; # 3 = Wednesday
1605
1606             @today = Today();
1607
1608             @date = Add_Delta_Days( Monday_of_Week( Week_of_Year(@today) ),
1609                                     $searching_dow - 1 );
1610
1611           Solution #3:
1612
1613             use Date::Pcalc qw( Standard_to_Business Today
1614                                Business_to_Standard );
1615
1616             @business = Standard_to_Business(Today());
1617
1618             $business[2] = 3; # 3 = Wednesday
1619
1620             @date = Business_to_Standard(@business);
1621
1622       7)  How can I add a week offset to a business date (including across
1623           year boundaries)?
1624
1625             use Date::Pcalc qw( Business_to_Standard Add_Delta_Days
1626                                Standard_to_Business );
1627
1628             @temp = Business_to_Standard($year,$week,$dow);
1629
1630             @temp = Add_Delta_Days(@temp, $week_offset * 7);
1631
1632             ($year,$week,$dow) = Standard_to_Business(@temp);
1633
1634       8)  How do I calculate the last and the next Saturday for any given
1635           date?
1636
1637             use Date::Pcalc qw( Today Day_of_Week Add_Delta_Days
1638                                Day_of_Week_to_Text Date_to_Text );
1639
1640             $searching_dow = 6; # 6 = Saturday
1641
1642             @today = Today();
1643
1644             $current_dow = Day_of_Week(@today);
1645
1646             if ($searching_dow == $current_dow)
1647             {
1648                 @prev = Add_Delta_Days(@today,-7);
1649                 @next = Add_Delta_Days(@today,+7);
1650             }
1651             else
1652             {
1653                 if ($searching_dow > $current_dow)
1654                 {
1655                     @next = Add_Delta_Days(@today,
1656                               $searching_dow - $current_dow);
1657                     @prev = Add_Delta_Days(@next,-7);
1658                 }
1659                 else
1660                 {
1661                     @prev = Add_Delta_Days(@today,
1662                               $searching_dow - $current_dow);
1663                     @next = Add_Delta_Days(@prev,+7);
1664                 }
1665             }
1666
1667             $dow = Day_of_Week_to_Text($searching_dow);
1668
1669             print "Today is:      ", ' ' x length($dow),
1670                                          Date_to_Text(@today), "\n";
1671             print "Last $dow was:     ", Date_to_Text(@prev),  "\n";
1672             print "Next $dow will be: ", Date_to_Text(@next),  "\n";
1673
1674           This will print something like:
1675
1676             Today is:              Sun 12-Apr-1998
1677             Last Saturday was:     Sat 11-Apr-1998
1678             Next Saturday will be: Sat 18-Apr-1998
1679
1680       9)  How can I calculate the last business day (payday!) of a month?
1681
1682           Solution #1 (holidays NOT taken into account):
1683
1684             use Date::Pcalc qw( Days_in_Month Day_of_Week Add_Delta_Days );
1685
1686             $day = Days_in_Month($year,$month);
1687             $dow = Day_of_Week($year,$month,$day);
1688             if ($dow > 5)
1689             {
1690                 ($year,$month,$day) =
1691                     Add_Delta_Days($year,$month,$day, 5-$dow);
1692             }
1693
1694           Solution #2 (holidays taken into account):
1695
1696           This solution expects a multi-dimensional array "@holiday", which
1697           contains all holidays, as follows: ""$holiday[$year][$month][$day]
1698           = 1;"".
1699
1700           (See the description of the function ""Easter_Sunday()"" further
1701           above for how to calculate the moving (variable) christian feast
1702           days!)
1703
1704           Days which are not holidays remain undefined or should have a value
1705           of zero in this array.
1706
1707             use Date::Pcalc qw( Days_in_Month Add_Delta_Days Day_of_Week );
1708
1709             $day = Days_in_Month($year,$month);
1710             while (1)
1711             {
1712                 while ($holiday[$year][$month][$day])
1713                 {
1714                     ($year,$month,$day) =
1715                         Add_Delta_Days($year,$month,$day, -1);
1716                 }
1717                 $dow = Day_of_Week($year,$month,$day);
1718                 if ($dow > 5)
1719                 {
1720                     ($year,$month,$day) =
1721                         Add_Delta_Days($year,$month,$day, 5-$dow);
1722                 }
1723                 else { last; }
1724             }
1725
1726       10) How do I convert a MS Visual Basic "DATETIME" value into its date
1727           and time constituents?
1728
1729             use Date::Pcalc qw( Add_Delta_DHMS Date_to_Text );
1730
1731             $datetime = "35883.121653";
1732
1733             ($Dd,$Dh,$Dm,$Ds) = ($datetime =~ /^(\d+)\.(\d\d)(\d\d)(\d\d)$/);
1734
1735             ($year,$month,$day, $hour,$min,$sec) =
1736                 Add_Delta_DHMS(1900,1,1, 0,0,0, $Dd,$Dh,$Dm,$Ds);
1737
1738             printf("The given date is %s %02d:%02d:%02d\n",
1739                 Date_to_Text($year,$month,$day), $hour, $min, $sec);
1740
1741           This prints:
1742
1743             The given date is Tue 31-Mar-1998 12:16:53
1744
1745       11) How can I send a reminder to members of a group on the day before a
1746           meeting which occurs every first Friday of a month?
1747
1748             use Date::Pcalc qw( Today Date_to_Days Add_Delta_YMD
1749                                Nth_Weekday_of_Month_Year );
1750
1751             ($year,$month,$day) = Today();
1752
1753             $tomorrow = Date_to_Days($year,$month,$day) + 1;
1754
1755             $dow = 5; # 5 = Friday
1756             $n   = 1; # 1 = First of that day of week
1757
1758             $meeting_this_month = Date_to_Days(
1759                 Nth_Weekday_of_Month_Year($year,$month,$dow,$n) );
1760
1761             ($year,$month,$day) = Add_Delta_YMD($year,$month,$day, 0,1,0);
1762
1763             $meeting_next_month = Date_to_Days(
1764                 Nth_Weekday_of_Month_Year($year,$month,$dow,$n) );
1765
1766             if (($tomorrow == $meeting_this_month) ⎪⎪
1767                 ($tomorrow == $meeting_next_month))
1768             {
1769                 # Send reminder e-mail!
1770             }
1771
1772       12) How can I print a date in a different format than provided by the
1773           functions ""Date_to_Text()"", ""Date_to_Text_Long()"" or ""Com‐
1774           pressed_to_Text()""?
1775
1776             use Date::Pcalc qw( Today Day_of_Week_to_Text
1777                                Day_of_Week Month_to_Text
1778                                English_Ordinal );
1779
1780             ($year,$month,$day) = Today();
1781
1782           For example with leading zeros for the day: "Fri 03-Jan-1964"
1783
1784             printf("%.3s %02d-%.3s-%d\n",
1785                 Day_of_Week_to_Text(Day_of_Week($year,$month,$day)),
1786                 $day,
1787                 Month_to_Text($month),
1788                 $year);
1789
1790           For example in U.S. american format: "April 12th, 1998"
1791
1792             $string = sprintf("%s %s, %d",
1793                           Month_to_Text($month),
1794                           English_Ordinal($day),
1795                           $year);
1796
1797           (See also "printf" in perlfunc(1) and/or "sprintf" in perlfunc(1)!)
1798
1799       13) How can I iterate through a range of dates?
1800
1801             use Date::Pcalc qw( Delta_Days Add_Delta_Days );
1802
1803             @start = (1999,5,27);
1804             @stop  = (1999,6,1);
1805
1806             $j = Delta_Days(@start,@stop);
1807
1808             for ( $i = 0; $i <= $j; $i++ )
1809             {
1810                 @date = Add_Delta_Days(@start,$i);
1811                 printf("%4d/%02d/%02d\n", @date);
1812             }
1813
1814           Note that the loop can be improved; see also the recipe below.
1815
1816       14) How can I create a (Perl) list of dates in a certain range?
1817
1818             use Date::Pcalc qw( Delta_Days Add_Delta_Days Date_to_Text );
1819
1820             sub date_range
1821             {
1822                 my(@date) = (@_)[0,1,2];
1823                 my(@list);
1824                 my($i);
1825
1826                 $i = Delta_Days(@_);
1827                 while ($i-- >= 0)
1828                 {
1829                     push( @list, [ @date ] );
1830                     @date = Add_Delta_Days(@date, 1) if ($i >= 0);
1831                 }
1832                 return(@list);
1833             }
1834
1835             @range = &date_range(1999,11,3, 1999,12,24); # in chronological order
1836
1837             foreach $date (@range)
1838             {
1839                 print Date_to_Text(@{$date}), "\n";
1840             }
1841
1842           Note that you probably shouldn't use this one, because it is much
1843           more efficient to iterate through all the dates (as shown in the
1844           recipe immediately above) than to construct such an array and then
1845           to loop through it. Also, it is much more space-efficient not to
1846           create this array.
1847
1848       15) How can I calculate the difference in days between dates, but with‐
1849           out counting Saturdays and Sundays?
1850
1851             sub Delta_Business_Days
1852             {
1853                 my(@date1) = (@_)[0,1,2];
1854                 my(@date2) = (@_)[3,4,5];
1855                 my($minus,$result,$dow1,$dow2,$diff,$temp);
1856
1857                 $minus  = 0;
1858                 $result = Delta_Days(@date1,@date2);
1859                 if ($result != 0)
1860                 {
1861                     if ($result < 0)
1862                     {
1863                         $minus = 1;
1864                         $result = -$result;
1865                         $dow1 = Day_of_Week(@date2);
1866                         $dow2 = Day_of_Week(@date1);
1867                     }
1868                     else
1869                     {
1870                         $dow1 = Day_of_Week(@date1);
1871                         $dow2 = Day_of_Week(@date2);
1872                     }
1873                     $diff = $dow2 - $dow1;
1874                     $temp = $result;
1875                     if ($diff != 0)
1876                     {
1877                         if ($diff < 0)
1878                         {
1879                             $diff += 7;
1880                         }
1881                         $temp -= $diff;
1882                         $dow1 += $diff;
1883                         if ($dow1 > 6)
1884                         {
1885                             $result--;
1886                             if ($dow1 > 7)
1887                             {
1888                                 $result--;
1889                             }
1890                         }
1891                     }
1892                     if ($temp != 0)
1893                     {
1894                         $temp /= 7;
1895                         $result -= ($temp << 1);
1896                     }
1897                 }
1898                 if ($minus) { return -$result; }
1899                 else        { return  $result; }
1900             }
1901
1902           This solution is probably of little practical value, however,
1903           because it doesn't take legal holidays into account.
1904

SEE ALSO

1906         "The Calendar FAQ":
1907         http://www.tondering.dk/claus/calendar.html
1908         by Claus Tondering <claus@tondering.dk>
1909

LIMITATIONS

1911       In the current implementation of this package, the selected language is
1912       stored in a global variable named $pcalc_Language.
1913
1914       Therefore, on systems where the "Date::Pcalc" module is a shared
1915       library, or as soon as Perl will be capable of multi-threading, this
1916       may cause undesired effects (of one process or thread always selecting
1917       the language for ALL OTHER processes or threads as well).
1918

VERSION

1920       This man page documents "Date::Pcalc" version 1.2.
1921

AUTHOR

1923         J. David Eisenberg
1924         4604 Corrida Circle
1925         San Jose, California 95129
1926         USA
1927
1928         mailto: nessus@best.com
1929         http://www.best.com/~nessus/date/pcalc.html
1930
1931       Please contact me by e-mail whenever possible!
1932
1933       All the mistakes in this implementation are caused by my translation of
1934       the original C code to perl.
1935
1936       Anything that works does so because it was written correctly by the
1937       original author:
1938
1939         Steffen Beyer
1940         mailto:sb@engelschall.com
1941         http://www.engelschall.com/u/sb/download/
1942
1944       Copyright (c) 1999-2001 by J. David Eisenberg; portions Copyright (c)
1945       1993-2001 by Steffen Beyer.  All rights reserved.
1946

LICENSE

1948       This package is free software; you can redistribute it and/or modify it
1949       under the same terms as Perl itself, i.e., under the terms of the
1950       "Artistic License" or the "GNU General Public License".
1951
1952       Please refer to the files "Artistic.txt" and "GNU_GPL.txt" in this dis‐
1953       tribution for details!
1954

DISCLAIMER

1956       This package is distributed in the hope that it will be useful, but
1957       WITHOUT ANY WARRANTY; without even the implied warranty of MER‐
1958       CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1959
1960       See the "GNU General Public License" for more details.
1961
1962
1963
1964perl v5.8.8                       2001-04-02                          Pcalc(3)
Impressum