php 8. strpos(): Passing null to parameter #1 ($haystack) of type string is deprecate...
[fa-stable.git] / includes / date_functions.inc
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 /*
13 date validation and parsing functions
14
15 These functions refer to the global variable defining the date format
16 The date format is defined in config.php called dateformats
17 this can be a string either "d/m/Y" for UK/Australia/New Zealand dates or
18 "m/d/Y" for US/Canada format dates depending on setting in preferences.
19
20 */
21
22 function __date($year, $month, $day)
23 {
24         global $SysPrefs, $tmonths;
25         
26         $how = user_date_format();
27         $sep = $SysPrefs->dateseps[user_date_sep()];
28         $day = (int)$day;
29         $month = (int)$month;
30         if ($how < 3)
31         {
32                 if ($day < 10)
33                         $day = "0".$day;
34                 if ($month < 10)
35                         $month = "0".$month;
36         }               
37         if ($how == 0)
38                 return $month.$sep.$day.$sep.$year;
39         elseif ($how == 1)
40                 return $day.$sep.$month.$sep.$year;
41         elseif ($how == 2)
42                 return $year.$sep.$month.$sep.$day;
43         elseif ($how == 3)
44                 return $tmonths[$month].$sep.$day.$sep.$year;
45         elseif ($how == 4)
46                 return $day.$sep.$tmonths[$month].$sep.$year;
47         else
48                 return $year.$sep.$tmonths[$month].$sep.$day;
49 }
50
51 function is_date($date_) 
52 {
53         global $SysPrefs;
54
55         if ($date_ == null || $date_ == "")
56                 return 0;
57         $how = user_date_format();
58         $sep = $SysPrefs->dateseps[user_date_sep()];
59
60         $date_ = trim($date_);
61         $date = str_replace($sep, "", $date_);
62         
63         if ($how > 2)
64         {
65                 global $tmonths;
66                 $dd = explode($sep, $date_);
67                 if ($how == 3)
68                 {
69                         $day = $dd[1];
70                         $month = array_search($dd[0], $tmonths);
71                         $year = $dd[2];
72                 } 
73                 elseif ($how == 4)
74                 {
75                         $day = $dd[0];
76                         $month = array_search($dd[1], $tmonths);
77                         $year = $dd[2];
78                 } 
79                 else
80                 {
81                         $day = $dd[2];
82                         $month = array_search($dd[1], $tmonths);
83                         $year = $dd[0];
84                 }
85                 if ($year < 1000)
86                         return 0;
87         }
88         elseif (strlen($date) == 6)
89         {
90                 if ($how == 0)
91                 {
92                         $day = substr($date,2,2);
93                         $month = substr($date,0,2);
94                         $year = substr($date,4,2);
95                 } 
96                 elseif ($how == 1)
97                 {
98                         $day = substr($date,0,2);
99                         $month = substr($date,2,2);
100                         $year = substr($date,4,2);
101                 } 
102                 else
103                 {
104                         $day = substr($date,4,2);
105                         $month = substr($date,2,2);
106                         $year = substr($date,0,2);
107                 }
108         }
109         elseif (strlen($date) == 8)
110         {
111                 if ($how == 0)
112                 {
113                         $day = substr($date,2,2);
114                         $month = substr($date,0,2);
115                         $year = substr($date,4,4);
116                 } 
117                 elseif ($how == 1)
118                 {
119                         $day = substr($date,0,2);
120                         $month = substr($date,2,2);
121                         $year = substr($date,4,4);
122                 } 
123                 else
124                 {
125                         $day = substr($date,6,2);
126                         $month = substr($date,4,2);
127                         $year = substr($date,0,4);
128                 }
129         }
130         if (!isset($year)|| (int)$year > 9999) 
131         {
132                 return 0;
133         }
134
135         if (is_long((int)$day) && is_long((int)$month) && is_long((int)$year))
136         {
137                 global $SysPrefs;
138                 if ($SysPrefs->date_system == 1)
139                         list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);  
140                 elseif ($SysPrefs->date_system == 2)    
141                         list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);  
142                 if (checkdate((int)$month, (int)$day, (int)$year))
143                 {
144                         return 1;
145                 }
146                 else
147                 {
148                         return 0;
149                 }
150         }
151         else
152         { /*Can't be in an appropriate DefaultDateFormat */
153                 return 0;
154         }
155 } //end of is_date function
156
157 function Today() 
158 {
159         global $SysPrefs;
160
161         $year = date("Y");
162         $month = date("n");
163         $day = date("j");
164         if ($SysPrefs->date_system == 1)
165                 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
166         elseif ($SysPrefs->date_system == 2)    
167                 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
168         return __date($year, $month, $day);     
169 }
170
171 function Now() 
172 {
173         if (user_date_format() == 0)
174                 return date("h:i a");
175         else
176                 return date("H:i");
177 }
178 //
179 //      Retrieve and optionaly set default date for new document.
180 //
181 function new_doc_date($date=null)
182 {
183         if (isset($date) && $date != '')
184                 $_SESSION['_default_date'] = $date;
185
186         if (!isset($_SESSION['_default_date']) || !sticky_doc_date())
187                 $_SESSION['_default_date'] = Today();
188
189         return $_SESSION['_default_date'];
190 }
191
192 function is_date_in_fiscalyear($date, $convert=false)
193 {
194         global $path_to_root;
195         include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
196
197         if ($convert)
198                 $date2 = sql2date($date);
199         else
200                 $date2 = $date;
201
202         if (is_date_closed($date2))
203                 return 0;
204
205         if (user_check_access('SA_MULTIFISCALYEARS')) // allow all open years for this one
206                 return is_date_in_fiscalyears($date2, false);
207
208         $myrow = get_current_fiscalyear();
209         $begin = sql2date($myrow['begin']);
210         $end = sql2date($myrow['end']);
211         if (date1_greater_date2($begin, $date2) || date1_greater_date2($date2, $end))
212         {
213                 return 0;
214         }
215         return 1;
216 }
217
218 function is_date_closed($date)
219 {
220         return !date1_greater_date2($date, sql2date(get_company_pref('gl_closing_date')));
221 }
222
223 function begin_fiscalyear()
224 {
225         global $path_to_root;
226         include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
227
228         $myrow = get_current_fiscalyear();
229         return sql2date($myrow['begin']);
230 }
231
232 function end_fiscalyear()
233 {
234         global $path_to_root;
235         include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
236
237         $myrow = get_current_fiscalyear();
238         return sql2date($myrow['end']);
239 }
240
241 function begin_month($date)
242 {
243         global $SysPrefs;
244     list($day, $month, $year) = explode_date_to_dmy($date);
245     if ($SysPrefs->date_system == 1)
246         list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
247     elseif ($SysPrefs->date_system == 2)        
248         list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
249         return __date($year, $month, 1);
250 }
251
252 function days_in_month($month, $year)
253 {
254         global $SysPrefs;
255
256         if ($SysPrefs->date_system == 1)
257         {
258                 $days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, ((((((($year - (($year > 0) ? 474 : 473)) % 2820) + 474) + 38) * 682) % 2816) < 682 ? 30 : 29));
259         }
260         elseif ($SysPrefs->date_system == 2)
261         {
262                 $days_in_month = array(30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, (((((11 * $year) + 14) % 30) < 11) ? 30 : 29));
263         }
264         else // gregorian date
265                 $days_in_month = array(31, ((!($year % 4 ) && (($year % 100) || !($year % 400)))?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
266
267         return $days_in_month[$month - 1];
268 }
269
270 function end_month($date)
271 {
272         global $SysPrefs;
273
274     list($day, $month, $year) = explode_date_to_dmy($date);
275         if ($SysPrefs->date_system == 1)
276         {
277                 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
278         }
279         elseif ($SysPrefs->date_system == 2)
280         {
281                 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
282         }
283
284         return __date($year, $month, days_in_month($month, $year));
285 }
286
287 function add_days($date, $days) // accepts negative values as well
288 {
289         global $SysPrefs;
290     list($day, $month, $year) = explode_date_to_dmy($date);
291         $timet = mktime(0,0,0, $month, $day + $days, $year);
292     if ($SysPrefs->date_system == 1 || $SysPrefs->date_system == 2)
293     {
294         if ($SysPrefs->date_system == 1)
295                 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
296         elseif ($SysPrefs->date_system == 2)    
297                 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
298         return __date($year, $month, $day);
299     }
300     list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
301         return __date($year, $month, $day);
302 }
303
304 function add_months($date, $months) // accepts negative values as well
305 {
306         global $SysPrefs;
307
308     list($day, $month, $year) = explode_date_to_dmy($date);
309
310         $months += $year*12+$month;
311         $month = ($months-1)%12+1;
312         $year = ($months-$month)/12;
313
314         $timet = mktime(0,0,0, $month, min($day, days_in_month($month, $year)), $year);
315
316     if ($SysPrefs->date_system == 1 || $SysPrefs->date_system == 2)
317     {
318         if ($SysPrefs->date_system == 1)
319                 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
320         elseif ($SysPrefs->date_system == 2)    
321                 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
322         return __date($year, $month, $day);
323     }
324     list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
325         return __date($year, $month, $day);
326 }
327
328 function add_years($date, $years) // accepts negative values as well
329 {
330         global $SysPrefs;
331
332     list($day, $month, $year) = explode_date_to_dmy($date);
333         $timet = Mktime(0,0,0, $month, $day, $year + $years);
334     if ($SysPrefs->date_system == 1 || $SysPrefs->date_system == 2)
335     {
336         if ($SysPrefs->date_system == 1)
337                 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
338         elseif ($SysPrefs->date_system == 2)    
339                 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
340         return __date($year, $month, $day);
341     }
342     list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
343         return __date($year, $month, $day);
344 }
345
346 //_______________________________________________________________
347
348 function sql2date($date_) 
349 {
350         global $SysPrefs;
351
352         //for MySQL dates are in the format YYYY-mm-dd
353         if ($date_ == null)
354                 return "";
355         if (strpos($date_, "/")) 
356         { // In MySQL it could be either / or -
357                 list($year, $month, $day) = explode("/", $date_);
358         } 
359         elseif (strpos ($date_, "-")) 
360         {
361                 list($year, $month, $day) = explode("-", $date_);
362         }
363         if (!isset($day)) // data format error
364                 return "";
365
366         if (strlen($day) > 4) 
367         {  /*chop off the time stuff */
368                 $day = substr($day, 0, 2);
369         }
370         if ($SysPrefs->date_system == 1)
371                 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
372         elseif ($SysPrefs->date_system == 2)
373                 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
374         return __date($year, $month, $day);     
375 } // end function sql2date
376
377
378 function date2sql($date_)
379 {
380         global $SysPrefs, $tmonths;
381 /* takes a date in a the format specified in $DefaultDateFormat
382 and converts to a yyyy/mm/dd format */
383
384         $how = user_date_format();
385         $sep = $SysPrefs->dateseps[user_date_sep()];
386
387         $date_ = trim($date_);
388         if ($date_ == null || strlen($date_) == 0)
389                 return "";
390
391     $year = $month = $day = 0;
392     // Split up the date by the separator based on "how" to split it
393     if ($how == 0 || $how == 3) // MMDDYYYY or MmmDDYYYY
394         list($month, $day, $year) = explode($sep, $date_);
395     elseif ($how == 1 || $how == 4) // DDMMYYYY or DDMmYYYY
396         list($day, $month, $year) = explode($sep, $date_);
397     else // $how == 2 || $how == 5, YYYYMMDD or YYYYMmmDD
398         list($year, $month, $day) = explode($sep, $date_);
399
400         if ($how > 2)
401         {
402                 global $tmonths;
403                 $month = array_search($month, $tmonths);
404         }
405         if ($year+$day+$month) {
406                 //to modify assumption in 2030
407                 if ($SysPrefs->date_system == 0 || $SysPrefs->date_system == 3)
408                 {
409                         if ((int)$year < 60)
410                         {
411                                 $year = "20".$year;
412                         } 
413                         elseif ((int)$year > 59 && (int)$year < 100)
414                         {
415                                 $year = "19".$year;
416                         }
417                 }
418                 if ((int)$year > 9999)
419                 {
420                         return 0;
421                 }
422                 if ($SysPrefs->date_system == 1)
423                         list($year, $month, $day) = jalali_to_gregorian($year, $month, $day); 
424                 elseif ($SysPrefs->date_system == 2)
425                         list($year, $month, $day) = islamic_to_gregorian($year, $month, $day); 
426         }
427         return sprintf("%04d-%02d-%02d", $year, $month, $day);
428 }// end of function
429
430 /**
431  *      Compare dates in sql format.
432  *      Return +1 if sql date1>date2, -1 if date1<date2,
433  *  or 0 if dates are equal.
434  */
435 function sql_date_comp($date1, $date2)
436 {
437         @list($year1, $month1, $day1) = explode("-", $date1);
438         @list($year2, $month2, $day2) = explode("-", $date2);
439
440         if ($year1 != $year2) {
441                 return $year1 < $year2 ? -1 : +1;
442     }
443     elseif ($month1 != $month2) {
444                 return $month1 < $month2 ? -1 : +1;
445         }
446         elseif ($day1 != $day2) {
447                 return $day1 < $day2 ? -1 : +1;
448         }
449         return 0;
450 }
451 /*
452         Compare dates in user format.
453 */
454 function date_comp($date1, $date2)
455 {
456         $date1 = date2sql($date1);
457         $date2 = date2sql($date2);
458
459         return sql_date_comp($date1, $date2);
460 }
461
462 function date1_greater_date2 ($date1, $date2) 
463 {
464
465 /* returns 1 true if date1 is greater than date_ 2 */
466
467         $date1 = date2sql($date1);
468         $date2 = date2sql($date2);
469
470         @list($year1, $month1, $day1) = explode("-", $date1);
471         @list($year2, $month2, $day2) = explode("-", $date2);
472
473         if ($year1 > $year2)
474         {
475                 return 1;
476         }
477         elseif ($year1 == $year2)
478         {
479                 if ($month1 > $month2)
480                 {
481                         return 1;
482                 }
483                 elseif ($month1 == $month2)
484                 {
485                         if ($day1 > $day2)
486                         {
487                                 return 1;
488                         }
489                 }
490         }
491         return 0;
492 }
493
494 function date_diff2 ($date1, $date2, $period) 
495 {
496
497 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
498 months are assumed to be 30 days and years 365.25 days This only works
499 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
500
501         $date1 = date2sql($date1);
502         $date2 = date2sql($date2);
503         list($year1, $month1, $day1) = explode("-", $date1);
504         list($year2, $month2, $day2) = explode("-", $date2);
505
506         $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
507         $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
508         $difference = $stamp1 - $stamp2;
509
510 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
511
512         switch ($period) 
513         {
514                 case "d":
515                         return (int)($difference / (24 * 60 * 60));
516                 case "w":
517                         return (int)($difference / (24 * 60 * 60 * 7));
518                 case "m":
519                         return (int)($difference / (24 * 60 * 60 * 30));
520                 case "s":
521                         return $difference;
522                 case "y":
523                         return (int)($difference / (24 * 60 * 60 * 365.25));
524                 default:
525                         Return 0;
526         }
527 }
528
529 function explode_date_to_dmy($date_)
530 {
531         $date = date2sql($date_);
532         if ($date == "") 
533         {
534                 return array(0,0,0);
535         }
536         list($year, $month, $day) = explode("-", $date);
537         return array($day, $month, $year);
538 }
539
540 function div($a, $b) 
541 {
542     return (int) ($a / $b);
543 }
544 /* Based on convertor to and from Gregorian and Jalali calendars.
545    Copyright (C) 2000  Roozbeh Pournader and Mohammad Toossi 
546    Released under GNU General Public License */
547
548 function gregorian_to_jalali ($g_y, $g_m, $g_d)
549 {
550     $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
551     $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
552
553         $gy = $g_y - 1600;
554         $gm = $g_m - 1;
555         $gd = $g_d - 1;
556
557         $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
558
559         for ($i = 0; $i < $gm; ++$i)
560         $g_day_no += $g_days_in_month[$i];
561         if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
562         /* leap and after Feb */
563         $g_day_no++;
564         $g_day_no += $gd;
565         $j_day_no = $g_day_no - 79;
566
567         $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
568         $j_day_no %= 12053;
569
570         $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
571
572         $j_day_no %= 1461;
573
574         if ($j_day_no >= 366) 
575         {
576         $jy += div($j_day_no - 1, 365);
577         $j_day_no = ($j_day_no - 1) % 365;
578         }
579
580         for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
581         $j_day_no -= $j_days_in_month[$i];
582         $jm = $i + 1;
583         $jd = $j_day_no + 1;
584
585         return array($jy, $jm, $jd);
586 }
587
588 function jalali_to_gregorian($j_y, $j_m, $j_d)
589 {
590     $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
591     $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
592
593         $jy = $j_y - 979;
594         $jm = $j_m - 1;
595         $jd = $j_d - 1;
596
597         $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
598         for ($i = 0; $i < $jm; ++$i)
599         $j_day_no += $j_days_in_month[$i];
600
601         $j_day_no += $jd;
602
603         $g_day_no = $j_day_no + 79;
604
605         $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
606         $g_day_no %= 146097;
607
608         $leap = true;
609         if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
610         {
611         $g_day_no--;
612         $gy += 100 * div($g_day_no,  36524); /* 36524 = 365*100 + 100/4 - 100/100 */
613         $g_day_no %= 36524;
614
615         if ($g_day_no >= 365)
616                 $g_day_no++;
617         else
618                 $leap = false;
619         }
620
621         $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
622         $g_day_no %= 1461;
623
624         if ($g_day_no >= 366) 
625         {
626         $leap = false;
627
628         $g_day_no--;
629         $gy += div($g_day_no, 365);
630         $g_day_no %= 365;
631         }
632
633         for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
634         $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
635         $gm = $i + 1;
636         $gd = $g_day_no + 1;
637
638         return array($gy, $gm, $gd);
639 }
640 /* Based on Hidri Date Script 
641    Released under GNU General Public License */
642 function gregorian_to_islamic($g_y, $g_m, $g_d)
643 {
644         $y = $g_y;   
645         $m = $g_m;
646         $d = $g_d;
647         if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) && 
648                 ($m == 10) && ($d > 14))) 
649         {
650                 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) + 
651                         (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) - 
652                         (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
653         } 
654         else 
655         {
656                 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) + 
657                         (int)((275 * $m) / 9) + $d + 1729777;
658         }
659         $l = $jd - 1948440 + 10632;
660         $n = (int)(($l - 1) / 10631);
661         $l = $l - 10631 * $n + 354;
662         $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) + 
663                 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
664         $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) - 
665                 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
666         $m = (int)((24 * $l) / 709);
667         $d = $l - (int)((709 * $m) / 24);
668         $y = 30 * $n + $j - 30;
669         return array($y, $m, $d);
670 }
671
672 function islamic_to_gregorian($i_y, $i_m, $i_d)
673 {
674         $y = $i_y;   
675         $m = $i_m;
676         $d = $i_d;
677
678         $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
679         if ($jd > 2299160)
680         {
681                 $l = $jd + 68569;
682                 $n = (int)((4 * $l) / 146097);
683                 $l = $l - (int)((146097 * $n + 3) / 4);
684                 $i = (int)((4000 * ($l + 1)) / 1461001);
685                 $l = $l - (int)((1461 * $i) / 4) + 31;
686                 $j = (int)((80 * $l) / 2447);
687                 $d = $l - (int)((2447 * $j) / 80);
688                 $l= (int)($j / 11);
689                 $m = $j + 2 - 12 * $l;
690                 $y = 100 * ($n - 49) + $i + $l;
691         } 
692         else 
693         {
694                 $j = $jd + 1402;
695                 $k = (int)(($j - 1) / 1461);
696                 $l = $j - 1461 * $k;
697                 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
698                 $i = $l - 365 * $n + 30;
699                 $j = (int)((80 * $i) / 2447);
700                 $d = $i - (int)((2447 * $j) / 80);
701                 $i = (int)($j / 11);
702                 $m = $j + 2 - 12 * $i;
703                 $y = 4 * $k + $n + $i - 4716;
704         }
705         return array($y, $m, $d);
706 }