1Pcalc(3) User Contributed Perl Documentation Pcalc(3)
2
3
4
6 Date::Pcalc - Gregorian calendar date calculations
7
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
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
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
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
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
1906 "The Calendar FAQ":
1907 http://www.tondering.dk/claus/calendar.html
1908 by Claus Tondering <claus@tondering.dk>
1909
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
1920 This man page documents "Date::Pcalc" version 1.2.
1921
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
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
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)