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