File Coverage

blib/lib/Date/Calc/PP.pm
Criterion Covered Total %
statement 1223 1504 81.3
branch 538 844 63.7
condition 360 600 60.0
subroutine 132 157 84.0
pod 1 152 0.6
total 2254 3257 69.2


line stmt bran cond sub pod time code
1              
2             ###############################################################################
3             ## ##
4             ## Copyright (c) 1995 - 2015 by Steffen Beyer. ##
5             ## All rights reserved. ##
6             ## ##
7             ## This package is free software; you can redistribute it ##
8             ## and/or modify it under the same terms as Perl itself. ##
9             ## ##
10             ###############################################################################
11              
12             package Date::Calc::PP;
13              
14 50     50   116 BEGIN { eval { require bytes; }; }
  50         1246  
15 50     50   219 use strict;
  50         71  
  50         1465  
16 50     50   184 use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
  50         68  
  50         3072  
17              
18 50     50   17598 use Carp::Clan qw(^Date::);
  50         132134  
  50         304  
19              
20 50     50   33354 use POSIX ();
  50         265874  
  50         795106  
21              
22             require Exporter;
23              
24             @ISA = qw(Exporter);
25              
26             @EXPORT = qw();
27              
28             @EXPORT_OK = qw(
29             Days_in_Year
30             Days_in_Month
31             Weeks_in_Year
32             leap_year
33             check_date
34             check_time
35             check_business_date
36             Day_of_Year
37             Date_to_Days
38             Day_of_Week
39             Week_Number
40             Week_of_Year
41             Monday_of_Week
42             Nth_Weekday_of_Month_Year
43             Standard_to_Business
44             Business_to_Standard
45             Delta_Days
46             Delta_DHMS
47             Delta_YMD
48             Delta_YMDHMS
49             N_Delta_YMD
50             N_Delta_YMDHMS
51             Normalize_DHMS
52             Add_Delta_Days
53             Add_Delta_DHMS
54             Add_Delta_YM
55             Add_Delta_YMD
56             Add_Delta_YMDHMS
57             Add_N_Delta_YMD
58             Add_N_Delta_YMDHMS
59             System_Clock
60             Today
61             Now
62             Today_and_Now
63             This_Year
64             Gmtime
65             Localtime
66             Mktime
67             Timezone
68             Date_to_Time
69             Time_to_Date
70             Easter_Sunday
71             Decode_Month
72             Decode_Day_of_Week
73             Decode_Language
74             Decode_Date_EU
75             Decode_Date_US
76             Fixed_Window
77             Moving_Window
78             Compress
79             Uncompress
80             check_compressed
81             Compressed_to_Text
82             Date_to_Text
83             Date_to_Text_Long
84             English_Ordinal
85             Calendar
86             Month_to_Text
87             Day_of_Week_to_Text
88             Day_of_Week_Abbreviation
89             Language_to_Text
90             Language
91             Languages
92             Decode_Date_EU2
93             Decode_Date_US2
94             Parse_Date
95             ISO_LC
96             ISO_UC
97             );
98              
99             %EXPORT_TAGS = (all => [@EXPORT_OK]);
100              
101             ##################################################
102             ## ##
103             ## "Version()" is available but not exported ##
104             ## in order to avoid possible name clashes. ##
105             ## Call "Date::Calc::PP::Version()" instead! ##
106             ## ##
107             ##################################################
108              
109             $VERSION = '6.4';
110              
111             sub Version
112             {
113 1     1 1 17 return $VERSION;
114             }
115              
116             #################
117             ## ##
118             ## Resources ##
119             ## ##
120             #################
121              
122             my $DateCalc_YEAR_OF_EPOCH = 70; # year of reference (epoch)
123             my $DateCalc_CENTURY_OF_EPOCH = 1900; # century of reference (epoch)
124             my $DateCalc_EPOCH = $DateCalc_CENTURY_OF_EPOCH + $DateCalc_YEAR_OF_EPOCH;
125              
126             my $DateCalc_DAYS_TO_EPOCH;
127             my $DateCalc_DAYS_TO_OVFLW;
128             my $DateCalc_SECS_TO_OVFLW;
129              
130             ## MacOS (Classic): ##
131             ## <695056.0> = Fri 1-Jan-1904 00:00:00 (time=0x00000000) ##
132             ## <744766.23295> = Mon 6-Feb-2040 06:28:15 (time=0xFFFFFFFF) ##
133              
134             ## Unix: ##
135             ## <719163.0> = Thu 1-Jan-1970 00:00:00 (time=0x00000000) ##
136             ## <744018.11647> = Tue 19-Jan-2038 03:14:07 (time=0x7FFFFFFF) ##
137              
138             if ($^O eq 'MacOS')
139             {
140             $DateCalc_DAYS_TO_EPOCH = 695056;
141             $DateCalc_DAYS_TO_OVFLW = 744766;
142             $DateCalc_SECS_TO_OVFLW = 23295;
143             }
144             else
145             {
146             $DateCalc_DAYS_TO_EPOCH = 719163;
147             $DateCalc_DAYS_TO_OVFLW = 744018;
148             $DateCalc_SECS_TO_OVFLW = 11647;
149             }
150              
151             my(@DateCalc_Days_in_Year_) =
152             (
153             [ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 ],
154             [ 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 ]
155             );
156              
157             my(@DateCalc_Days_in_Month_) =
158             (
159             [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
160             [ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
161             );
162              
163             my $DateCalc_LANGUAGES = 14;
164              
165             my $DateCalc_Language = 1; # Default = 1 (English)
166              
167             my(@DateCalc_Month_to_Text_) =
168             (
169             [
170             "???", "???", "???", "???", "???", "???", "???",
171             "???", "???", "???", "???", "???", "???"
172             ],
173             [
174             "???", "January", "February", "March", "April", "May", "June",
175             "July", "August", "September", "October", "November", "December"
176             ],
177             [
178             "???", "janvier", "février", "mars", "avril", "mai", "juin",
179             "juillet", "aoűt", "septembre", "octobre", "novembre", "décembre"
180             ],
181             [
182             "???", "Januar", "Februar", "März", "April", "Mai", "Juni",
183             "Juli", "August", "September", "Oktober", "November", "Dezember"
184             ],
185             [
186             "???", "enero", "febrero", "marzo", "abril", "mayo", "junio",
187             "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"
188             ],
189             [
190             "???", "janeiro", "fevereiro", "março", "abril", "maio", "junho",
191             "julho", "agosto", "setembro", "outubro", "novembro", "dezembro"
192             ],
193             [
194             "???", "januari", "februari", "maart", "april", "mei", "juni",
195             "juli", "augustus", "september", "oktober", "november", "december"
196             ],
197             [
198             "???", "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno",
199             "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"
200             ],
201             [
202             "???", "januar", "februar", "mars", "april", "mai", "juni",
203             "juli", "august", "september", "oktober", "november", "desember"
204             ],
205             [
206             "???", "januari", "februari", "mars", "april", "maj", "juni",
207             "juli", "augusti", "september", "oktober", "november", "december"
208             ],
209             [
210             "???", "januar", "februar", "marts", "april", "maj", "juni",
211             "juli", "august", "september", "oktober", "november", "december"
212             ],
213             [
214             "???", "tammikuu", "helmikuu", "maaliskuu", "huhtikuu",
215             "toukokuu", "kesäkuu", "heinäkuu", "elokuu",
216             "syyskuu", "lokakuu", "marraskuu", "joulukuu"
217             ],
218             [
219             "???", "Január", "Február", "Március", "Április", "Május", "Június",
220             "Július", "Augusztus", "Szeptember", "Október", "November", "December"
221             ],
222             [
223             "???", "Styczen", "Luty", "Marzec", "Kwiecien", "Maj", "Czerwiec", # ISO-Latin-1 approximation
224             "Lipiec", "Sierpien", "Wrzesien", "Pazdziernik", "Listopad", "Grudzien"
225             ],
226             [
227             "???", "Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie",
228             "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"
229             ]
230             );
231              
232             my(@DateCalc_Day_of_Week_to_Text_) =
233             (
234             [
235             "???", "???", "???", "???",
236             "???", "???", "???", "???"
237             ],
238             [
239             "???", "Monday", "Tuesday", "Wednesday",
240             "Thursday", "Friday", "Saturday", "Sunday"
241             ],
242             [
243             "???", "Lundi", "Mardi", "Mercredi",
244             "Jeudi", "Vendredi", "Samedi", "Dimanche"
245             ],
246             [
247             "???", "Montag", "Dienstag", "Mittwoch",
248             "Donnerstag", "Freitag", "Samstag", "Sonntag"
249             ],
250             [
251             "???", "Lunes", "Martes", "Miércoles",
252             "Jueves", "Viernes", "Sábado", "Domingo"
253             ],
254             [
255             "???", "Segunda-feira", "Terça-feira", "Quarta-feira",
256             "Quinta-feira", "Sexta-feira", "Sábado", "Domingo"
257             ],
258             [
259             "???", "Maandag", "Dinsdag", "Woensdag",
260             "Donderdag", "Vrijdag", "Zaterdag", "Zondag"
261             ],
262             [
263             "???", "Lunedě", "Martedě", "Mercoledě",
264             "Giovedě", "Venerdě", "Sabato", "Domenica"
265             ],
266             [
267             "???", "mandag", "tirsdag", "onsdag",
268             "torsdag", "fredag", "lřrdag", "sřndag"
269             ],
270             [
271             "???", "mĺndag", "tisdag", "onsdag",
272             "torsdag", "fredag", "lördag", "söndag"
273             ],
274             [
275             "???", "mandag", "tirsdag", "onsdag",
276             "torsdag", "fredag", "lřrdag", "sřndag"
277             ],
278             [
279             "???", "maanantai", "tiistai", "keskiviikko",
280             "torstai", "perjantai", "lauantai", "sunnuntai"
281             ],
282             [
283             "???", "hétfő", "kedd", "szerda",
284             "csütörtök", "péntek", "szombat", "vasárnap"
285             ],
286             [
287             "???", "poniedzialek", "wtorek", "sroda", # ISO-Latin-1 approximation
288             "czwartek", "piatek", "sobota", "niedziela"
289             ],
290             [
291             "???", "Luni", "Marti", "Miercuri",
292             "Joi", "Vineri", "Sambata", "Duminica"
293             ]
294             );
295              
296             my(@DateCalc_Day_of_Week_Abbreviation_) =
297             (
298             # Fill the fields below _only_ if special abbreviations are needed!
299             # Note that the first field serves as a flag and must be non-empty!
300             [
301             "", "", "", "", "", "", "", "" # 0 #
302             ],
303             [
304             "", "", "", "", "", "", "", "" # 1 #
305             ],
306             [
307             "", "", "", "", "", "", "", "" # 2 #
308             ],
309             [
310             "", "", "", "", "", "", "", "" # 3 #
311             ],
312             [
313             "", "", "", "", "", "", "", "" # 4 #
314             ],
315             [
316             "", "", "", "", "", "", "", "" # 5 #
317             # "???", "2Ş", "3Ş", "4Ş", "5Ş", "6Ş", "Sáb", "Dom" # 5 #
318             ],
319             [
320             "", "", "", "", "", "", "", "" # 6 #
321             ],
322             [
323             "", "", "", "", "", "", "", "" # 7 #
324             ],
325             [
326             "", "", "", "", "", "", "", "" # 8 #
327             ],
328             [
329             "", "", "", "", "", "", "", "" # 9 #
330             ],
331             [
332             "", "", "", "", "", "", "", "" # 10 #
333             ],
334             [
335             "", "", "", "", "", "", "", "" # 11 #
336             ],
337             [
338             "", "", "", "", "", "", "", "" # 12 #
339             ],
340             [
341             "???", "Pn", "Wt", "Sr", "Cz", "Pt", "So", "Ni" # 13 # ISO-Latin-1 approximation
342             ],
343             [
344             "", "", "", "", "", "", "", "" # 14 #
345             ]
346             );
347              
348             my(@DateCalc_English_Ordinals_) =
349             (
350             "th",
351             "st",
352             "nd",
353             "rd"
354             );
355              
356             my(@DateCalc_Date_Long_Format_) =
357             (
358             "%s, %d %s %d", # 0 Default #
359             "%s, %s %s %d", # 1 English #
360             "%s %d %s %d", # 2 Français #
361             "%s, den %d. %s %d", # 3 Deutsch #
362             "%s, %d de %s de %d", # 4 Espańol #
363             "%s, dia %d de %s de %d", # 5 Portuguęs #
364             "%s, %d %s %d", # 6 Nederlands #
365             "%s, %d %s %d", # 7 Italiano #
366             "%s, %d. %s %d", # 8 Norsk #
367             "%s, %d %s %d", # 9 Svenska #
368             "%s, %d. %s %d", # 10 Dansk #
369             "%s, %d. %sta %d", # 11 suomi #
370             "%d. %s %d., %s", # 12 Magyar #
371             "%s, %d %s %d", # 13 polski #
372             "%s %d %s %d" # 14 Romaneste #
373             );
374              
375             my(@DateCalc_Language_to_Text_) =
376             (
377             "???", "English", "Français", "Deutsch", "Espańol",
378             "Portuguęs", "Nederlands", "Italiano", "Norsk", "Svenska",
379             "Dansk", "suomi", "Magyar", "polski", "Romaneste"
380             );
381              
382             ###############
383             ## ##
384             ## Calc.xs ##
385             ## ##
386             ###############
387              
388             ###############################################################################
389             ## ##
390             ## Copyright (c) 1995 - 2015 by Steffen Beyer. ##
391             ## All rights reserved. ##
392             ## ##
393             ## This package is free software; you can redistribute it ##
394             ## and/or modify it under the same terms as Perl itself. ##
395             ## ##
396             ###############################################################################
397              
398             sub DATECALC_USAGE
399             {
400 0     0 0 0 croak('Usage: Date::Calc::' . $_[0]);
401             }
402             sub DATECALC_ERROR
403             {
404 0     0 0 0 croak("Date::Calc::$_[0](): $_[1]");
405             }
406             sub DATECALC_DATE_ERROR
407             {
408 32     32 0 110 croak("Date::Calc::$_[0](): not a valid date");
409             }
410             sub DATECALC_TIME_ERROR
411             {
412 17     17 0 46 croak("Date::Calc::$_[0](): not a valid time");
413             }
414             sub DATECALC_YEAR_ERROR
415             {
416 4     4 0 16 croak("Date::Calc::$_[0](): year out of range");
417             }
418             sub DATECALC_MONTH_ERROR
419             {
420 17     17 0 41 croak("Date::Calc::$_[0](): month out of range");
421             }
422             sub DATECALC_WEEK_ERROR
423             {
424 4     4 0 12 croak("Date::Calc::$_[0](): week out of range");
425             }
426             sub DATECALC_DAYOFWEEK_ERROR
427             {
428 10     10 0 23 croak("Date::Calc::$_[0](): day of week out of range");
429             }
430             sub DATECALC_DATE_RANGE_ERROR
431             {
432 0     0 0 0 croak("Date::Calc::$_[0](): date out of range");
433             }
434             sub DATECALC_TIME_RANGE_ERROR
435             {
436 0     0 0 0 croak("Date::Calc::$_[0](): time out of range");
437             }
438             sub DATECALC_FACTOR_ERROR
439             {
440 0     0 0 0 croak("Date::Calc::$_[0](): factor out of range");
441             }
442             sub DATECALC_LANGUAGE_ERROR
443             {
444 1     1 0 6 croak("Date::Calc::$_[0](): language not available");
445             }
446             sub DATECALC_SYSTEM_ERROR
447             {
448 0     0 0 0 croak("Date::Calc::$_[0](): not available on this system");
449             }
450             sub DATECALC_MEMORY_ERROR
451             {
452 0     0 0 0 croak("Date::Calc::$_[0](): unable to allocate memory");
453             }
454             sub DATECALC_STRING_ERROR
455             {
456 0     0 0 0 croak("Date::Calc::$_[0](): argument is not a string");
457             }
458             sub DATECALC_SCALAR_ERROR
459             {
460 0     0 0 0 croak("Date::Calc::$_[0](): argument is not a scalar");
461             }
462              
463             sub Days_in_Year
464             {
465 191 50   191 0 410 DATECALC_USAGE('Days_in_Year($year,$month)') unless (@_ == 2);
466 191         225 my($year,$month) = @_;
467 191 50       354 if ($year > 0)
468             {
469 191 50 33     677 if (($month >= 1) and ($month <= 12))
470             {
471 191         388 return $DateCalc_Days_in_Year_[DateCalc_leap_year($year)][$month+1];
472             }
473 0         0 else { DATECALC_MONTH_ERROR('Days_in_Year'); }
474             }
475 0         0 else { DATECALC_YEAR_ERROR('Days_in_Year'); }
476             }
477              
478             sub Days_in_Month
479             {
480 26 50   26 0 282 DATECALC_USAGE('Days_in_Month($year,$month)') unless (@_ == 2);
481 26         40 my($year,$month) = @_;
482 26 50       32 if ($year > 0)
483             {
484 26 100 66     70 if (($month >= 1) and ($month <= 12))
485             {
486 24         26 return $DateCalc_Days_in_Month_[DateCalc_leap_year($year)][$month];
487             }
488 2         4 else { DATECALC_MONTH_ERROR('Days_in_Month'); }
489             }
490 0         0 else { DATECALC_YEAR_ERROR('Days_in_Month'); }
491             }
492              
493             sub Weeks_in_Year
494             {
495 4 50   4 0 47 DATECALC_USAGE('Weeks_in_Year($year)') unless (@_ == 1);
496 4         22 my($year) = shift;
497 4 50       8 if ($year > 0)
498             {
499 4         8 return DateCalc_Weeks_in_Year($year);
500             }
501 0         0 else { DATECALC_YEAR_ERROR('Weeks_in_Year'); }
502             }
503              
504             sub leap_year
505             {
506 4 50   4 0 33 DATECALC_USAGE('leap_year($year)') unless (@_ == 1);
507 4         25 my($year) = shift;
508 4 50       19 if ($year > 0)
509             {
510 4         6 return DateCalc_leap_year($year);
511             }
512 0         0 else { DATECALC_YEAR_ERROR('leap_year'); }
513             }
514              
515             sub check_date
516             {
517 47213 50   47213 0 70174 DATECALC_USAGE('check_date($year,$month,$day)') unless (@_ == 3);
518 47213         38254 my($year,$month,$day) = @_;
519 47213         51146 return DateCalc_check_date($year,$month,$day);
520             }
521              
522             sub check_time
523             {
524 315 50   315 0 494 DATECALC_USAGE('check_time($hour,$min,$sec)') unless (@_ == 3);
525 315         296 my($hour,$min,$sec) = @_;
526 315         389 return DateCalc_check_time($hour,$min,$sec);
527             }
528              
529             sub check_business_date
530             {
531 0 0   0 0 0 DATECALC_USAGE('check_business_date($year,$week,$dow)') unless (@_ == 3);
532 0         0 my($year,$week,$dow) = @_;
533 0         0 return DateCalc_check_business_date($year,$week,$dow);
534             }
535              
536             sub Day_of_Year
537             {
538 0 0   0 0 0 DATECALC_USAGE('Day_of_Year($year,$month,$day)') unless (@_ == 3);
539 0         0 my($year,$month,$day) = @_;
540 0         0 my $retval = DateCalc_Day_of_Year($year,$month,$day);
541 0 0       0 if ($retval == 0) { DATECALC_DATE_ERROR('Day_of_Year'); }
  0         0  
542 0         0 return $retval;
543             }
544              
545             sub Date_to_Days
546             {
547 24648 50   24648 0 37161 DATECALC_USAGE('Date_to_Days($year,$month,$day)') unless (@_ == 3);
548 24648         23385 my($year,$month,$day) = @_;
549 24648         28391 my $retval = DateCalc_Date_to_Days($year,$month,$day);
550 24648 50       38487 if ($retval == 0) { DATECALC_DATE_ERROR('Date_to_Days'); }
  0         0  
551 24648         34607 return $retval;
552             }
553              
554             sub Day_of_Week
555             {
556 870 50   870 0 1608 DATECALC_USAGE('Day_of_Week($year,$month,$day)') unless (@_ == 3);
557 870         902 my($year,$month,$day) = @_;
558 870         1215 my $retval = DateCalc_Day_of_Week($year,$month,$day);
559 870 100       1427 if ($retval == 0) { DATECALC_DATE_ERROR('Day_of_Week'); }
  1         3  
560 869         1610 return $retval;
561             }
562              
563             sub Week_Number
564             {
565 0 0   0 0 0 DATECALC_USAGE('Week_Number($year,$month,$day)') unless (@_ == 3);
566 0         0 my($year,$month,$day) = @_;
567 0         0 my($retval);
568 0 0       0 if (DateCalc_check_date($year,$month,$day))
569             {
570 0         0 $retval = DateCalc_Week_Number($year,$month,$day);
571             }
572 0         0 else { DATECALC_DATE_ERROR('Week_Number'); }
573 0         0 return $retval;
574             }
575              
576             sub Week_of_Year
577             {
578 9 50   9 0 174 DATECALC_USAGE('Week_of_Year($year,$month,$day)') unless (@_ == 3);
579 9         59 my($year,$month,$day) = @_;
580 9         6 my($week);
581 9 100       18 if (DateCalc_week_of_year(\$week,\$year,$month,$day))
582             {
583 7 50       15 if (wantarray) { return($week,$year); }
  7         18  
584 0         0 else { return $week; }
585             }
586 2         5 else { DATECALC_DATE_ERROR('Week_of_Year'); }
587             }
588              
589             sub Monday_of_Week
590             {
591 17 50   17 0 543 DATECALC_USAGE('Monday_of_Week($week,$year)') unless (@_ == 2);
592 17         39 my($week,$year) = @_;
593 17         10 my($month,$day);
594 17 100       26 if ($year > 0)
595             {
596 15 100 100     37 if (($week > 0) and ($week <= DateCalc_Weeks_in_Year($year)))
597             {
598 11 50       19 if (DateCalc_monday_of_week($week,\$year,\$month,\$day))
599             {
600 11         28 return($year,$month,$day);
601             }
602 0         0 else { DATECALC_DATE_ERROR('Monday_of_Week'); }
603             }
604 4         10 else { DATECALC_WEEK_ERROR('Monday_of_Week'); }
605             }
606 2         4 else { DATECALC_YEAR_ERROR('Monday_of_Week'); }
607             }
608              
609             sub Nth_Weekday_of_Month_Year
610             {
611 1323 50   1323 0 2408 DATECALC_USAGE('Nth_Weekday_of_Month_Year($year,$month,$dow,$n)') unless (@_ == 4);
612 1323         1946 my($year,$month,$dow,$n) = @_;
613 1323         941 my($day);
614 1323 50       1784 if ($year > 0)
615             {
616 1323 50 33     4142 if (($month >= 1) and ($month <= 12))
617             {
618 1323 50 33     3634 if (($dow >= 1) and ($dow <= 7))
619             {
620 1323 50 33     4026 if (($n >= 1) and ($n <= 5))
621             {
622 1323 100       2692 if (DateCalc_nth_weekday_of_month_year(\$year,\$month,\$day,$dow,$n))
623             {
624 1252         5241 return($year,$month,$day);
625             }
626 71         316 else { return(); }
627             }
628 0         0 else { DATECALC_FACTOR_ERROR('Nth_Weekday_of_Month_Year'); }
629             }
630 0         0 else { DATECALC_DAYOFWEEK_ERROR('Nth_Weekday_of_Month_Year'); }
631             }
632 0         0 else { DATECALC_MONTH_ERROR('Nth_Weekday_of_Month_Year'); }
633             }
634 0         0 else { DATECALC_YEAR_ERROR('Nth_Weekday_of_Month_Year'); }
635             }
636              
637             sub Standard_to_Business
638             {
639 629 50   629 0 2290 DATECALC_USAGE('Standard_to_Business($year,$month,$day)') unless (@_ == 3);
640 629         601 my($year,$month,$day) = @_;
641 629         496 my($week,$dow);
642 629 50       964 if (DateCalc_standard_to_business(\$year,\$week,\$dow,$month,$day))
643             {
644 629         1810 return($year,$week,$dow);
645             }
646 0         0 else { DATECALC_DATE_ERROR('Standard_to_Business'); }
647             }
648              
649             sub Business_to_Standard
650             {
651 629 50   629 0 2226 DATECALC_USAGE('Business_to_Standard($year,$week,$dow)') unless (@_ == 3);
652 629         627 my($year,$week,$dow) = @_;
653 629         451 my($month,$day);
654 629 50       951 if (DateCalc_business_to_standard(\$year,\$month,\$day,$week,$dow))
655             {
656 629         2055 return($year,$month,$day);
657             }
658 0         0 else { DATECALC_DATE_ERROR('Business_to_Standard'); }
659             }
660              
661             sub Delta_Days
662             {
663 15 50   15 0 189 DATECALC_USAGE('Delta_Days($year1,$month1,$day1,$year2,$month2,$day2)') unless (@_ == 6);
664 15         35 my($year1,$month1,$day1,$year2,$month2,$day2) = @_;
665 15         11 my($retval);
666 15 100 100     28 if (DateCalc_check_date($year1,$month1,$day1) and
667             DateCalc_check_date($year2,$month2,$day2))
668             {
669 12         24 $retval = DateCalc_Delta_Days($year1,$month1,$day1, $year2,$month2,$day2);
670             }
671 3         5 else { DATECALC_DATE_ERROR('Delta_Days'); }
672 12         36 return $retval;
673             }
674              
675             sub Delta_DHMS
676             {
677 32 50   32 0 1022 DATECALC_USAGE('Delta_DHMS($year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2)') unless (@_ == 12);
678 32         98 my($year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2) = @_;
679 32         21 my($Dd,$Dh,$Dm,$Ds);
680 32 100 100     42 if (DateCalc_check_date($year1,$month1,$day1) and
681             DateCalc_check_date($year2,$month2,$day2))
682             {
683 29 100 100     35 if (DateCalc_check_time($hour1,$min1,$sec1) and
684             DateCalc_check_time($hour2,$min2,$sec2))
685             {
686 17 50       45 if (DateCalc_delta_dhms(\$Dd,\$Dh,\$Dm,\$Ds,
687             $year1,$month1,$day1, $hour1,$min1,$sec1,
688             $year2,$month2,$day2, $hour2,$min2,$sec2))
689             {
690 17         57 return($Dd,$Dh,$Dm,$Ds);
691             }
692 0         0 else { DATECALC_DATE_ERROR('Delta_DHMS'); }
693             }
694 12         14 else { DATECALC_TIME_ERROR('Delta_DHMS'); }
695             }
696 3         5 else { DATECALC_DATE_ERROR('Delta_DHMS'); }
697             }
698              
699             sub Delta_YMD
700             {
701 5 50   5 0 9 DATECALC_USAGE('Delta_YMD($year1,$month1,$day1,$year2,$month2,$day2)') unless (@_ == 6);
702 5         5 my($year1,$month1,$day1,$year2,$month2,$day2) = @_;
703 5 50       12 if (DateCalc_delta_ymd(\$year1,\$month1,\$day1, $year2,$month2,$day2))
704             {
705 5         21 return($year1,$month1,$day1);
706             }
707 0         0 else { DATECALC_DATE_ERROR('Delta_YMD'); }
708             }
709              
710             sub Delta_YMDHMS
711             {
712 3 50   3 0 7 DATECALC_USAGE('Delta_YMDHMS($year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2)') unless (@_ == 12);
713 3         5 my($year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2) = @_;
714 3         3 my($D_y,$D_m,$D_d,$Dh,$Dm,$Ds);
715 3 50 33     4 if (DateCalc_check_date($year1,$month1,$day1) and
716             DateCalc_check_date($year2,$month2,$day2))
717             {
718 3 50 33     4 if (DateCalc_check_time($hour1,$min1,$sec1) and
719             DateCalc_check_time($hour2,$min2,$sec2))
720             {
721 3 50       15 if (DateCalc_delta_ymdhms(\$D_y,\$D_m,\$D_d, \$Dh,\$Dm,\$Ds,
722             $year1,$month1,$day1, $hour1,$min1,$sec1,
723             $year2,$month2,$day2, $hour2,$min2,$sec2))
724             {
725 3         16 return($D_y,$D_m,$D_d,$Dh,$Dm,$Ds);
726             }
727 0         0 else { DATECALC_DATE_ERROR('Delta_YMDHMS'); }
728             }
729 0         0 else { DATECALC_TIME_ERROR('Delta_YMDHMS'); }
730             }
731 0         0 else { DATECALC_DATE_ERROR('Delta_YMDHMS'); }
732             }
733              
734             sub N_Delta_YMD
735             {
736 82 50   82 0 1163 DATECALC_USAGE('N_Delta_YMD($year1,$month1,$day1,$year2,$month2,$day2)') unless (@_ == 6);
737 82         108 my($year1,$month1,$day1,$year2,$month2,$day2) = @_;
738 82 100       179 if (DateCalc_norm_delta_ymd(\$year1,\$month1,\$day1, $year2,$month2,$day2))
739             {
740 74         290 return($year1,$month1,$day1);
741             }
742 8         13 else { DATECALC_DATE_ERROR('N_Delta_YMD'); }
743             }
744              
745             sub N_Delta_YMDHMS
746             {
747 84 50   84 0 1154 DATECALC_USAGE('N_Delta_YMDHMS($year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2)') unless (@_ == 12);
748 84         95 my($year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2) = @_;
749 84         69 my($D_y,$D_m,$D_d,$Dhh,$Dmm,$Dss);
750 84 100 100     102 if (DateCalc_check_date($year1,$month1,$day1) and
751             DateCalc_check_date($year2,$month2,$day2))
752             {
753 82 100 100     103 if (DateCalc_check_time($hour1,$min1,$sec1) and
754             DateCalc_check_time($hour2,$min2,$sec2))
755             {
756 80 50       173 if (DateCalc_norm_delta_ymdhms(\$D_y,\$D_m,\$D_d, \$Dhh,\$Dmm,\$Dss,
757             $year1,$month1,$day1, $hour1,$min1,$sec1,
758             $year2,$month2,$day2, $hour2,$min2,$sec2))
759             {
760 80         311 return($D_y,$D_m,$D_d,$Dhh,$Dmm,$Dss);
761             }
762 0         0 else { DATECALC_DATE_ERROR('N_Delta_YMDHMS'); }
763             }
764 2         5 else { DATECALC_TIME_ERROR('N_Delta_YMDHMS'); }
765             }
766 2         4 else { DATECALC_DATE_ERROR('N_Delta_YMDHMS'); }
767             }
768              
769             sub Normalize_DHMS
770             {
771 14 50   14 0 26 DATECALC_USAGE('Normalize_DHMS($Dd,$Dh,$Dm,$Ds)') unless (@_ == 4);
772 14         14 my($Dd,$Dh,$Dm,$Ds) = @_;
773 14         31 DateCalc_Normalize_DHMS(\$Dd,\$Dh,\$Dm,\$Ds);
774 14         52 return($Dd,$Dh,$Dm,$Ds);
775             }
776              
777             sub Add_Delta_Days
778             {
779 2213 50   2213 0 8952 DATECALC_USAGE('Add_Delta_Days($year,$month,$day,$Dd)') unless (@_ == 4);
780 2213         2842 my($year,$month,$day,$Dd) = @_;
781 2213 100       3784 if (DateCalc_add_delta_days(\$year,\$month,\$day, $Dd))
782             {
783 2210         6783 return($year,$month,$day);
784             }
785 3         6 else { DATECALC_DATE_ERROR('Add_Delta_Days'); }
786             }
787              
788             sub Add_Delta_DHMS
789             {
790 56 50   56 0 535 DATECALC_USAGE('Add_Delta_DHMS($year,$month,$day,$hour,$min,$sec,$Dd,$Dh,$Dm,$Ds)') unless (@_ == 10);
791 56         86 my($year,$month,$day,$hour,$min,$sec,$Dd,$Dh,$Dm,$Ds) = @_;
792 56 100       67 if (DateCalc_check_date($year,$month,$day))
793             {
794 55 100       66 if (DateCalc_check_time($hour,$min,$sec))
795             {
796 52 100       101 if (DateCalc_add_delta_dhms(\$year,\$month,\$day,
797             \$hour,\$min,\$sec,
798             $Dd,$Dh,$Dm,$Ds))
799             {
800 51         186 return($year,$month,$day,$hour,$min,$sec);
801             }
802 1         6 else { DATECALC_DATE_ERROR('Add_Delta_DHMS'); }
803             }
804 3         4 else { DATECALC_TIME_ERROR('Add_Delta_DHMS'); }
805             }
806 1         7 else { DATECALC_DATE_ERROR('Add_Delta_DHMS'); }
807             }
808              
809             sub Add_Delta_YM
810             {
811 74 50   74 0 329 DATECALC_USAGE('Add_Delta_YM($year,$month,$day,$Dy,$Dm)') unless (@_ == 5);
812 74         71 my($year,$month,$day,$Dy,$Dm) = @_;
813 74 50       97 if (DateCalc_add_delta_ym(\$year,\$month,\$day, $Dy,$Dm))
814             {
815 74         123 return($year,$month,$day);
816             }
817 0         0 else { DATECALC_DATE_ERROR('Add_Delta_YM'); }
818             }
819              
820             sub Add_Delta_YMD
821             {
822 53 50   53 0 622 DATECALC_USAGE('Add_Delta_YMD($year,$month,$day,$Dy,$Dm,$Dd)') unless (@_ == 6);
823 53         81 my($year,$month,$day,$Dy,$Dm,$Dd) = @_;
824 53 100       163 if (DateCalc_add_delta_ymd(\$year,\$month,\$day, $Dy,$Dm,$Dd))
825             {
826 45         130 return($year,$month,$day);
827             }
828 8         10 else { DATECALC_DATE_ERROR('Add_Delta_YMD'); }
829             }
830              
831             sub Add_Delta_YMDHMS
832             {
833 6 50   6 0 13 DATECALC_USAGE('Add_Delta_YMDHMS($year,$month,$day,$hour,$min,$sec,$D_y,$D_m,$D_d,$Dh,$Dm,$Ds)') unless (@_ == 12);
834 6         12 my($year,$month,$day,$hour,$min,$sec,$D_y,$D_m,$D_d,$Dh,$Dm,$Ds) = @_;
835 6 50       8 if (DateCalc_check_date($year,$month,$day))
836             {
837 6 50       8 if (DateCalc_check_time($hour,$min,$sec))
838             {
839 6 50       18 if (DateCalc_add_delta_ymdhms(\$year,\$month,\$day,
840             \$hour,\$min,\$sec,
841             $D_y,$D_m,$D_d,
842             $Dh,$Dm,$Ds))
843             {
844 6         20 return($year,$month,$day,$hour,$min,$sec);
845             }
846 0         0 else { DATECALC_DATE_ERROR('Add_Delta_YMDHMS'); }
847             }
848 0         0 else { DATECALC_TIME_ERROR('Add_Delta_YMDHMS'); }
849             }
850 0         0 else { DATECALC_DATE_ERROR('Add_Delta_YMDnMS'); }
851             }
852              
853             sub Add_N_Delta_YMD
854             {
855 96 50   96 0 214 DATECALC_USAGE('Add_N_Delta_YMD($year,$month,$day,$Dy,$Dm,$Dd)') unless (@_ == 6);
856 96         94 my($year,$month,$day,$Dy,$Dm,$Dd) = @_;
857 96 50       159 if (DateCalc_add_norm_delta_ymd(\$year,\$month,\$day, $Dy,$Dm,$Dd))
858             {
859 96         257 return($year,$month,$day);
860             }
861 0         0 else { DATECALC_DATE_ERROR('Add_N_Delta_YMD'); }
862             }
863              
864             sub Add_N_Delta_YMDHMS
865             {
866 80 50   80 0 240 DATECALC_USAGE('Add_N_Delta_YMDHMS($year,$month,$day,$hour,$min,$sec,$D_y,$D_m,$D_d,$Dhh,$Dmm,$Dss)') unless (@_ == 12);
867 80         101 my($year,$month,$day,$hour,$min,$sec,$D_y,$D_m,$D_d,$Dhh,$Dmm,$Dss) = @_;
868 80 50       111 if (DateCalc_check_date($year,$month,$day))
869             {
870 80 50       97 if (DateCalc_check_time($hour,$min,$sec))
871             {
872 80 50       145 if (DateCalc_add_norm_delta_ymdhms(\$year,\$month,\$day,
873             \$hour,\$min,\$sec,
874             $D_y,$D_m,$D_d,
875             $Dhh,$Dmm,$Dss))
876             {
877 80         370 return($year,$month,$day,$hour,$min,$sec);
878             }
879 0         0 else { DATECALC_DATE_ERROR('Add_N_Delta_YMDHMS'); }
880             }
881 0         0 else { DATECALC_TIME_ERROR('Add_N_Delta_YMDHMS'); }
882             }
883 0         0 else { DATECALC_DATE_ERROR('Add_N_Delta_YMDHMS'); }
884             }
885              
886             sub System_Clock
887             {
888 0 0 0 0 0 0 DATECALC_USAGE('System_Clock([$gmt])') unless ((@_ == 0) or (@_ == 1));
889 0         0 my($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst,$gmt);
890 0 0       0 if (@_ == 1) { $gmt = shift; }
  0         0  
891 0         0 else { $gmt = 0; }
892 0 0       0 if (DateCalc_system_clock(\$year,\$month,\$day,
893             \$hour,\$min,\$sec,
894             \$doy,\$dow,\$dst,
895             $gmt))
896             {
897 0         0 return($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst);
898             }
899 0         0 else { DATECALC_SYSTEM_ERROR('System_Clock'); }
900             }
901              
902             sub Today
903             {
904 0 0 0 0 0 0 DATECALC_USAGE('Today([$gmt])') unless ((@_ == 0) or (@_ == 1));
905 0         0 my($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst,$gmt);
906 0 0       0 if (@_ == 1) { $gmt = shift; }
  0         0  
907 0         0 else { $gmt = 0; }
908 0 0       0 if (DateCalc_system_clock(\$year,\$month,\$day,
909             \$hour,\$min,\$sec,
910             \$doy,\$dow,\$dst,
911             $gmt))
912             {
913 0         0 return($year,$month,$day);
914             }
915 0         0 else { DATECALC_SYSTEM_ERROR('Today'); }
916             }
917              
918             sub Now
919             {
920 0 0 0 0 0 0 DATECALC_USAGE('Now([$gmt])') unless ((@_ == 0) or (@_ == 1));
921 0         0 my($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst,$gmt);
922 0 0       0 if (@_ == 1) { $gmt = shift; }
  0         0  
923 0         0 else { $gmt = 0; }
924 0 0       0 if (DateCalc_system_clock(\$year,\$month,\$day,
925             \$hour,\$min,\$sec,
926             \$doy,\$dow,\$dst,
927             $gmt))
928             {
929 0         0 return($hour,$min,$sec);
930             }
931 0         0 else { DATECALC_SYSTEM_ERROR('Now'); }
932             }
933              
934             sub Today_and_Now
935             {
936 1 50 33 1 0 16 DATECALC_USAGE('Today_and_Now([$gmt])') unless ((@_ == 0) or (@_ == 1));
937 1         3 my($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst,$gmt);
938 1 50       4 if (@_ == 1) { $gmt = shift; }
  0         0  
939 1         3 else { $gmt = 0; }
940 1 50       7 if (DateCalc_system_clock(\$year,\$month,\$day,
941             \$hour,\$min,\$sec,
942             \$doy,\$dow,\$dst,
943             $gmt))
944             {
945 1         4 return($year,$month,$day,$hour,$min,$sec);
946             }
947 0         0 else { DATECALC_SYSTEM_ERROR('Today_and_Now'); }
948             }
949              
950             sub This_Year
951             {
952 0 0 0 0 0 0 DATECALC_USAGE('This_Year([$gmt])') unless ((@_ == 0) or (@_ == 1));
953 0         0 my($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst,$gmt);
954 0 0       0 if (@_ == 1) { $gmt = shift; }
  0         0  
955 0         0 else { $gmt = 0; }
956 0 0       0 if (DateCalc_system_clock(\$year,\$month,\$day,
957             \$hour,\$min,\$sec,
958             \$doy,\$dow,\$dst,
959             $gmt))
960             {
961 0         0 return($year);
962             }
963 0         0 else { DATECALC_SYSTEM_ERROR('This_Year'); }
964             }
965              
966             sub Gmtime
967             {
968 2 50 33 2 0 17 DATECALC_USAGE('Gmtime([time])') unless ((@_ == 0) or (@_ == 1));
969 2         3 my($seconds,$year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst);
970 2 50       7 if (@_ == 1) { $seconds = shift; }
  0         0  
971 2         17 else { $seconds = time; }
972 2 50 33     16 if (($seconds < 0) or ($seconds > 0xFFFFFFFF)) { DATECALC_TIME_RANGE_ERROR('Gmtime'); }
  0         0  
973 2 50       15 if (DateCalc_gmtime(\$year,\$month,\$day,
974             \$hour,\$min,\$sec,
975             \$doy,\$dow,\$dst,
976             $seconds))
977             {
978 2         10 return($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst);
979             }
980 0         0 else { DATECALC_TIME_RANGE_ERROR('Gmtime'); }
981             }
982              
983             sub Localtime
984             {
985 2 50 33 2 0 16 DATECALC_USAGE('Localtime([time])') unless ((@_ == 0) or (@_ == 1));
986 2         4 my($seconds,$year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst);
987 2 50       11 if (@_ == 1) { $seconds = shift; }
  0         0  
988 2         3 else { $seconds = time; }
989 2 50 33     17 if (($seconds < 0) or ($seconds > 0xFFFFFFFF)) { DATECALC_TIME_RANGE_ERROR('Localtime'); }
  0         0  
990 2 50       12 if (DateCalc_localtime(\$year,\$month,\$day,
991             \$hour,\$min,\$sec,
992             \$doy,\$dow,\$dst,
993             $seconds))
994             {
995 2         14 return($year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst);
996             }
997 0         0 else { DATECALC_TIME_RANGE_ERROR('Localtime'); }
998             }
999              
1000             sub Mktime
1001             {
1002 2 50   2 0 14 DATECALC_USAGE('Mktime($year,$month,$day,$hour,$min,$sec)') unless (@_ == 6);
1003 2         5 my($year,$month,$day,$hour,$min,$sec) = @_;
1004 2         4 my($seconds);
1005 2 50       17 if (DateCalc_mktime(\$seconds, $year,$month,$day, $hour,$min,$sec, -1,-1,-1))
1006             {
1007 2         8 return $seconds;
1008             }
1009 0         0 else { DATECALC_DATE_RANGE_ERROR('Mktime'); }
1010             }
1011              
1012             sub Timezone
1013             {
1014 0 0 0 0 0 0 DATECALC_USAGE('Timezone([time])') unless ((@_ == 0) or (@_ == 1));
1015 0         0 my($when,$year,$month,$day,$hour,$min,$sec,$dst);
1016 0 0       0 if (@_ == 1) { $when = shift; }
  0         0  
1017 0         0 else { $when = time; }
1018 0 0 0     0 if (($when < 0) or ($when > 0xFFFFFFFF)) { DATECALC_TIME_RANGE_ERROR('Timezone'); }
  0         0  
1019 0 0       0 if (DateCalc_timezone(\$year,\$month,\$day,
1020             \$hour,\$min,\$sec,
1021             \$dst,$when))
1022             {
1023 0         0 return($year,$month,$day,$hour,$min,$sec,$dst);
1024             }
1025 0         0 else { DATECALC_TIME_RANGE_ERROR('Timezone'); }
1026             }
1027              
1028             sub Date_to_Time
1029             {
1030 6 50   6 0 72 DATECALC_USAGE('Date_to_Time($year,$month,$day,$hour,$min,$sec)') unless (@_ == 6);
1031 6         8 my($year,$month,$day,$hour,$min,$sec) = @_;
1032 6         6 my($seconds);
1033 6 50       16 if (DateCalc_date2time(\$seconds, $year,$month,$day, $hour,$min,$sec))
1034             {
1035 6         15 return $seconds;
1036             }
1037 0         0 else { DATECALC_DATE_RANGE_ERROR('Date_to_Time'); }
1038             }
1039              
1040             sub Time_to_Date
1041             {
1042 8 50 66 8 0 81 DATECALC_USAGE('Time_to_Date([time])') unless ((@_ == 0) or (@_ == 1));
1043 8         58 my($seconds,$year,$month,$day,$hour,$min,$sec);
1044 8 100       19 if (@_ == 1) { $seconds = shift; }
  6         10  
1045 2         4 else { $seconds = time; }
1046 8 50 33     44 if (($seconds < 0) or ($seconds > 0xFFFFFFFF)) { DATECALC_TIME_RANGE_ERROR('Time_to_Date'); }
  0         0  
1047 8 50       24 if (DateCalc_time2date(\$year,\$month,\$day, \$hour,\$min,\$sec, $seconds))
1048             {
1049 8         54 return($year,$month,$day,$hour,$min,$sec);
1050             }
1051 0         0 else { DATECALC_TIME_RANGE_ERROR('Time_to_Date'); }
1052             }
1053              
1054             sub Easter_Sunday
1055             {
1056 910 50   910 0 5197 DATECALC_USAGE('Easter_Sunday($year)') unless (@_ == 1);
1057 910         1013 my($year) = shift;
1058 910         697 my($month,$day);
1059 910 100 66     2461 if (($year > 0) and DateCalc_easter_sunday(\$year,\$month,\$day))
1060             {
1061 908         1972 return($year,$month,$day);
1062             }
1063 2         6 else { DATECALC_YEAR_ERROR('Easter_Sunday'); }
1064             }
1065              
1066             sub Decode_Month
1067             {
1068 2109 50 66 2109 0 6425 DATECALC_USAGE('Decode_Month($string[,$lang])') unless ((@_ == 1) or (@_ == 2));
1069 2109         2126 my($string) = shift;
1070 2109   100     4147 my($lang) = shift || 0;
1071 2109         2968 return DateCalc_Decode_Month($string,$lang);
1072             }
1073              
1074             sub Decode_Day_of_Week
1075             {
1076 1187 50 66 1187 0 4695 DATECALC_USAGE('Decode_Day_of_Week($string[,$lang])') unless ((@_ == 1) or (@_ == 2));
1077 1187         1355 my($string) = shift;
1078 1187   100     2107 my($lang) = shift || 0;
1079 1187         2058 return DateCalc_Decode_Day_of_Week($string,$lang);
1080             }
1081              
1082             sub Decode_Language
1083             {
1084 10 50   10 0 76 DATECALC_USAGE('Decode_Language($string)') unless (@_ == 1);
1085 10         17 my($string) = shift;
1086 10         41 return DateCalc_Decode_Language($string);
1087             }
1088              
1089             sub Decode_Date_EU
1090             {
1091 14 50 66 14 0 163 DATECALC_USAGE('Decode_Date_EU($string[,$lang])') unless ((@_ == 1) or (@_ == 2));
1092 14         35 my($string) = shift;
1093 14   100     38 my($lang) = shift || 0;
1094 14         9 my($year,$month,$day);
1095 14 100       24 if (DateCalc_decode_date_eu($string,\$year,\$month,\$day,$lang))
1096             {
1097 13         40 return($year,$month,$day);
1098             }
1099 1         3 else { return(); }
1100             }
1101              
1102             sub Decode_Date_US
1103             {
1104 11 50 33 11 0 118 DATECALC_USAGE('Decode_Date_US($string[,$lang])') unless ((@_ == 1) or (@_ == 2));
1105 11         14 my($string) = shift;
1106 11   50     26 my($lang) = shift || 0;
1107 11         8 my($year,$month,$day);
1108 11 100       16 if (DateCalc_decode_date_us($string,\$year,\$month,\$day,$lang))
1109             {
1110 10         30 return($year,$month,$day);
1111             }
1112 1         4 else { return(); }
1113             }
1114              
1115             sub Fixed_Window
1116             {
1117 0 0   0 0 0 DATECALC_USAGE('Fixed_Window($year)') unless (@_ == 1);
1118 0         0 my($year) = shift;
1119 0         0 return DateCalc_Fixed_Window($year);
1120             }
1121              
1122             sub Moving_Window
1123             {
1124 84 50   84 0 158 DATECALC_USAGE('Moving_Window($year)') unless (@_ == 1);
1125 84         111 my($year) = shift;
1126 84         134 return DateCalc_Moving_Window($year);
1127             }
1128              
1129             sub Compress
1130             {
1131 6 50   6 0 49 DATECALC_USAGE('Compress($year,$month,$day)') unless (@_ == 3);
1132 6         42 my($year,$month,$day) = @_;
1133 6         9 return DateCalc_Compress($year,$month,$day);
1134             }
1135              
1136             sub Uncompress
1137             {
1138 5 50   5 0 56 DATECALC_USAGE('Uncompress($date)') unless (@_ == 1);
1139 5         32 my($date) = shift;
1140 5         3 my($century,$year,$month,$day);
1141 5 100       13 if (DateCalc_uncompress($date,\$century,\$year,\$month,\$day))
1142             {
1143 3         12 return($century,$year,$month,$day);
1144             }
1145 2         6 else { return(); }
1146             }
1147              
1148             sub check_compressed
1149             {
1150 5 50   5 0 39 DATECALC_USAGE('check_compressed($date)') unless (@_ == 1);
1151 5         24 my($date) = shift;
1152 5         7 return DateCalc_check_compressed($date);
1153             }
1154              
1155             sub Compressed_to_Text
1156             {
1157 20 50 66 20 0 148 DATECALC_USAGE('Compressed_to_Text($date[,$lang])') unless ((@_ == 1) or (@_ == 2));
1158 20         35 my($date) = shift;
1159 20   100     36 my($lang) = shift || 0;
1160 20         31 return DateCalc_Compressed_to_Text($date,$lang);
1161             }
1162              
1163             sub Date_to_Text
1164             {
1165 9 50 66 9 0 83 DATECALC_USAGE('Date_to_Text($year,$month,$day[,$lang])') unless ((@_ == 3) or (@_ == 4));
1166 9         23 my($year) = shift;
1167 9         10 my($month) = shift;
1168 9         10 my($day) = shift;
1169 9   100     18 my($lang) = shift || 0;
1170 9 50       15 if (DateCalc_check_date($year,$month,$day))
1171             {
1172 9         17 return DateCalc_Date_to_Text($year,$month,$day,$lang);
1173             }
1174 0         0 else { DATECALC_DATE_ERROR('Date_to_Text'); }
1175             }
1176              
1177             sub Date_to_Text_Long
1178             {
1179 55 50 66 55 0 343 DATECALC_USAGE('Date_to_Text_Long($year,$month,$day[,$lang])') unless ((@_ == 3) or (@_ == 4));
1180 55         71 my($year) = shift;
1181 55         46 my($month) = shift;
1182 55         50 my($day) = shift;
1183 55   100     116 my($lang) = shift || 0;
1184 55 50       73 if (DateCalc_check_date($year,$month,$day))
1185             {
1186 55         84 return DateCalc_Date_to_Text_Long($year,$month,$day,$lang);
1187             }
1188 0         0 else { DATECALC_DATE_ERROR('Date_to_Text_Long'); }
1189             }
1190              
1191             sub English_Ordinal
1192             {
1193 0 0   0 0 0 DATECALC_USAGE('English_Ordinal($number)') unless (@_ == 1);
1194 0         0 my($number) = shift;
1195 0         0 return DateCalc_English_Ordinal($number);
1196             }
1197              
1198             sub Calendar
1199             {
1200 24 50 33 24 0 201 DATECALC_USAGE('Calendar($year,$month[,$orthodox[,$lang]])') if ((@_ < 2) or (@_ > 4));
1201 24         43 my($year) = shift;
1202 24         17 my($month) = shift;
1203 24         14 my($orthodox,$lang);
1204 24 50       45 if (@_ == 2) { $orthodox = shift; $lang = shift; }
  0 50       0  
  0         0  
1205 24         18 elsif (@_ == 1) { $orthodox = shift; $lang = 0; }
  24         14  
1206 0         0 else { $orthodox = 0; $lang = 0; }
  0         0  
1207 24 50       35 if ($year > 0)
1208             {
1209 24 50 33     69 if (($month >= 1) and ($month <= 12))
1210             {
1211 24         30 return DateCalc_Calendar($year,$month,$orthodox,$lang);
1212             }
1213 0         0 else { DATECALC_MONTH_ERROR('Calendar'); }
1214             }
1215 0         0 else { DATECALC_YEAR_ERROR('Calendar'); }
1216             }
1217              
1218             sub Month_to_Text
1219             {
1220 134 50 66 134 0 1214 DATECALC_USAGE('Month_to_Text($month[,$lang])') unless ((@_ == 1) or (@_ == 2));
1221 134         143 my($month) = shift;
1222 134   100     213 my($lang) = shift || 0;
1223 134 100 66     335 if (($lang < 1) or ($lang > $DateCalc_LANGUAGES)) { $lang = $DateCalc_Language; }
  38         28  
1224 134 100 100     388 if (($month >= 1) and ($month <= 12))
1225             {
1226 119         382 return $DateCalc_Month_to_Text_[$lang][$month];
1227             }
1228 15         22 else { DATECALC_MONTH_ERROR('Month_to_Text'); }
1229             }
1230              
1231             sub Day_of_Week_to_Text
1232             {
1233 48 50 66 48 0 752 DATECALC_USAGE('Day_of_Week_to_Text($dow[,$lang])') unless ((@_ == 1) or (@_ == 2));
1234 48         65 my($dow) = shift;
1235 48   100     131 my($lang) = shift || 0;
1236 48 100 66     102 if (($lang < 1) or ($lang > $DateCalc_LANGUAGES)) { $lang = $DateCalc_Language; }
  33         28  
1237 48 100 100     120 if (($dow >= 1) and ($dow <= 7))
1238             {
1239 38         79 return $DateCalc_Day_of_Week_to_Text_[$lang][$dow];
1240             }
1241 10         13 else { DATECALC_DAYOFWEEK_ERROR('Day_of_Week_to_Text'); }
1242             }
1243              
1244             sub Day_of_Week_Abbreviation
1245             {
1246 0 0 0 0 0 0 DATECALC_USAGE('Day_of_Week_Abbreviation($dow[,$lang])') unless ((@_ == 1) or (@_ == 2));
1247 0         0 my($dow) = shift;
1248 0   0     0 my($lang) = shift || 0;
1249 0 0 0     0 if (($lang < 1) or ($lang > $DateCalc_LANGUAGES)) { $lang = $DateCalc_Language; }
  0         0  
1250 0 0 0     0 if (($dow >= 1) and ($dow <= 7))
1251             {
1252 0 0       0 if ($DateCalc_Day_of_Week_Abbreviation_[$lang][0] ne '')
1253             {
1254 0         0 return $DateCalc_Day_of_Week_Abbreviation_[$lang][$dow];
1255             }
1256             else
1257             {
1258 0         0 return substr($DateCalc_Day_of_Week_to_Text_[$lang][$dow],0,3);
1259             }
1260             }
1261 0         0 else { DATECALC_DAYOFWEEK_ERROR('Day_of_Week_Abbreviation'); }
1262             }
1263              
1264             sub Language_to_Text
1265             {
1266 20 50   20 0 45 DATECALC_USAGE('Language_to_Text($lang)') unless (@_ == 1);
1267 20         20 my($lang) = shift;
1268 20 100 66     61 if (($lang >= 1) and ($lang <= $DateCalc_LANGUAGES))
1269             {
1270 19         36 return $DateCalc_Language_to_Text_[$lang];
1271             }
1272 1         4 else { DATECALC_LANGUAGE_ERROR('Language_to_Text'); }
1273             }
1274              
1275             sub Language
1276             {
1277 425 50 66 425 0 1152 DATECALC_USAGE('Language([$lang])') unless ((@_ == 0) or (@_ == 1));
1278 425         432 my($retval) = $DateCalc_Language;
1279 425         348 my($lang);
1280 425 100       776 if (@_ == 1)
1281             {
1282 6   50     17 $lang = shift || 0;
1283 6 50 33     24 if (($lang >= 1) and ($lang <= $DateCalc_LANGUAGES))
1284             {
1285 6         8 $DateCalc_Language = $lang;
1286             }
1287 0         0 else { DATECALC_LANGUAGE_ERROR('Language'); }
1288             }
1289 425         702 return $retval;
1290             }
1291              
1292             sub Languages
1293             {
1294 169 50   169 0 269 DATECALC_USAGE('Languages()') unless (@_ == 0);
1295 169         531 return $DateCalc_LANGUAGES;
1296             }
1297              
1298             sub ISO_LC
1299             {
1300 0 0   0 0 0 DATECALC_USAGE('ISO_LC($string)') unless (@_ == 1);
1301 0         0 my($string) = shift;
1302 0         0 $string =~ s!([\x41-\x5A\xC0-\xD6\xD8-\xDE])!chr(ord($1)+0x20)!ge;
  0         0  
1303 0         0 return $string;
1304             }
1305              
1306             sub ISO_UC
1307             {
1308 253 50   253 0 351 DATECALC_USAGE('ISO_UC($string)') unless (@_ == 1);
1309 253         229 my($string) = shift;
1310 253         480 $string =~ s!([\x61-\x7A\xE0-\xF6\xF8-\xFE])!chr(ord($1)-0x20)!ge;
  2779         3641  
1311 253         466 return $string;
1312             }
1313              
1314             ##################
1315             ## ##
1316             ## DateCalc.c ##
1317             ## ##
1318             ##################
1319              
1320             ########################
1321             ## Private functions: ##
1322             ########################
1323              
1324             sub DateCalc_is_digit
1325             {
1326 240 100   240 0 675 return 1 if ($_[0] =~ /^[0-9]+$/);
1327 104         189 return 0;
1328             }
1329              
1330             sub DateCalc_is_alnum
1331             {
1332 122 100   122 0 397 return 1 if ($_[0] =~ /^[\x30-\x39\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF]+$/);
1333 34         64 return 0;
1334             }
1335              
1336             sub DateCalc_ISO_LC
1337             {
1338 0     0 0 0 my($char) = $_[0];
1339 0         0 $char =~ s!([\x41-\x5A\xC0-\xD6\xD8-\xDE])!chr(ord($1)+0x20)!ge;
  0         0  
1340 0         0 return $char;
1341             }
1342              
1343             sub DateCalc_ISO_UC
1344             {
1345 36967     36967 0 37308 my($char) = $_[0];
1346 36967         60607 $char =~ s!([\x61-\x7A\xE0-\xF6\xF8-\xFE])!chr(ord($1)-0x20)!ge;
  74237         99180  
1347 36967         103428 return $char;
1348             }
1349              
1350             sub DateCalc_ISO_UC_First
1351             {
1352 24     24 0 23 my($string) = $_[0];
1353 24         76 $string =~ s!([\x41-\x5A\xC0-\xD6\xD8-\xDE])!chr(ord($1)+0x20)!ge;
  24         65  
1354 24         40 $string =~ s!^([\x61-\x7A\xE0-\xF6\xF8-\xFE])!chr(ord($1)-0x20)!e;
  24         33  
1355 24         64 return $string;
1356             }
1357              
1358             sub DateCalc_Year_to_Days
1359             {
1360 41799     41799 0 33529 my($year) = $_[0];
1361 41799         34175 my($days) = $year * 365;
1362 41799         30792 $year >>= 2;
1363 41799         33574 $days += $year;
1364 41799         36271 $year = int($year / 25);
1365 41799         34372 $days -= $year;
1366 41799         30859 $days += ($year >> 2);
1367 41799         82525 return $days;
1368             }
1369              
1370             sub DateCalc_scan9
1371             { ## Mnemonic: COBOL "PIC 9" ##
1372 251     251 0 225 my($str,$buf,$len,$idx,$neg) = @_;
1373 251         180 $idx += $buf;
1374 251         191 $len += $buf;
1375 251 100 100     765 if (($idx >= 0) and ($idx < $len)) { return DateCalc_is_digit(substr($str,$idx,1)) ^ $neg; }
  240         323  
1376 11         20 return 0;
1377             }
1378              
1379             sub DateCalc_scanx
1380             { ## Mnemonic: COBOL "PIC X" ##
1381 138     138 0 163 my($str,$buf,$len,$idx,$neg) = @_;
1382 138         105 $idx += $buf;
1383 138         86 $len += $buf;
1384 138 100 66     407 if (($idx >= 0) and ($idx < $len)) { return DateCalc_is_alnum(substr($str,$idx,1)) ^ $neg; }
  122         154  
1385 16         30 return 0;
1386             }
1387              
1388             sub DateCalc_Center
1389             {
1390 24     24 0 23 my($_target,$source,$width) = @_;
1391 24         16 my($length,$blank);
1392 24         18 $length = length($source);
1393 24 50       37 $length = $width if ($length > $width);
1394 24         24 $blank = $width - $length;
1395 24         16 $blank >>= 1;
1396 24         26 $$_target .= ' ' x $blank;
1397 24         25 $$_target .= substr($source,0,$length);
1398 24         23 $$_target .= "\n";
1399             }
1400              
1401             sub DateCalc_Blank
1402             {
1403 646     646 0 465 my($_target,$count) = @_;
1404 646         684 $$_target .= ' ' x $count;
1405             }
1406              
1407             sub DateCalc_Newline
1408             {
1409 149     149 0 108 my($_target,$count) = @_;
1410 149         168 $$_target .= "\n" x $count;
1411             }
1412              
1413             sub DateCalc_Normalize_Time
1414             {
1415 305     305 0 248 my($_Dd,$_Dh,$_Dm,$_Ds) = @_;
1416 305         215 my($quot);
1417 305         254 $quot = int($$_Ds / 60);
1418 305         252 $$_Ds -= $quot * 60;
1419 305         227 $$_Dm += $quot;
1420 305         252 $quot = int($$_Dm / 60);
1421 305         216 $$_Dm -= $quot * 60;
1422 305         222 $$_Dh += $quot;
1423 305         246 $quot = int($$_Dh / 24);
1424 305         200 $$_Dh -= $quot * 24;
1425 305         343 $$_Dd += $quot;
1426             }
1427              
1428             ## Prevent overflow errors on systems ##
1429             ## with short "long"s (e.g. 32 bits): ##
1430              
1431             sub DateCalc_Normalize_Ranges
1432             {
1433 152     152 0 145 my($_Dd,$_Dh,$_Dm,$_Ds) = @_;
1434 152         117 my($quot);
1435 152         177 $quot = int($$_Dh / 24);
1436 152         152 $$_Dh -= $quot * 24;
1437 152         125 $$_Dd += $quot;
1438 152         132 $quot = int($$_Dm / 60);
1439 152         119 $$_Dm -= $quot * 60;
1440 152         121 $$_Dh += $quot;
1441 152         206 DateCalc_Normalize_Time($_Dd,$_Dh,$_Dm,$_Ds);
1442             }
1443              
1444             # $_Dh and $_Dm are assumed to be empty;
1445             # the whole time part must be in $_Ds:
1446              
1447             sub DateCalc_Normalize_Signs
1448             {
1449 34     34 0 35 my($_Dd,$_Dh,$_Dm,$_Ds) = @_;
1450 34         24 my($quot);
1451 34         45 $quot = int($$_Ds / 86400);
1452 34         32 $$_Ds -= $quot * 86400;
1453 34         30 $$_Dd += $quot;
1454 34 100       63 if ($$_Dd != 0)
1455             {
1456 31 100       46 if ($$_Dd > 0)
1457             {
1458 14 100       37 if ($$_Ds < 0)
1459             {
1460 7         7 $$_Ds += 86400;
1461 7         11 ${$_Dd}--;
  7         10  
1462             }
1463             }
1464             else
1465             {
1466 17 100       28 if ($$_Ds > 0)
1467             {
1468 5         7 $$_Ds -= 86400;
1469 5         3 ${$_Dd}++;
  5         5  
1470             }
1471             }
1472             }
1473 34         32 $$_Dh = 0;
1474 34         33 $$_Dm = 0;
1475 34 50       54 if ($$_Ds != 0) { DateCalc_Normalize_Time($_Dd,$_Dh,$_Dm,$_Ds); }
  34         48  
1476             }
1477              
1478             sub DateCalc_Normalize_DHMS
1479             {
1480 14     14 0 14 my($_Dd,$_Dh,$_Dm,$_Ds) = @_;
1481 14         18 DateCalc_Normalize_Ranges($_Dd,$_Dh,$_Dm,$_Ds);
1482 14         15 $$_Ds += (($$_Dh * 60) + $$_Dm) * 60;
1483 14         17 DateCalc_Normalize_Signs($_Dd,$_Dh,$_Dm,$_Ds);
1484             }
1485              
1486             #######################
1487             ## Public functions: ##
1488             #######################
1489              
1490             sub DateCalc_leap_year
1491             {
1492 91840     91840 0 75331 my($year) = $_[0];
1493 91840         57613 my($yy);
1494 91840   66     584963 return( (($year & 0x03) == 0) and
1495             ( ((($yy = int($year / 100)) * 100) != $year) or
1496             (($yy & 0x03) == 0) ) );
1497             }
1498              
1499             sub DateCalc_check_date
1500             {
1501 49407     49407 0 37023 my($year,$month,$day) = @_;
1502 49407 100 100     298213 return 1 if
      66        
      100        
      100        
1503             (($year >= 1) and
1504             ($month >= 1) and ($month <= 12) and
1505             ($day >= 1) and
1506             ($day <= $DateCalc_Days_in_Month_[DateCalc_leap_year($year)][$month]));
1507 47         126 return 0;
1508             }
1509              
1510             sub DateCalc_check_time
1511             {
1512 1021     1021 0 847 my($hour,$min,$sec) = @_;
1513 1021 100 100     10259 return 1 if
      100        
      100        
      100        
      100        
1514             (($hour >= 0) and ($min >= 0) and ($sec >= 0) and
1515             ($hour < 24) and ($min < 60) and ($sec < 60));
1516 17         35 return 0;
1517             }
1518              
1519             sub DateCalc_check_business_date
1520             {
1521 629     629 0 622 my($year,$week,$dow) = @_;
1522 629 50 33     2315 return 1 if
      33        
      33        
      33        
1523             (($year >= 1) and
1524             ($week >= 1) and ($week <= DateCalc_Weeks_in_Year($year)) and
1525             ($dow >= 1) and ($dow <= 7));
1526 0         0 return 0;
1527             }
1528              
1529             sub DateCalc_Day_of_Year
1530             {
1531 0     0 0 0 my($year,$month,$day) = @_;
1532 0         0 my($leap);
1533 0 0 0     0 if (($year >= 1) and
      0        
      0        
      0        
1534             ($month >= 1) and ($month <= 12) and
1535             ($day >= 1) and
1536             ($day <= $DateCalc_Days_in_Month_[($leap=DateCalc_leap_year($year))][$month]))
1537             {
1538 0         0 return $DateCalc_Days_in_Year_[$leap][$month] + $day;
1539             }
1540 0         0 return 0;
1541             }
1542              
1543             sub DateCalc_Date_to_Days
1544             {
1545 37448     37448 0 30899 my($year,$month,$day) = @_;
1546 37448         25892 my($leap);
1547 37448 100 66     232814 if (($year >= 1) and
      66        
      33        
      66        
1548             ($month >= 1) and ($month <= 12) and
1549             ($day >= 1) and
1550             ($day <= $DateCalc_Days_in_Month_[($leap=DateCalc_leap_year($year))][$month]))
1551             {
1552 37445         46910 return DateCalc_Year_to_Days(--$year)
1553             + $DateCalc_Days_in_Year_[$leap][$month]
1554             + $day;
1555             }
1556 3         7 return 0;
1557             }
1558              
1559             sub DateCalc_Day_of_Week
1560             {
1561 6535     6535 0 6041 my($year,$month,$day) = @_;
1562 6535         4613 my($days);
1563 6535         7333 $days = DateCalc_Date_to_Days($year,$month,$day);
1564 6535 100       10865 if ($days > 0)
1565             {
1566 6534         4619 $days--;
1567 6534         5479 $days %= 7;
1568 6534         5683 $days++;
1569             }
1570 6535         10561 return $days;
1571             }
1572              
1573             sub DateCalc_Weeks_in_Year
1574             {
1575 1282     1282 0 1127 my($year) = $_[0];
1576 1282 100 100     1529 if ((DateCalc_Day_of_Week($year,1,1) == 4) or
1577             (DateCalc_Day_of_Week($year,12,31) == 4))
1578 305         1429 { return 53; }
1579             else
1580 977         4436 { return 52; }
1581             }
1582              
1583             sub DateCalc_Week_Number
1584             {
1585 636     636 0 586 my($year,$month,$day) = @_;
1586 636         497 my($first,$week);
1587 636         827 $first = DateCalc_Day_of_Week($year,1,1) - 1;
1588 636         1056 $week = int((DateCalc_Delta_Days($year,1,1, $year,$month,$day) + $first) / 7);
1589 636 100       1188 if ($first < 4) { return ++$week; }
  351         494  
1590 285         437 else { return $week; }
1591             }
1592              
1593             sub DateCalc_week_of_year
1594             {
1595 638     638 0 609 my($_week,$_year,$month,$day) = @_;
1596 638 100       893 if (DateCalc_check_date($$_year,$month,$day))
1597             {
1598 636         955 $$_week = DateCalc_Week_Number($$_year,$month,$day);
1599 636 100       1250 if ($$_week == 0) { $$_week = DateCalc_Weeks_in_Year(--${$_year}); }
  37 100       36  
  37         69  
1600             elsif ($$_week > DateCalc_Weeks_in_Year($$_year))
1601             {
1602 31         29 $$_week = 1;
1603 31         22 ${$_year}++;
  31         31  
1604             }
1605 636         1327 return 1;
1606             }
1607 2         3 return 0;
1608             }
1609              
1610             sub DateCalc_monday_of_week
1611             {
1612 11     11 0 13 my($week,$_year,$_month,$_day) = @_;
1613 11         7 my($first);
1614 11         9 $$_month = $$_day = 1;
1615 11         17 $first = DateCalc_Day_of_Week($$_year,1,1) - 1;
1616 11 100       19 $week-- if ($first < 4);
1617 11         23 return DateCalc_add_delta_days($_year,$_month,$_day, ($week * 7 - $first));
1618             }
1619              
1620             sub DateCalc_nth_weekday_of_month_year
1621             {
1622 1323     1323 0 1662 my($_year,$_month,$_day,$dow,$n) = @_;
1623 1323         1423 my($mm) = $$_month;
1624 1323         1074 my($first,$delta);
1625 1323         1170 $$_day = 1;
1626 1323 50 33     14697 return 0 if
      33        
      33        
      33        
      33        
      33        
1627             (($$_year < 1) or
1628             ($mm < 1) or ($mm > 12) or
1629             ($dow < 1) or ($dow > 7) or
1630             ($n < 1) or ($n > 5));
1631 1323         1822 $first = DateCalc_Day_of_Week($$_year,$mm,1);
1632 1323 100       2012 $dow += 7 if ($dow < $first);
1633 1323         988 $delta = $dow - $first;
1634 1323         1543 $delta += --$n * 7;
1635 1323 100 66     2192 return 1 if (DateCalc_add_delta_days($_year,$_month,$_day,$delta) and ($$_month == $mm));
1636 71         185 return 0;
1637             }
1638              
1639             sub DateCalc_standard_to_business
1640             {
1641 629     629 0 674 my($_year,$_week,$_dow,$month,$day) = @_;
1642 629         702 my($yy) = $$_year;
1643              
1644 629 50       891 if (DateCalc_week_of_year($_week,$_year,$month,$day))
1645             {
1646 629         939 $$_dow = DateCalc_Day_of_Week($yy,$month,$day);
1647 629         1213 return 1;
1648             }
1649 0         0 return 0;
1650             }
1651              
1652             sub DateCalc_business_to_standard
1653             {
1654 629     629 0 681 my($_year,$_month,$_day,$week,$dow) = @_;
1655 629         473 my($first,$delta);
1656 629 50       842 if (DateCalc_check_business_date($$_year,$week,$dow))
1657             {
1658 629         649 $$_month = $$_day = 1;
1659 629         848 $first = DateCalc_Day_of_Week($$_year,1,1);
1660 629 100       1007 $week++ if ($first > 4);
1661 629         657 $delta = --$week * 7 + $dow - $first;
1662 629         892 return DateCalc_add_delta_days($_year,$_month,$_day,$delta);
1663             }
1664 0         0 return 0;
1665             }
1666              
1667             sub DateCalc_Delta_Days
1668             {
1669 665     665 0 1081 return DateCalc_Date_to_Days(@_[3..5]) -
1670             DateCalc_Date_to_Days(@_[0..2]);
1671             }
1672              
1673             sub DateCalc_delta_hms
1674             {
1675 20     20 0 28 my($_Dd,$_Dh,$_Dm,$_Ds,$hour1,$min1,$sec1,$hour2,$min2,$sec2) = @_;
1676 20 50 33     27 if (DateCalc_check_time($hour1,$min1,$sec1) and
1677             DateCalc_check_time($hour2,$min2,$sec2))
1678             {
1679 20         45 $$_Ds = (((($hour2 * 60) + $min2) * 60) + $sec2) -
1680             (((($hour1 * 60) + $min1) * 60) + $sec1);
1681 20         33 DateCalc_Normalize_Signs($_Dd,$_Dh,$_Dm,$_Ds);
1682 20         45 return 1;
1683             }
1684 0         0 return 0;
1685             }
1686              
1687             sub DateCalc_delta_dhms
1688             {
1689 17     17 0 23 my($_Dd,$_Dh,$_Dm,$_Ds,$year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2) = @_;
1690 17         24 $$_Dd = $$_Dh = $$_Dm = $$_Ds = 0;
1691 17 50 33     21 if (DateCalc_check_date($year1,$month1,$day1) and
1692             DateCalc_check_date($year2,$month2,$day2))
1693             {
1694 17         35 $$_Dd = DateCalc_Delta_Days($year1,$month1,$day1, $year2,$month2,$day2);
1695 17         43 return DateCalc_delta_hms($_Dd,$_Dh,$_Dm,$_Ds, $hour1,$min1,$sec1, $hour2,$min2,$sec2);
1696             }
1697 0         0 return 0;
1698             }
1699              
1700             sub DateCalc_delta_ymd
1701             {
1702 8     8 0 9 my($_year1,$_month1,$_day1,$year2,$month2,$day2) = @_;
1703 8 50 33     14 if (DateCalc_check_date($$_year1,$$_month1,$$_day1) and
1704             DateCalc_check_date( $year2, $month2, $day2))
1705             {
1706 8         9 $$_day1 = $day2 - $$_day1;
1707 8         10 $$_month1 = $month2 - $$_month1;
1708 8         13 $$_year1 = $year2 - $$_year1;
1709 8         13 return 1;
1710             }
1711 0         0 return 0;
1712             }
1713              
1714             sub DateCalc_delta_ymdhms
1715             {
1716 3     3 0 6 my($_D_y,$_D_m,$_D_d,$_Dh,$_Dm,$_Ds,$year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2) = @_;
1717 3 50       8 return 0 unless (DateCalc_delta_ymd(\$year1,\$month1,\$day1, $year2,$month2,$day2));
1718 3         4 $$_D_d = $day1;
1719 3 50       8 return 0 unless (DateCalc_delta_hms($_D_d,$_Dh,$_Dm,$_Ds, $hour1,$min1,$sec1, $hour2,$min2,$sec2));
1720 3         3 $$_D_y = $year1;
1721 3         4 $$_D_m = $month1;
1722 3         5 return 1;
1723             }
1724              
1725             sub DateCalc_norm_delta_ymd
1726             {
1727 82     82 0 82 my($_year1,$_month1,$_day1,$year2,$month2,$day2) = @_;
1728 82         64 my($Dy) = 0;
1729 82         67 my($Dm) = 0;
1730 82         63 my($Dd) = 0;
1731 82         72 my($d2,$ty,$tm,$td);
1732              
1733 82 100 100     106 if (DateCalc_check_date($$_year1,$$_month1,$$_day1) and
1734             DateCalc_check_date( $year2, $month2, $day2))
1735             {
1736 74         96 $d2 = DateCalc_Date_to_Days( $year2, $month2, $day2);
1737 74         112 $Dd = $d2-DateCalc_Date_to_Days($$_year1,$$_month1,$$_day1);
1738 74 100 100     220 if (($Dd < -30) or ($Dd > 30))
1739             {
1740 50         47 $Dy = ($year2 - $$_year1);
1741 50         44 $Dm = ($month2 - $$_month1);
1742 50 50       38 $ty=$$_year1; $tm=$$_month1; $td=$$_day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td);
  50         35  
  50         45  
  50         78  
  50         66  
1743 50 100 100     323 unless ((($Dy >= 0) and ($Dm >= 0) and ($Dd >= 0)) or
      100        
      100        
      100        
      66        
1744             (($Dy <= 0) and ($Dm <= 0) and ($Dd <= 0)))
1745             {
1746 33 100 100     181 if (($Dy < 0) and ($Dm > 0)) { $Dy++; $Dm -= 12; }
  7 100 100     7  
  7         9  
1747 7         7 elsif (($Dy > 0) and ($Dm < 0)) { $Dy--; $Dm += 12; }
  7         9  
1748 33 50 100     139 if (($Dm < 0) and ($Dd > 0)) { $Dm++; $ty=$$_year1; $tm=$$_month1; $td=$$_day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  4 100 100     7  
  4 100       6  
  4         4  
  4         3  
  4         7  
  4         7  
1749 5 50       7 elsif (($Dm > 0) and ($Dd < 0)) { $Dm--; $ty=$$_year1; $tm=$$_month1; $td=$$_day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  5         7  
  5         10  
  5         7  
  5         9  
  5         8  
1750 33 100 100     135 if (($Dy < 0) and ($Dd > 0)) { $Dy++; $Dm -= 12; }
  8 100 100     8  
  8         33  
1751 6         7 elsif (($Dy > 0) and ($Dd < 0)) { $Dy--; $Dm += 12; }
  6         8  
1752 33 50 100     138 if (($Dm < 0) and ($Dd > 0)) { $Dm++; $ty=$$_year1; $tm=$$_month1; $td=$$_day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  8 100 100     8  
  8 100       8  
  8         7  
  8         9  
  8         13  
  8         18  
1753 6 50       5 elsif (($Dm > 0) and ($Dd < 0)) { $Dm--; $ty=$$_year1; $tm=$$_month1; $td=$$_day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  6         8  
  6         8  
  6         6  
  6         20  
  6         10  
1754             }
1755             }
1756 74         72 $$_year1 = $Dy;
1757 74         58 $$_month1 = $Dm;
1758 74         78 $$_day1 = $Dd;
1759 74         127 return 1;
1760             }
1761 8         14 return 0;
1762             }
1763              
1764             sub DateCalc_norm_delta_ymdhms
1765             {
1766 80     80 0 116 my($_D_y,$_D_m,$_D_d,$_Dhh,$_Dmm,$_Dss,$year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2) = @_;
1767 80         63 my($Dy) = 0;
1768 80         63 my($Dm) = 0;
1769 80         62 my($Dd) = 0;
1770 80         55 my($d2,$ty,$tm,$td,$hh,$mm,$ss);
1771 80 50 33     90 if (DateCalc_check_date($year1,$month1,$day1) and
      33        
      33        
1772             DateCalc_check_time($hour1,$min1, $sec1) and
1773             DateCalc_check_date($year2,$month2,$day2) and
1774             DateCalc_check_time($hour1,$min2, $sec2))
1775             {
1776 80         116 $ss = ( ($hour2-$hour1) * 60 + ($min2-$min1) ) * 60 + ($sec2-$sec1);
1777 80         110 $d2 = DateCalc_Date_to_Days($year2,$month2,$day2);
1778 80         118 $Dd = $d2-DateCalc_Date_to_Days($year1,$month1,$day1);
1779 80 100 100     230 if (($Dd < -30) or ($Dd > 30))
1780             {
1781 52         48 $Dy = $year2 - $year1;
1782 52         40 $Dm = $month2 - $month1;
1783 52 50       30 $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td);
  52         42  
  52         36  
  52         90  
  52         68  
1784 52 100 100     440 unless ((($Dy >= 0) and ($Dm >= 0) and ($Dd >= 0) and ($ss >= 0)) or
      100        
      100        
      100        
      100        
      100        
      66        
1785             (($Dy <= 0) and ($Dm <= 0) and ($Dd <= 0) and ($ss <= 0)))
1786             {
1787 46 100 100     193 if (($Dy < 0) and ($Dm > 0)) { $Dy++; $Dm -= 12; }
  6 100 100     5  
  6         21  
1788 6         5 elsif (($Dy > 0) and ($Dm < 0)) { $Dy--; $Dm += 12; }
  6         7  
1789 46 50 100     206 if (($Dm < 0) and ($Dd > 0)) { $Dm++; $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  4 100 100     4  
  4 100       5  
  4         5  
  4         4  
  4         11  
  4         7  
1790 4 50       6 elsif (($Dm > 0) and ($Dd < 0)) { $Dm--; $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  4         6  
  4         3  
  4         5  
  4         14  
  4         8  
1791 46 100 100     174 if (($Dy < 0) and ($Dd > 0)) { $Dy++; $Dm -= 12; }
  10 100 100     8  
  10         10  
1792 6         8 elsif (($Dy > 0) and ($Dd < 0)) { $Dy--; $Dm += 12; }
  6         8  
1793 46 50 100     189 if (($Dm < 0) and ($Dd > 0)) { $Dm++; $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  10 100 100     12  
  10 100       7  
  10         6  
  10         9  
  10         19  
  10         14  
1794 6 50       7 elsif (($Dm > 0) and ($Dd < 0)) { $Dm--; $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  6         5  
  6         4  
  6         20  
  6         11  
  6         11  
1795 46 100 100     183 if (($Dd < 0) and ($ss > 0)) { $Dd++; $ss -= 86400; }
  14 100 100     13  
  14         17  
1796 14         13 elsif (($Dd > 0) and ($ss < 0)) { $Dd--; $ss += 86400; }
  14         18  
1797 46 50 100     194 if (($Dm < 0) and ($ss > 0)) { $Dm++; $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  4 100 100     6  
  4 100       4  
  4         4  
  4         3  
  4         9  
  4         7  
1798 2 50       4 elsif (($Dm > 0) and ($ss < 0)) { $Dm--; $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  2         7  
  2         3  
  2         2  
  2         7  
  2         6  
1799 46 50 66     177 if (($Dy < 0) and ($ss > 0)) { $Dy++; $Dm -= 12; }
  0 100 100     0  
  0         0  
1800 2         4 elsif (($Dy > 0) and ($ss < 0)) { $Dy--; $Dm += 12; }
  2         3  
1801 46 0 66     217 if (($Dm < 0) and ($ss > 0)) { $Dm++; $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  0 50 100     0  
  0 100       0  
  0         0  
  0         0  
  0         0  
  0         0  
1802 2 50       3 elsif (($Dm > 0) and ($ss < 0)) { $Dm--; $ty=$year1; $tm=$month1; $td=$day1; return 0 unless (DateCalc_add_delta_ym(\$ty,\$tm,\$td,$Dy,$Dm)); $Dd=$d2-DateCalc_Date_to_Days($ty,$tm,$td); }
  2         3  
  2         3  
  2         2  
  2         6  
  2         7  
1803 46 100 100     179 if (($Dd < 0) and ($ss > 0)) { $Dd++; $ss -= 86400; }
  4 100 100     5  
  4         5  
1804 4         4 elsif (($Dd > 0) and ($ss < 0)) { $Dd--; $ss += 86400; }
  4         5  
1805             }
1806             }
1807             else
1808             {
1809 28 100 100     171 if (($Dd < 0) and ($ss > 0)) { $Dd++; $ss -= 86400; }
  12 100 100     13  
  12         12  
1810 12         11 elsif (($Dd > 0) and ($ss < 0)) { $Dd--; $ss += 86400; }
  12         11  
1811             }
1812 80         78 $mm = int( $ss / 60 );
1813 80         75 $ss -= $mm * 60;
1814 80         68 $hh = int( $mm / 60 );
1815 80         69 $mm -= $hh * 60;
1816 80         64 $$_D_y = $Dy;
1817 80         68 $$_D_m = $Dm;
1818 80         53 $$_D_d = $Dd;
1819 80         67 $$_Dhh = $hh;
1820 80         55 $$_Dmm = $mm;
1821 80         58 $$_Dss = $ss;
1822 80         144 return 1;
1823             }
1824 0         0 return 0;
1825             }
1826              
1827             sub DateCalc_add_delta_days
1828             {
1829 4464     4464 0 4555 my($_year,$_month,$_day,$Dd) = @_;
1830 4464         3337 my($days,$leap);
1831 4464 100 100     6002 if ((($days = DateCalc_Date_to_Days($$_year,$$_month,$$_day)) > 0) and
1832             (($days += $Dd) > 0))
1833             {
1834 4459 100       7285 if ($Dd != 0)
1835             {
1836 4350         4889 $$_year = int( $days / 365.2425 );
1837 4350         5234 $$_day = $days - DateCalc_Year_to_Days($$_year);
1838 4350 100       6291 if ($$_day < 1)
1839             {
1840 4         6 $$_day = $days - DateCalc_Year_to_Days($$_year-1);
1841             }
1842 4346         2995 else { ${$_year}++; }
  4346         4752  
1843 4350         5318 $leap = DateCalc_leap_year($$_year);
1844 4350 50       8100 if ($$_day > $DateCalc_Days_in_Year_[$leap][13])
1845             {
1846 0         0 $$_day -= $DateCalc_Days_in_Year_[$leap][13];
1847 0         0 $leap = DateCalc_leap_year(++${$_year});
  0         0  
1848             }
1849 4350         7876 for ( $$_month = 12; $$_month >= 1; ${$_month}-- )
  26912         37745  
1850             {
1851 31262 100       43762 if ($$_day > $DateCalc_Days_in_Year_[$leap][$$_month])
1852             {
1853 4350         4102 $$_day -= $DateCalc_Days_in_Year_[$leap][$$_month];
1854 4350         4500 last;
1855             }
1856             }
1857             }
1858 4459         11992 return 1;
1859             }
1860 5         11 return 0;
1861             }
1862              
1863             sub DateCalc_add_delta_dhms
1864             {
1865 138     138 0 191 my($_year,$_month,$_day,$_hour,$_min,$_sec,$Dd,$Dh,$Dm,$Ds) = @_;
1866 138 50 33     173 if (DateCalc_check_date($$_year,$$_month,$$_day) and
1867             DateCalc_check_time($$_hour,$$_min, $$_sec))
1868             {
1869 138         278 DateCalc_Normalize_Ranges(\$Dd,\$Dh,\$Dm,\$Ds);
1870 138         283 $Ds += (((($$_hour * 60) + $$_min) * 60) + $$_sec) +
1871             ((( $Dh * 60) + $Dm) * 60);
1872 138         226 while ($Ds < 0)
1873             {
1874 51         53 $Ds += 86400;
1875 51         83 $Dd--;
1876             }
1877 138 100       186 if ($Ds > 0)
1878             {
1879 119         154 $Dh = 0;
1880 119         83 $Dm = 0;
1881 119         179 DateCalc_Normalize_Time(\$Dd,\$Dh,\$Dm,\$Ds);
1882 119         136 $$_hour = $Dh;
1883 119         91 $$_min = $Dm;
1884 119         97 $$_sec = $Ds;
1885             }
1886 19         22 else { $$_hour = $$_min = $$_sec = 0; }
1887 138         181 return DateCalc_add_delta_days($_year,$_month,$_day,$Dd);
1888             }
1889 0         0 return 0;
1890             }
1891              
1892             sub DateCalc_add_year_month
1893             {
1894 461     461 0 419 my($_year,$_month,$Dy,$Dm) = @_;
1895 461         310 my($quot);
1896 461 50 33     2002 return 0 if (($$_year < 1) or ($$_month < 1) or ($$_month > 12));
      33        
1897 461 100       608 if ($Dm != 0)
1898             {
1899 245         220 $Dm += $$_month - 1;
1900 245         280 $quot = int($Dm / 12);
1901 245         198 $Dm -= $quot * 12;
1902 245 100       340 if ($Dm < 0)
1903             {
1904 69         54 $Dm += 12;
1905 69         55 $quot--;
1906             }
1907 245         205 $$_month = $Dm + 1;
1908 245         201 $Dy += $quot;
1909             }
1910 461 100       623 if ($Dy != 0)
1911             {
1912 271         235 $$_year += $Dy;
1913             }
1914 461 100       655 return 0 if ($$_year < 1);
1915 459         775 return 1;
1916             }
1917              
1918             sub DateCalc_add_delta_ym
1919             {
1920 407     407 0 418 my($_year,$_month,$_day,$Dy,$Dm) = @_;
1921 407         264 my($Dd);
1922 407 50       470 return 0 unless (DateCalc_check_date($$_year,$$_month,$$_day));
1923 407 50       654 return 0 unless (DateCalc_add_year_month($_year,$_month,$Dy,$Dm));
1924 407 100       525 if ($$_day > ($Dd = $DateCalc_Days_in_Month_[DateCalc_leap_year($$_year)][$$_month]))
1925             {
1926 50         41 $$_day = $Dd;
1927             }
1928 407         755 return 1;
1929             }
1930              
1931             sub DateCalc_add_delta_ymd
1932             {
1933 53     53 0 51 my($_year,$_month,$_day,$Dy,$Dm,$Dd) = @_;
1934 53 100       72 return 0 unless (DateCalc_check_date($$_year,$$_month,$$_day));
1935 48 100       79 return 0 unless (DateCalc_add_year_month($_year,$_month,$Dy,$Dm));
1936 46         49 $Dd += $$_day - 1;
1937 46         39 $$_day = 1;
1938 46         58 return DateCalc_add_delta_days($_year,$_month,$_day,$Dd);
1939             }
1940              
1941             sub DateCalc_add_delta_ymdhms
1942             {
1943 6     6 0 14 my($_year,$_month,$_day,$_hour,$_min,$_sec,$D_y,$D_m,$D_d,$Dh,$Dm,$Ds) = @_;
1944 6 50 33     11 return 0 unless (DateCalc_check_date($$_year,$$_month,$$_day) and DateCalc_check_time($$_hour,$$_min,$$_sec));
1945 6 50       15 return 0 unless (DateCalc_add_year_month($_year,$_month,$D_y,$D_m));
1946 6         7 $D_d += $$_day - 1;
1947 6         9 $$_day = 1;
1948 6         12 return DateCalc_add_delta_dhms($_year,$_month,$_day,$_hour,$_min,$_sec,$D_d,$Dh,$Dm,$Ds);
1949             }
1950              
1951             sub DateCalc_add_norm_delta_ymd
1952             {
1953 96     96 0 104 my($_year,$_month,$_day,$Dy,$Dm,$Dd) = @_;
1954 96 50       129 return 0 unless (DateCalc_add_delta_ym($_year,$_month,$_day,$Dy,$Dm));
1955 96         138 return DateCalc_add_delta_days($_year,$_month,$_day,$Dd);
1956             }
1957              
1958             sub DateCalc_add_norm_delta_ymdhms
1959             {
1960 80     80 0 91 my($_year,$_month,$_day,$_hour,$_min,$_sec,$D_y,$D_m,$D_d,$Dh,$Dm,$Ds) = @_;
1961 80 50       110 return 0 unless (DateCalc_add_delta_ym($_year,$_month,$_day,$D_y,$D_m));
1962 80         113 return DateCalc_add_delta_dhms($_year,$_month,$_day,$_hour,$_min,$_sec,$D_d,$Dh,$Dm,$Ds);
1963             }
1964              
1965             sub DateCalc_system_clock
1966             {
1967 1     1 0 3 my($_year,$_month,$_day,$_hour,$_min,$_sec,$_doy,$_dow,$_dst,$gmt) = @_;
1968 1         5 my($seconds) = time();
1969 1 50       5 if ($seconds >= 0)
1970             {
1971 1         2 $$_dst = 0;
1972 1 50       4 if ($gmt) { ($$_sec,$$_min,$$_hour,$$_day,$$_month,$$_year,$$_dow,$$_doy) = gmtime($seconds); }
  0         0  
1973 1         117 else { ($$_sec,$$_min,$$_hour,$$_day,$$_month,$$_year,$$_dow,$$_doy,$$_dst) = localtime($seconds); }
1974 1         3 ${$_year} += 1900;
  1         2  
1975 1         1 ${$_month}++;
  1         2  
1976 1 50       1 ${$_dow} = 7 if (${$_dow} == 0);
  0         0  
  1         5  
1977 1         1 ${$_doy}++;
  1         2  
1978 1 50       3 if ($$_dst != 0)
1979             {
1980 0 0       0 if ($$_dst < 0) { $$_dst = -1; }
  0         0  
1981 0         0 else { $$_dst = 1; }
1982             }
1983 1         4 return 1;
1984             }
1985 0         0 return 0;
1986             }
1987              
1988             sub DateCalc_gmtime
1989             {
1990 2     2 0 4 my($_year,$_month,$_day,$_hour,$_min,$_sec,$_doy,$_dow,$_dst,$seconds) = @_;
1991 2 50       7 if ($seconds >= 0)
1992             {
1993 2         5 $$_dst = 0;
1994 2         40 ($$_sec,$$_min,$$_hour,$$_day,$$_month,$$_year,$$_dow,$$_doy) = gmtime($seconds);
1995 2         5 ${$_year} += 1900;
  2         5  
1996 2         4 ${$_month}++;
  2         3  
1997 2 50       4 ${$_dow} = 7 if (${$_dow} == 0);
  0         0  
  2         7  
1998 2         2 ${$_doy}++;
  2         3  
1999 2         9 return 1;
2000             }
2001 0         0 return 0;
2002             }
2003              
2004             sub DateCalc_localtime
2005             {
2006 2     2 0 5 my($_year,$_month,$_day,$_hour,$_min,$_sec,$_doy,$_dow,$_dst,$seconds) = @_;
2007 2 50       12 if ($seconds >= 0)
2008             {
2009 2         296 ($$_sec,$$_min,$$_hour,$$_day,$$_month,$$_year,$$_dow,$$_doy,$$_dst) = localtime($seconds);
2010 2         7 ${$_year} += 1900;
  2         5  
2011 2         5 ${$_month}++;
  2         3  
2012 2 50       3 ${$_dow} = 7 if (${$_dow} == 0);
  0         0  
  2         10  
2013 2         3 ${$_doy}++;
  2         3  
2014 2 50       7 if ($$_dst != 0)
2015             {
2016 0 0       0 if ($$_dst < 0) { $$_dst = -1; }
  0         0  
2017 0         0 else { $$_dst = 1; }
2018             }
2019 2         14 return 1;
2020             }
2021 0         0 return 0;
2022             }
2023              
2024             ## MacOS (Classic): ##
2025             ## <695056.0> = Fri 1-Jan-1904 00:00:00 (time=0x00000000) ##
2026             ## <744766.23295> = Mon 6-Feb-2040 06:28:15 (time=0xFFFFFFFF) ##
2027              
2028             ## Unix: ##
2029             ## <719163.0> = Thu 1-Jan-1970 00:00:00 (time=0x00000000) ##
2030             ## <744018.11647> = Tue 19-Jan-2038 03:14:07 (time=0x7FFFFFFF) ##
2031              
2032             sub DateCalc_mktime
2033             {
2034 2     2 0 24 my($_seconds,$year,$month,$day,$hour,$min,$sec,$doy,$dow,$dst) = @_;
2035 2         4 $$_seconds = 0;
2036 2 50       10 if ($^O eq 'MacOS')
2037             {
2038 0 0 0     0 return 0 if
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
2039             (
2040             ($year < 1904) or ($year > 2040) or
2041             ($month < 1) or ($month > 12) or
2042             ($day < 1) or ($day > 31) or
2043             ($hour < 0) or ($hour > 23) or
2044             ($min < 0) or ($min > 59) or
2045             ($sec < 0) or ($sec > 59)
2046             );
2047 0 0 0     0 return 0 if
      0        
2048             (
2049             ($year == 2040) and ( ($month > 2) or
2050             ( ($month == 2) and ( ($day > 6) or
2051             ( ($day == 6) and ( ($hour > 6) or
2052             ( ($hour == 6) and ( ($min > 28) or
2053             ( ($min == 28) and ($sec > 15) ) )))))))
2054             );
2055             }
2056             else
2057             {
2058 2 50 33     84 return 0 if
      33        
      33        
      33        
      33        
      33        
      33        
      33        
      33        
      33        
      33        
2059             (
2060             ($year < 1970) or ($year > 2038) or
2061             ($month < 1) or ($month > 12) or
2062             ($day < 1) or ($day > 31) or
2063             ($hour < 0) or ($hour > 23) or
2064             ($min < 0) or ($min > 59) or
2065             ($sec < 0) or ($sec > 59)
2066             );
2067 2 0 0     8 return 0 if
      33        
2068             (
2069             ($year == 2038) and ( ($month > 1) or
2070             ( ($month == 1) and ( ($day > 19) or
2071             ( ($day == 19) and ( ($hour > 3) or
2072             ( ($hour == 3) and ( ($min > 14) or
2073             ( ($min == 14) and ($sec > 7) ) )))))))
2074             );
2075             }
2076 2         3 $year -= 1900;
2077 2         2 $month--;
2078 2 50       61 if ($doy <= 0) { $doy = -1; }
  2         6  
2079 0         0 else { $doy--; }
2080 2 50       6 if ($dow <= 0) { $dow = -1; }
  2 0       3  
2081 0         0 elsif ($dow == 7) { $dow = 0; }
2082 2 50       9 if ($dst != 0)
2083             {
2084 2 50       5 if ($dst < 0) { $dst = -1; }
  2         4  
2085 0         0 else { $dst = 1; }
2086             }
2087 2   50     77 $$_seconds = POSIX::mktime($sec,$min,$hour,$day,$month,$year,$doy,$dow,$dst) || 0;
2088 2 50       12 return 1 if ($$_seconds >= 0);
2089 0         0 return 0;
2090             }
2091              
2092             sub DateCalc_timezone
2093             {
2094 0     0 0 0 my($_year,$_month,$_day,$_hour,$_min,$_sec,$_dst,$when) = @_;
2095 0         0 my($year1,$month1,$day1,$hour1,$min1,$sec1,$year2,$month2,$day2,$hour2,$min2,$sec2);
2096 0 0       0 if ($when >= 0)
2097             {
2098 0         0 ($year1,$month1,$day1,$hour1,$min1,$sec1) = (gmtime($when))[5,4,3,2,1,0];
2099 0         0 $year1 += 1900;
2100 0         0 $month1++;
2101 0         0 ($year2,$month2,$day2,$hour2,$min2,$sec2,$$_dst) = (localtime($when))[5,4,3,2,1,0,8];
2102 0         0 $year2 += 1900;
2103 0         0 $month2++;
2104 0 0       0 if (DateCalc_delta_ymdhms($_year,$_month,$_day, $_hour,$_min,$_sec,
2105             $year1,$month1,$day1, $hour1,$min1,$sec1,
2106             $year2,$month2,$day2, $hour2,$min2,$sec2))
2107             {
2108 0 0       0 if ($$_dst != 0)
2109             {
2110 0 0       0 if ($$_dst < 0) { $$_dst = -1; }
  0         0  
2111 0         0 else { $$_dst = 1; }
2112             }
2113 0         0 return 1;
2114             }
2115             }
2116 0         0 return 0;
2117             }
2118              
2119             ## MacOS (Classic): ##
2120             ## <695056.0> = Fri 1-Jan-1904 00:00:00 (time=0x00000000) ##
2121             ## <744766.23295> = Mon 6-Feb-2040 06:28:15 (time=0xFFFFFFFF) ##
2122              
2123             ## Unix: ##
2124             ## <719163.0> = Thu 1-Jan-1970 00:00:00 (time=0x00000000) ##
2125             ## <744018.11647> = Tue 19-Jan-2038 03:14:07 (time=0x7FFFFFFF) ##
2126              
2127             #ifdef MACOS_TRADITIONAL
2128             #define DateCalc_DAYS_TO_EPOCH 695056
2129             #define DateCalc_DAYS_TO_OVFLW 744766
2130             #define DateCalc_SECS_TO_OVFLW 23295
2131             #else
2132             #define DateCalc_DAYS_TO_EPOCH 719163
2133             #define DateCalc_DAYS_TO_OVFLW 744018
2134             #define DateCalc_SECS_TO_OVFLW 11647
2135             #endif
2136              
2137             ## Substitute for BSD's timegm(3) function: ##
2138              
2139             sub DateCalc_date2time
2140             {
2141 6     6 0 9 my($_seconds,$year,$month,$day,$hour,$min,$sec) = @_;
2142 6         8 my($days,$secs);
2143 6         8 $$_seconds = 0;
2144 6         19 $days = DateCalc_Date_to_Days($year,$month,$day);
2145 6         12 $secs = ((($hour * 60) + $min) * 60) + $sec;
2146 6 50 33     76 return 0 if
      33        
      66        
      33        
2147             (
2148             ($days < $DateCalc_DAYS_TO_EPOCH) or
2149             ($secs < 0) or
2150             ($days > $DateCalc_DAYS_TO_OVFLW) or
2151             (
2152             ($days == $DateCalc_DAYS_TO_OVFLW) and
2153             ($secs > $DateCalc_SECS_TO_OVFLW)
2154             )
2155             );
2156 6         10 $$_seconds = (($days - $DateCalc_DAYS_TO_EPOCH) * 86400) + $secs;
2157 6         16 return 1;
2158             }
2159              
2160             ## Substitute for POSIX's gmtime(3) function: ##
2161              
2162             sub DateCalc_time2date
2163             {
2164 8     8 0 14 my($_year,$_month,$_day,$_hour,$_min,$_sec,$ss) = @_;
2165 8         8 my($mm,$hh,$dd);
2166 8 50       18 return 0 if ($ss < 0);
2167 8         15 $dd = int($ss / 86400);
2168 8         11 $ss -= $dd * 86400;
2169 8         13 $mm = int($ss / 60);
2170 8         9 $ss -= $mm * 60;
2171 8         12 $hh = int($mm / 60);
2172 8         10 $mm -= $hh * 60;
2173 8         12 $dd += $DateCalc_DAYS_TO_EPOCH-1;
2174 8         11 $$_sec = $ss;
2175 8         9 $$_min = $mm;
2176 8         10 $$_hour = $hh;
2177 8         7 $$_day = 1;
2178 8         9 $$_month = 1;
2179 8         8 $$_year = 1;
2180 8         19 return DateCalc_add_delta_days($_year,$_month,$_day,$dd);
2181             }
2182              
2183             sub DateCalc_easter_sunday
2184             {
2185             ##**************************************************************##
2186             ## ##
2187             ## Gauss'sche Regel (Gaussian Rule) ##
2188             ## ================================ ##
2189             ## ##
2190             ## Quelle / Source: ##
2191             ## ##
2192             ## H. H. Voigt, "Abriss der Astronomie", Wissenschaftsverlag, ##
2193             ## Bibliographisches Institut, Seite 9. ##
2194             ## ##
2195             ##**************************************************************##
2196              
2197 910     910 0 853 my($_year,$_month,$_day) = @_;
2198 910         770 my($a,$b,$c,$d,$e,$m,$n);
2199              
2200 910 100 100     2944 return 0 if (($$_year < 1583) or ($$_year > 2299));
2201              
2202 908 100       2447 if ($$_year < 1700) { $m = 22; $n = 2; }
  117 100       78  
  117 100       88  
    100          
    100          
2203 100         80 elsif ($$_year < 1800) { $m = 23; $n = 3; }
  100         74  
2204 100         107 elsif ($$_year < 1900) { $m = 23; $n = 4; }
  100         106  
2205 391         343 elsif ($$_year < 2100) { $m = 24; $n = 5; }
  391         355  
2206 100         74 elsif ($$_year < 2200) { $m = 24; $n = 6; }
  100         64  
2207 100         54 else { $m = 25; $n = 0; }
  100         72  
2208              
2209 908         852 $a = $$_year % 19;
2210 908         824 $b = $$_year % 4;
2211 908         795 $c = $$_year % 7;
2212 908         911 $d = (19 * $a + $m) % 30;
2213 908         1036 $e = (2 * $b + 4 * $c + 6 * $d + $n) % 7;
2214 908         843 $$_day = 22 + $d + $e;
2215 908         713 $$_month = 3;
2216 908 100       1371 if ($$_day > 31)
2217             {
2218 741         634 $$_day -= 31; ## same as $$_day = $d + $e - 9; ##
2219 741         538 ${$_month}++;
  741         764  
2220             }
2221 908 100 100     1903 $$_day = 19 if (($$_day == 26) and ($$_month == 4));
2222 908 100 100     1660 $$_day = 18 if (($$_day == 25) and ($$_month == 4) and ($d == 28) and ($e == 6) and ($a > 10));
      100        
      66        
      100        
2223 908         2498 return 1;
2224             }
2225              
2226             ## Carnival Monday / Rosenmontag / Veille du Mardi Gras = easter sunday - 48 ##
2227             ## Mardi Gras / Karnevalsdienstag / Mardi Gras = easter sunday - 47 ##
2228             ## Ash Wednesday / Aschermittwoch / Mercredi des Cendres = easter sunday - 46 ##
2229             ## Palm Sunday / Palmsonntag / Dimanche des Rameaux = easter sunday - 7 ##
2230             ## Easter Friday / Karfreitag / Vendredi Saint = easter sunday - 2 ##
2231             ## Easter Saturday / Ostersamstag / Samedi de Paques = easter sunday - 1 ##
2232             ## Easter Monday / Ostermontag / Lundi de Paques = easter sunday + 1 ##
2233             ## Ascension of Christ / Christi Himmelfahrt / Ascension = easter sunday + 39 ##
2234             ## Whitsunday / Pfingstsonntag / Dimanche de Pentecote = easter sunday + 49 ##
2235             ## Whitmonday / Pfingstmontag / Lundi de Pentecote = easter sunday + 50 ##
2236             ## Feast of Corpus Christi / Fronleichnam / Fete-Dieu = easter sunday + 60 ##
2237              
2238             sub DateCalc_Decode_Month ## 0 = error ##
2239             {
2240 2121     2121 0 1891 my($string,$lang) = @_;
2241 2121         1759 my($length,$buffer,$month,$ok,$m);
2242 2121 100 66     5858 $lang = $DateCalc_Language if (($lang < 1) or ($lang > $DateCalc_LANGUAGES));
2243 2121         1997 $length = length($string);
2244 2121         2618 $buffer = DateCalc_ISO_UC($string);
2245 2121         2030 $month = 0;
2246 2121         1708 $ok = 0;
2247             MONTH:
2248 2121         3929 for ( $m = 1; $m <= 12; $m++ )
2249             {
2250 25376 100       36349 next MONTH if ($length > length($DateCalc_Month_to_Text_[$lang][$m]));
2251 25259 100       33305 next MONTH if (DateCalc_ISO_UC(substr($DateCalc_Month_to_Text_[$lang][$m],0,$length)) ne $buffer);
2252 2130 100       3406 if ($month > 0) { $ok = 0; last MONTH; }
  13         20  
  13         15  
2253 2117         1766 else { $ok = 1; $month = $m; }
  2117         3323  
2254             }
2255 2121 100       7081 return $month if ($ok);
2256 17         29 return 0;
2257             }
2258              
2259             sub DateCalc_Decode_Day_of_Week ## 0 = error ##
2260             {
2261 1187     1187 0 1251 my($string,$lang) = @_;
2262 1187         981 my($length,$buffer,$dow,$ok,$d);
2263 1187 100 66     3764 $lang = $DateCalc_Language if (($lang < 1) or ($lang > $DateCalc_LANGUAGES));
2264 1187         1156 $length = length($string);
2265 1187         1469 $buffer = DateCalc_ISO_UC($string);
2266 1187         1130 $dow = 0;
2267 1187         957 $ok = 0;
2268             DAYOFWEEK:
2269 1187         2152 for ( $d = 1; $d <= 7; $d++ )
2270             {
2271 8303 100       12254 next DAYOFWEEK if ($length > length($DateCalc_Day_of_Week_to_Text_[$lang][$d]));
2272 8266 100       11443 next DAYOFWEEK if (DateCalc_ISO_UC(substr($DateCalc_Day_of_Week_to_Text_[$lang][$d],0,$length)) ne $buffer);
2273 1185 100       1955 if ($dow > 0) { $ok = 0; last DAYOFWEEK; }
  4         5  
  4         6  
2274 1181         1067 else { $ok = 1; $dow = $d; }
  1181         1895  
2275             }
2276 1187 100       4332 return $dow if ($ok);
2277 10         28 return 0;
2278             }
2279              
2280             sub DateCalc_Decode_Language ## 0 = error ##
2281             {
2282 10     10 0 19 my($string) = $_[0];
2283 10         11 my($length,$buffer,$lang,$ok,$l);
2284 10         16 $length = length($string);
2285 10         38 $buffer = DateCalc_ISO_UC($string);
2286 10         14 $lang = 0;
2287 10         17 $ok = 0;
2288             LANGUAGE:
2289 10         33 for ( $l = 1; $l <= $DateCalc_LANGUAGES; $l++ )
2290             {
2291 140 100       239 next LANGUAGE if ($length > length($DateCalc_Language_to_Text_[$l]));
2292 124 100       232 next LANGUAGE if (DateCalc_ISO_UC(substr($DateCalc_Language_to_Text_[$l],0,$length)) ne $buffer);
2293 10 50       33 if ($lang > 0) { $ok = 0; last LANGUAGE; }
  0         0  
  0         0  
2294 10         12 else { $ok = 1; $lang = $l; }
  10         20  
2295             }
2296 10 50       55 return $lang if ($ok);
2297 0         0 return 0;
2298             }
2299              
2300             sub DateCalc_decode_date_eu
2301             {
2302 14     14 0 14 my($string,$_year,$_month,$_day,$lang) = @_;
2303 14         9 my($length,$buffer,$i,$j);
2304 14 100 66     34 $lang = $DateCalc_Language if (($lang < 1) or ($lang > $DateCalc_LANGUAGES));
2305 14         14 $$_year = $$_month = $$_day = 0;
2306 14 50       21 return 0 unless ($length = length($string));
2307 14         10 $buffer = 0;
2308 14         13 $i = 0;
2309 14         18 while (DateCalc_scan9($string,$buffer,$length,$i,1)) { $i++; }
  12         16  
2310 14         18 $j = $length-1;
2311 14         16 while (DateCalc_scan9($string,$buffer,$length,$j,1)) { $j--; }
  24         31  
2312 14 50       28 if ($i+1 < $j) ## at least 3 chars, else error! ##
2313             {
2314 14         9 $buffer += $i;
2315 14         13 $length = $j-$i+1;
2316 14         10 $i = 1;
2317 14         17 while (DateCalc_scan9($string,$buffer,$length,$i,0)) { $i++; }
  13         21  
2318 14         14 $j = $length-2;
2319 14         18 while (DateCalc_scan9($string,$buffer,$length,$j,0)) { $j--; }
  28         45  
2320 14 100       21 if ($j < $i) ## only numerical chars without delimiters ##
2321             {
2322 2 50       13 if ($length == 3)
    100          
    50          
    50          
    0          
    0          
2323             {
2324 0         0 $$_day = substr($string,$buffer, 1);
2325 0         0 $$_month = substr($string,$buffer+1,1);
2326 0         0 $$_year = substr($string,$buffer+2,1);
2327             }
2328             elsif ($length == 4)
2329             {
2330 1         1 $$_day = substr($string,$buffer, 1);
2331 1         2 $$_month = substr($string,$buffer+1,1);
2332 1         2 $$_year = substr($string,$buffer+2,2);
2333             }
2334             elsif ($length == 5)
2335             {
2336 0         0 $$_day = substr($string,$buffer, 1);
2337 0         0 $$_month = substr($string,$buffer+1,2);
2338 0         0 $$_year = substr($string,$buffer+3,2);
2339             }
2340             elsif ($length == 6)
2341             {
2342 1         2 $$_day = substr($string,$buffer, 2);
2343 1         2 $$_month = substr($string,$buffer+2,2);
2344 1         1 $$_year = substr($string,$buffer+4,2);
2345             }
2346             elsif ($length == 7)
2347             {
2348 0         0 $$_day = substr($string,$buffer, 1);
2349 0         0 $$_month = substr($string,$buffer+1,2);
2350 0         0 $$_year = substr($string,$buffer+3,4);
2351             }
2352             elsif ($length == 8)
2353             {
2354 0         0 $$_day = substr($string,$buffer, 2);
2355 0         0 $$_month = substr($string,$buffer+2,2);
2356 0         0 $$_year = substr($string,$buffer+4,4);
2357             }
2358 0         0 else { return 0; }
2359             }
2360             else ## at least one non-numerical char (i <= j) ##
2361             {
2362 12         15 $$_day = substr($string,$buffer,$i);
2363 12         17 $$_year = substr($string,$buffer+($j+1),$length-($j+1));
2364 12         15 while (DateCalc_scanx($string,$buffer,$length,$i,1)) { $i++; }
  12         20  
2365 12         18 while (DateCalc_scanx($string,$buffer,$length,$j,1)) { $j--; }
  10         14  
2366 12 50       18 if ($i <= $j) ## at least one char left for month ##
2367             {
2368 12         10 $buffer += $i;
2369 12         14 $length = $j-$i+1;
2370 12         9 $i = 1;
2371 12         16 while (DateCalc_scanx($string,$buffer,$length,$i,0)) { $i++; }
  16         25  
2372 12 50       18 if ($i >= $length) ## ok, no more delimiters ##
2373             {
2374 12         8 $i = 0;
2375 12         15 while (DateCalc_scan9($string,$buffer,$length,$i,0)) { $i++; }
  8         11  
2376 12 100       17 if ($i >= $length) ## only digits for month ##
2377             {
2378 6         7 $$_month = substr($string,$buffer,$length);
2379             }
2380             else ## match with month names ##
2381             {
2382 6         12 $$_month = DateCalc_Decode_Month(substr($string,$buffer,$length),$lang);
2383             }
2384             }
2385 0         0 else { return 0; } ## delimiters inside month string ##
2386             }
2387 0         0 else { return 0; } ## no chars left for month ##
2388             } ## at least one non-numerical char (i <= j) ##
2389             }
2390 0         0 else { return 0; } ## less than 3 chars in buffer ##
2391 14         20 $$_year = DateCalc_Moving_Window($$_year);
2392 14         23 return DateCalc_check_date($$_year,$$_month,$$_day);
2393             }
2394              
2395             sub DateCalc_decode_date_us
2396             {
2397 11     11 0 11 my($string,$_year,$_month,$_day,$lang) = @_;
2398 11         13 my($length,$buffer,$i,$j,$k);
2399 11 50 33     22 $lang = $DateCalc_Language if (($lang < 1) or ($lang > $DateCalc_LANGUAGES));
2400              
2401 11         11 $$_year = $$_month = $$_day = 0;
2402 11 50       16 return 0 unless ($length = length($string));
2403             {
2404 11         10 $buffer = 0;
  11         7  
2405 11         10 $i = 0;
2406 11         13 while (DateCalc_scanx($string,$buffer,$length,$i,1)) { $i++; }
  5         6  
2407 11         15 $j = $length-1;
2408 11         17 while (DateCalc_scan9($string,$buffer,$length,$j,1)) { $j--; }
  11         17  
2409 11 50       23 if ($i+1 < $j) ## at least 3 chars, else error! ##
2410             {
2411 11         8 $buffer += $i;
2412 11         12 $length = $j-$i+1;
2413 11         7 $i = 1;
2414 11         14 while (DateCalc_scanx($string,$buffer,$length,$i,0)) { $i++; }
  30         38  
2415 11         15 $j = $length-2;
2416 11         35 while (DateCalc_scan9($string,$buffer,$length,$j,0)) { $j--; }
  26         35  
2417 11 100       21 if ($i >= $length) ## only alphanumeric chars left ##
2418             {
2419 4 100       14 if ($j < 0) ## case 0 : xxxx999999xxxx ##
2420             { ## j0 i ##
2421 1 50       2 if ($length == 3)
    50          
    0          
    0          
    0          
    0          
2422             {
2423 0         0 $$_month = substr($string,$buffer, 1);
2424 0         0 $$_day = substr($string,$buffer+1,1);
2425 0         0 $$_year = substr($string,$buffer+2,1);
2426             }
2427             elsif ($length == 4)
2428             {
2429 1         2 $$_month = substr($string,$buffer, 1);
2430 1         3 $$_day = substr($string,$buffer+1,1);
2431 1         1 $$_year = substr($string,$buffer+2,2);
2432             }
2433             elsif ($length == 5)
2434             {
2435 0         0 $$_month = substr($string,$buffer, 1);
2436 0         0 $$_day = substr($string,$buffer+1,2);
2437 0         0 $$_year = substr($string,$buffer+3,2);
2438             }
2439             elsif ($length == 6)
2440             {
2441 0         0 $$_month = substr($string,$buffer, 2);
2442 0         0 $$_day = substr($string,$buffer+2,2);
2443 0         0 $$_year = substr($string,$buffer+4,2);
2444             }
2445             elsif ($length == 7)
2446             {
2447 0         0 $$_month = substr($string,$buffer, 1);
2448 0         0 $$_day = substr($string,$buffer+1,2);
2449 0         0 $$_year = substr($string,$buffer+3,4);
2450             }
2451             elsif ($length == 8)
2452             {
2453 0         0 $$_month = substr($string,$buffer, 2);
2454 0         0 $$_day = substr($string,$buffer+2,2);
2455 0         0 $$_year = substr($string,$buffer+4,4);
2456             }
2457 0         0 else { return 0; }
2458             }
2459             else ## case 1 : xxxxAAA999999xxxx ##
2460             { ## 0 j i ##
2461 3         7 $$_month = DateCalc_Decode_Month(substr($string,$buffer,$j+1),$lang);
2462 3         4 $buffer += $j+1;
2463 3         4 $length -= $j+1;
2464 3 50       13 if ($length == 2)
    100          
    50          
    50          
    0          
2465             {
2466 0         0 $$_day = substr($string,$buffer, 1);
2467 0         0 $$_year = substr($string,$buffer+1,1);
2468             }
2469             elsif ($length == 3)
2470             {
2471 2         3 $$_day = substr($string,$buffer, 1);
2472 2         3 $$_year = substr($string,$buffer+1,2);
2473             }
2474             elsif ($length == 4)
2475             {
2476 0         0 $$_day = substr($string,$buffer, 2);
2477 0         0 $$_year = substr($string,$buffer+2,2);
2478             }
2479             elsif ($length == 5)
2480             {
2481 1         1 $$_day = substr($string,$buffer, 1);
2482 1         2 $$_year = substr($string,$buffer+1,4);
2483             }
2484             elsif ($length == 6)
2485             {
2486 0         0 $$_day = substr($string,$buffer, 2);
2487 0         0 $$_year = substr($string,$buffer+2,4);
2488             }
2489 0         0 else { return 0; }
2490             }
2491             } ## 0 i j l ##
2492             else ## case 2 : xxxxAAAxxxx9999xxxx _OR_ ##
2493             { ## case 3 : xxxxAAAxx99xx9999xx ##
2494 7         6 $k = 0; ## 0 i j l ##
2495 7         9 while (DateCalc_scan9($string,$buffer,$length,$k,0)) { $k++; }
  5         6  
2496 7 100       12 if ($k >= $i) ## ok, only digits ##
2497             {
2498 4         6 $$_month = substr($string,$buffer,$i);
2499             }
2500             else ## no, some non-digits ##
2501             {
2502 3         6 $$_month = DateCalc_Decode_Month(substr($string,$buffer,$i),$lang);
2503 3 50       7 if ($$_month == 0) { return 0; }
  0         0  
2504             }
2505 7         6 $buffer += $i;
2506 7         7 $length -= $i;
2507 7         5 $j -= $i;
2508 7         4 $k = $j+1; ## remember start position of day+year(2)/year(3) ##
2509 7         6 $i = 1;
2510 7         8 while (DateCalc_scanx($string,$buffer,$length,$i,1)) { $i++; }
  0         0  
2511 7         8 $j--;
2512 7         11 while (DateCalc_scan9($string,$buffer,$length,$j,1)) { $j--; }
  3         4  
2513 7 50       13 if ($j < $i) ## case 2 : xxxxAAAxxxx9999xxxx ##
2514             { ## j0 i l ##
2515 0         0 $buffer += $k; ## k ##
2516 0         0 $length -= $k;
2517 0 0       0 if ($length == 2)
    0          
    0          
    0          
    0          
2518             {
2519 0         0 $$_day = substr($string,$buffer, 1);
2520 0         0 $$_year = substr($string,$buffer+1,1);
2521             }
2522             elsif ($length == 3)
2523             {
2524 0         0 $$_day = substr($string,$buffer, 1);
2525 0         0 $$_year = substr($string,$buffer+1,2);
2526             }
2527             elsif ($length == 4)
2528             {
2529 0         0 $$_day = substr($string,$buffer, 2);
2530 0         0 $$_year = substr($string,$buffer+2,2);
2531             }
2532             elsif ($length == 5)
2533             {
2534 0         0 $$_day = substr($string,$buffer, 1);
2535 0         0 $$_year = substr($string,$buffer+1,4);
2536             }
2537             elsif ($length == 6)
2538             {
2539 0         0 $$_day = substr($string,$buffer, 2);
2540 0         0 $$_year = substr($string,$buffer+2,4);
2541             }
2542 0         0 else { return 0; }
2543             }
2544             else ## case 3 : xxxxAAAxx99xx9999xx ##
2545             { ## 0 ij k l ##
2546 7         12 $$_year = substr($string,$buffer+$k,$length-$k);
2547 7         5 $k = $i;
2548 7         9 while (DateCalc_scan9($string,$buffer,$length,$k,0)) { $k++; }
  10         14  
2549 7 50       16 if ($k > $j) ## ok, only digits ##
2550             {
2551 7         12 $$_day = substr($string,$buffer+$i,$j-$i+1);
2552             }
2553 0         0 else { return 0; } ## non-digits inside day ##
2554             }
2555             } ## i < length ##
2556             }
2557 0         0 else { return 0; } ## less than 3 chars in buffer ##
2558             }
2559 11         15 $$_year = DateCalc_Moving_Window($$_year);
2560 11         21 return DateCalc_check_date($$_year,$$_month,$$_day);
2561             }
2562              
2563             sub DateCalc_Fixed_Window
2564             {
2565 0     0 0 0 my($year) = $_[0];
2566 0 0       0 return 0 if ($year < 0);
2567 0 0       0 if ($year < 100)
2568             {
2569 0 0       0 $year += 100 if ($year < $DateCalc_YEAR_OF_EPOCH);
2570 0         0 $year += $DateCalc_CENTURY_OF_EPOCH;
2571             }
2572 0         0 return $year;
2573             }
2574              
2575             sub DateCalc_Moving_Window
2576             {
2577 109     109 0 116 my($year) = $_[0];
2578 109         88 my($seconds,$current,$century);
2579 109 50       233 return 0 if ($year < 0);
2580 109 100       170 if ($year < 100)
2581             {
2582 68 50       107 if (($seconds = time()) >= 0)
2583             {
2584 68         239 $current = (gmtime($seconds))[5] + 1900;
2585 68         104 $century = int($current / 100);
2586 68         75 $year += $century * 100;
2587 68 50       189 if ($year < $current - 50) { $year += 100; }
  0 50       0  
2588 0         0 elsif ($year >= $current + 50) { $year -= 100; }
2589             }
2590 0         0 else { $year = DateCalc_Fixed_Window($year); }
2591             }
2592 109         174 return $year;
2593             }
2594              
2595             sub DateCalc_Compress
2596             {
2597 6     6 0 6 my($year,$month,$day) = @_;
2598 6         4 my($yy);
2599 6 100 66     19 if (($year >= $DateCalc_EPOCH) and ($year < ($DateCalc_EPOCH + 100)))
2600             {
2601 3         9 $yy = $year;
2602 3         3 $year -= $DateCalc_EPOCH;
2603             }
2604             else
2605             {
2606 3 100 66     14 return 0 if (($year < 0) or ($year > 99));
2607 2 100       4 if ($year < $DateCalc_YEAR_OF_EPOCH)
2608             {
2609 1         2 $yy = $DateCalc_CENTURY_OF_EPOCH + 100 + $year;
2610 1         2 $year += 100 - $DateCalc_YEAR_OF_EPOCH;
2611             }
2612             else
2613             {
2614 1         2 $yy = $DateCalc_CENTURY_OF_EPOCH + $year;
2615 1         2 $year -= $DateCalc_YEAR_OF_EPOCH;
2616             }
2617             }
2618 5 50 33     16 return 0 if (($month < 1) or ($month > 12));
2619 5 100 66     17 return 0 if
2620             (($day < 1) or
2621             ($day > $DateCalc_Days_in_Month_[DateCalc_leap_year($yy)][$month]));
2622 4         9 return ($year << 9) | ($month << 5) | $day;
2623             }
2624              
2625             sub DateCalc_uncompress
2626             {
2627 30     30 0 30 my($date,$_century,$_year,$_month,$_day) = @_;
2628 30 100       47 if ($date > 0)
2629             {
2630 24         23 $$_year = $date >> 9;
2631 24         24 $$_month = ($date & 0x01FF) >> 5;
2632 24         21 $$_day = $date & 0x001F;
2633 24 50       34 if ($$_year < 100)
2634             {
2635 24 100       34 if ($$_year < 100-$DateCalc_YEAR_OF_EPOCH)
2636             {
2637 18         16 $$_century = $DateCalc_CENTURY_OF_EPOCH;
2638 18         17 $$_year += $DateCalc_YEAR_OF_EPOCH;
2639             }
2640             else
2641             {
2642 6         9 $$_century = $DateCalc_CENTURY_OF_EPOCH+100;
2643 6         8 $$_year -= 100-$DateCalc_YEAR_OF_EPOCH;
2644             }
2645 24         43 return DateCalc_check_date($$_century+$$_year,$$_month,$$_day);
2646             }
2647             }
2648 6         12 return 0;
2649             }
2650              
2651             sub DateCalc_check_compressed
2652             {
2653 5     5 0 4 my($century,$year,$month,$day);
2654 5         10 return DateCalc_uncompress($_[0],\$century,\$year,\$month,\$day);
2655             }
2656              
2657             sub DateCalc_Compressed_to_Text
2658             {
2659 20     20 0 16 my($date,$lang) = @_;
2660 20         45 my($century,$year,$month,$day,$string);
2661 20 100 66     46 $lang = $DateCalc_Language if (($lang < 1) or ($lang > $DateCalc_LANGUAGES));
2662 20 100       25 if (DateCalc_uncompress($date,\$century,\$year,\$month,\$day))
2663             {
2664 12         31 $string = sprintf("%02d-%.3s-%02d",$day,$DateCalc_Month_to_Text_[$lang][$month],$year);
2665             }
2666 8         7 else { $string = '??-???-??'; }
2667 20         37 return $string;
2668             }
2669              
2670             sub DateCalc_Date_to_Text
2671             {
2672 9     9 0 12 my($year,$month,$day,$lang) = @_;
2673 9 100 66     32 $lang = $DateCalc_Language if (($lang < 1) or ($lang > $DateCalc_LANGUAGES));
2674 9 50       11 if (DateCalc_check_date($year,$month,$day))
2675             {
2676 9 50       16 if ($DateCalc_Day_of_Week_Abbreviation_[$lang][0] ne '')
2677             {
2678 0         0 return sprintf("%.3s %d-%.3s-%d",
2679             $DateCalc_Day_of_Week_Abbreviation_[$lang][DateCalc_Day_of_Week($year,$month,$day)],
2680             $day,$DateCalc_Month_to_Text_[$lang][$month],$year);
2681             }
2682             else
2683             {
2684 9         14 return sprintf("%.3s %d-%.3s-%d",
2685             $DateCalc_Day_of_Week_to_Text_[$lang][DateCalc_Day_of_Week($year,$month,$day)],
2686             $day,$DateCalc_Month_to_Text_[$lang][$month],$year);
2687             }
2688             }
2689 0         0 return undef;
2690             }
2691              
2692             sub DateCalc_English_Ordinal
2693             {
2694 13     13 0 24 my($result) = "$_[0]";
2695 13         12 my($length,$digit);
2696 13 50       24 if (($length = length($result)) > 0)
2697             {
2698 13 100 100     135 $digit = 0 unless
      66        
2699             (
2700             ( (($length > 1) and (substr($result,$length-2,1) ne '1')) or ($length == 1) )
2701             and
2702             ( ($digit = substr($result,$length-1,1)) <= 3 )
2703             );
2704 13         19 $result .= $DateCalc_English_Ordinals_[$digit];
2705             }
2706 13         71 return $result;
2707             }
2708              
2709             sub DateCalc_Date_to_Text_Long
2710             {
2711 55     55 0 53 my($year,$month,$day,$lang) = @_;
2712 55         42 my($string,$buffer);
2713 55 100 66     153 $lang = $DateCalc_Language if (($lang < 1) or ($lang > $DateCalc_LANGUAGES));
2714 55 50       64 if (DateCalc_check_date($year,$month,$day))
2715             {
2716 55 100       88 if ($lang == 1)
    50          
2717             {
2718 13         34 return sprintf
2719             (
2720             $DateCalc_Date_Long_Format_[$lang],
2721             $DateCalc_Day_of_Week_to_Text_[$lang]
2722             [DateCalc_Day_of_Week($year,$month,$day)],
2723             $DateCalc_Month_to_Text_[$lang][$month],
2724             DateCalc_English_Ordinal($day),
2725             $year
2726             );
2727             }
2728             elsif ($lang == 12)
2729             {
2730 0         0 return sprintf
2731             (
2732             $DateCalc_Date_Long_Format_[$lang],
2733             $year,
2734             $DateCalc_Month_to_Text_[$lang][$month],
2735             $day,
2736             $DateCalc_Day_of_Week_to_Text_[$lang]
2737             [DateCalc_Day_of_Week($year,$month,$day)]
2738             );
2739             }
2740             else
2741             {
2742 42         67 return sprintf
2743             (
2744             $DateCalc_Date_Long_Format_[$lang],
2745             $DateCalc_Day_of_Week_to_Text_[$lang]
2746             [DateCalc_Day_of_Week($year,$month,$day)],
2747             $day,
2748             $DateCalc_Month_to_Text_[$lang][$month],
2749             $year
2750             );
2751             }
2752             }
2753 0         0 return undef;
2754             }
2755              
2756             sub DateCalc_Calendar
2757             {
2758 24     24 0 21 my($year,$month,$orthodox,$lang) = @_;
2759 24         16 my($string,$cursor,$buffer,$first,$last,$day);
2760 24 50 33     40 if (($lang < 1) or ($lang > $DateCalc_LANGUAGES)) { $lang = $DateCalc_Language; }
  24         20  
2761 24         17 $string = '';
2762 24         18 $cursor = \$string;
2763 24         33 DateCalc_Newline($cursor,1);
2764 24         44 $buffer = sprintf("%s %d", DateCalc_ISO_UC_First($DateCalc_Month_to_Text_[$lang][$month]), $year);
2765 24         32 DateCalc_Center($cursor,$buffer,27);
2766 24 50       36 if ($DateCalc_Day_of_Week_Abbreviation_[$lang][0] ne '')
2767             {
2768 0 0       0 if ($orthodox)
2769             {
2770 0         0 $string .= sprintf("%3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s\n",
2771             $DateCalc_Day_of_Week_Abbreviation_[$lang][7],
2772             $DateCalc_Day_of_Week_Abbreviation_[$lang][1],
2773             $DateCalc_Day_of_Week_Abbreviation_[$lang][2],
2774             $DateCalc_Day_of_Week_Abbreviation_[$lang][3],
2775             $DateCalc_Day_of_Week_Abbreviation_[$lang][4],
2776             $DateCalc_Day_of_Week_Abbreviation_[$lang][5],
2777             $DateCalc_Day_of_Week_Abbreviation_[$lang][6]);
2778             }
2779             else ## conform to ISO standard ##
2780             {
2781 0         0 $string .= sprintf("%3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s\n",
2782             $DateCalc_Day_of_Week_Abbreviation_[$lang][1],
2783             $DateCalc_Day_of_Week_Abbreviation_[$lang][2],
2784             $DateCalc_Day_of_Week_Abbreviation_[$lang][3],
2785             $DateCalc_Day_of_Week_Abbreviation_[$lang][4],
2786             $DateCalc_Day_of_Week_Abbreviation_[$lang][5],
2787             $DateCalc_Day_of_Week_Abbreviation_[$lang][6],
2788             $DateCalc_Day_of_Week_Abbreviation_[$lang][7]);
2789             }
2790             }
2791             else
2792             {
2793 24 100       26 if ($orthodox)
2794             {
2795 12         36 $string .= sprintf("%3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s\n",
2796             $DateCalc_Day_of_Week_to_Text_[$lang][7],
2797             $DateCalc_Day_of_Week_to_Text_[$lang][1],
2798             $DateCalc_Day_of_Week_to_Text_[$lang][2],
2799             $DateCalc_Day_of_Week_to_Text_[$lang][3],
2800             $DateCalc_Day_of_Week_to_Text_[$lang][4],
2801             $DateCalc_Day_of_Week_to_Text_[$lang][5],
2802             $DateCalc_Day_of_Week_to_Text_[$lang][6]);
2803             }
2804             else ## conform to ISO standard ##
2805             {
2806 12         34 $string .= sprintf("%3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s\n",
2807             $DateCalc_Day_of_Week_to_Text_[$lang][1],
2808             $DateCalc_Day_of_Week_to_Text_[$lang][2],
2809             $DateCalc_Day_of_Week_to_Text_[$lang][3],
2810             $DateCalc_Day_of_Week_to_Text_[$lang][4],
2811             $DateCalc_Day_of_Week_to_Text_[$lang][5],
2812             $DateCalc_Day_of_Week_to_Text_[$lang][6],
2813             $DateCalc_Day_of_Week_to_Text_[$lang][7]);
2814             }
2815             }
2816 24         28 $first = DateCalc_Day_of_Week($year,$month,1);
2817 24         28 $last = $DateCalc_Days_in_Month_[DateCalc_leap_year($year)][$month];
2818 24 100       30 if ($orthodox) { $first = 0 if ($first == 7); }
  12 100       17  
2819 12         10 else { $first--; }
2820 24 100       30 if ($first) { DateCalc_Blank($cursor,($first<<2)-1); }
  20         27  
2821 24         41 for ( $day = 1; $day <= $last; $day++, $first++ )
2822             {
2823 731 100       818 if ($first > 0)
2824             {
2825 727 100       633 if ($first > 6)
2826             {
2827 101         64 $first = 0;
2828 101         98 DateCalc_Newline($cursor,1);
2829             }
2830 626         569 else { DateCalc_Blank($cursor,1); }
2831             }
2832 731         1265 $string .= sprintf(" %2d",$day);
2833             }
2834 24         28 DateCalc_Newline($cursor,2);
2835 24         56 return $string;
2836             }
2837              
2838             ###############
2839             ## ##
2840             ## Calc.pm ##
2841             ## ##
2842             ###############
2843              
2844             sub Decode_Date_EU2
2845             {
2846 46 50 66 46 0 461 croak "Usage: (\$year,\$month,\$day) = Decode_Date_EU2(\$date[,\$lang]);\n" unless ((@_ == 1) or (@_ == 2));
2847              
2848 46         85 my($buffer) = shift;
2849 46   100     106 my($lang) = shift || 0;
2850 46         34 my($year,$month,$day,$length);
2851              
2852 46 100 66     104 $lang = Language() unless (($lang >= 1) and ($lang <= Languages()));
2853 46 100       228 if ($buffer =~ /^\D* (\d+) [^A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF]* ([A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF]+) [^A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF]* (\d+) \D*$/x)
    100          
    100          
2854             {
2855 22         48 ($day,$month,$year) = ($1,$2,$3);
2856 22         27 $month = Decode_Month($month,$lang);
2857 22 100       36 unless ($month > 0)
2858             {
2859 1         4 return(); # can't decode month!
2860             }
2861             }
2862             elsif ($buffer =~ /^\D* 0*(\d+) \D*$/x)
2863             {
2864 19         28 $buffer = $1;
2865 19         15 $length = length($buffer);
2866 19 100       48 if ($length == 3)
    100          
    100          
    100          
    100          
    100          
2867             {
2868 3         4 $day = substr($buffer,0,1);
2869 3         3 $month = substr($buffer,1,1);
2870 3         3 $year = substr($buffer,2,1);
2871             }
2872             elsif ($length == 4)
2873             {
2874 3         4 $day = substr($buffer,0,1);
2875 3         3 $month = substr($buffer,1,1);
2876 3         3 $year = substr($buffer,2,2);
2877             }
2878             elsif ($length == 5)
2879             {
2880 3         5 $day = substr($buffer,0,1);
2881 3         2 $month = substr($buffer,1,2);
2882 3         4 $year = substr($buffer,3,2);
2883             }
2884             elsif ($length == 6)
2885             {
2886 3         4 $day = substr($buffer,0,2);
2887 3         2 $month = substr($buffer,2,2);
2888 3         4 $year = substr($buffer,4,2);
2889             }
2890             elsif ($length == 7)
2891             {
2892 3         5 $day = substr($buffer,0,1);
2893 3         3 $month = substr($buffer,1,2);
2894 3         3 $year = substr($buffer,3,4);
2895             }
2896             elsif ($length == 8)
2897             {
2898 3         8 $day = substr($buffer,0,2);
2899 3         1 $month = substr($buffer,2,2);
2900 3         4 $year = substr($buffer,4,4);
2901             }
2902 1         3 else { return(); } # wrong number of digits!
2903             }
2904             elsif ($buffer =~ /^\D* (\d+) \D+ (\d+) \D+ (\d+) \D*$/x)
2905             {
2906 3         9 ($day,$month,$year) = ($1,$2,$3);
2907             }
2908 2         7 else { return(); } # no match at all!
2909 42         51 $year = Moving_Window($year);
2910 42 100       55 if (check_date($year,$month,$day))
2911             {
2912 40         124 return($year,$month,$day);
2913             }
2914 2         8 else { return(); } # not a valid date!
2915             }
2916              
2917             sub Decode_Date_US2
2918             {
2919 46 50 66 46 0 760 croak "Usage: (\$year,\$month,\$day) = Decode_Date_US2(\$date[,\$lang]);\n" unless ((@_ == 1) or (@_ == 2));
2920              
2921 46         126 my($buffer) = shift;
2922 46   100     165 my($lang) = shift || 0;
2923 46         45 my($year,$month,$day,$length);
2924              
2925 46 100 66     159 $lang = Language() unless (($lang >= 1) and ($lang <= Languages()));
2926 46 100       431 if ($buffer =~ /^[^A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF]* ([A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF]+) [^A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF]* 0*(\d+) \D*$/x)
    100          
    100          
    100          
2927             {
2928 14         44 ($month,$buffer) = ($1,$2);
2929 14         31 $month = Decode_Month($month,$lang);
2930 14 50       44 unless ($month > 0)
2931             {
2932 0         0 return(); # can't decode month!
2933             }
2934 14         16 $length = length($buffer);
2935 14 50       50 if ($length == 2)
    100          
    100          
    100          
    50          
2936             {
2937 0         0 $day = substr($buffer,0,1);
2938 0         0 $year = substr($buffer,1,1);
2939             }
2940             elsif ($length == 3)
2941             {
2942 3         8 $day = substr($buffer,0,1);
2943 3         5 $year = substr($buffer,1,2);
2944             }
2945             elsif ($length == 4)
2946             {
2947 4         10 $day = substr($buffer,0,2);
2948 4         14 $year = substr($buffer,2,2);
2949             }
2950             elsif ($length == 5)
2951             {
2952 3         7 $day = substr($buffer,0,1);
2953 3         5 $year = substr($buffer,1,4);
2954             }
2955             elsif ($length == 6)
2956             {
2957 4         9 $day = substr($buffer,0,2);
2958 4         6 $year = substr($buffer,2,4);
2959             }
2960 0         0 else { return(); } # wrong number of digits!
2961             }
2962             elsif ($buffer =~ /^[^A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF]* ([A-Za-z\xC0-\xD6\xD8-\xF6\xF8-\xFF]+) [^A-Za-z0-9\xC0-\xD6\xD8-\xF6\xF8-\xFF]* (\d+) \D+ (\d+) \D*$/x)
2963             {
2964 8         29 ($month,$day,$year) = ($1,$2,$3);
2965 8         18 $month = Decode_Month($month,$lang);
2966 8 100       19 unless ($month > 0)
2967             {
2968 1         5 return(); # can't decode month!
2969             }
2970             }
2971             elsif ($buffer =~ /^\D* 0*(\d+) \D*$/x)
2972             {
2973 19         55 $buffer = $1;
2974 19         21 $length = length($buffer);
2975 19 100       78 if ($length == 3)
    100          
    100          
    100          
    100          
    100          
2976             {
2977 3         8 $month = substr($buffer,0,1);
2978 3         5 $day = substr($buffer,1,1);
2979 3         6 $year = substr($buffer,2,1);
2980             }
2981             elsif ($length == 4)
2982             {
2983 3         7 $month = substr($buffer,0,1);
2984 3         5 $day = substr($buffer,1,1);
2985 3         5 $year = substr($buffer,2,2);
2986             }
2987             elsif ($length == 5)
2988             {
2989 3         7 $month = substr($buffer,0,1);
2990 3         4 $day = substr($buffer,1,2);
2991 3         5 $year = substr($buffer,3,2);
2992             }
2993             elsif ($length == 6)
2994             {
2995 3         7 $month = substr($buffer,0,2);
2996 3         6 $day = substr($buffer,2,2);
2997 3         6 $year = substr($buffer,4,2);
2998             }
2999             elsif ($length == 7)
3000             {
3001 3         6 $month = substr($buffer,0,1);
3002 3         5 $day = substr($buffer,1,2);
3003 3         6 $year = substr($buffer,3,4);
3004             }
3005             elsif ($length == 8)
3006             {
3007 3         7 $month = substr($buffer,0,2);
3008 3         5 $day = substr($buffer,2,2);
3009 3         4 $year = substr($buffer,4,4);
3010             }
3011 1         5 else { return(); } # wrong number of digits!
3012             }
3013             elsif ($buffer =~ /^\D* (\d+) \D+ (\d+) \D+ (\d+) \D*$/x)
3014             {
3015 3         16 ($month,$day,$year) = ($1,$2,$3);
3016             }
3017 2         10 else { return(); } # no match at all!
3018 42         83 $year = Moving_Window($year);
3019 42 100       100 if (check_date($year,$month,$day))
3020             {
3021 40         234 return($year,$month,$day);
3022             }
3023 2         10 else { return(); } # not a valid date!
3024             }
3025              
3026             sub Parse_Date
3027             {
3028 15 50 66 15 0 318 croak "Usage: (\$year,\$month,\$day) = Parse_Date(\$date[,\$lang]);\n" unless ((@_ == 1) or (@_ == 2));
3029              
3030 15         61 my($date) = shift;
3031 15   100     44 my($lang) = shift || 0;
3032 15         16 my($year,$month,$day);
3033              
3034 15 100 66     48 $lang = Language() unless (($lang >= 1) and ($lang <= Languages()));
3035 15 100       97 unless ($date =~ /\b([\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF]{3})\s+([0123]??\d)\b/)
3036             {
3037 1         5 return();
3038             }
3039 14         28 $month = $1;
3040 14         19 $day = $2;
3041 14 100       58 unless ($date =~ /\b(19\d\d|20\d\d)\b/)
3042             {
3043 1         5 return();
3044             }
3045 13         16 $year = $1;
3046 13         26 $month = Decode_Month($month,$lang);
3047 13 50       29 unless ($month > 0)
3048             {
3049 0         0 return();
3050             }
3051 13 100       24 unless (check_date($year,$month,$day))
3052             {
3053 1         4 return();
3054             }
3055 12         74 return($year,$month,$day);
3056             }
3057              
3058             1;
3059              
3060             __END__