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 ***********************************************************************/
13 date validation and parsing functions
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.
22 function __date($year, $month, $day)
26 $how = user_date_format();
27 $sep = $dateseps[user_date_sep()];
35 return $month.$sep.$day.$sep.$year;
37 return $day.$sep.$month.$sep.$year;
39 return $year.$sep.$month.$sep.$day;
42 function is_date($date_)
46 if ($date_ == null || $date_ == "")
48 $how = user_date_format();
49 $sep = $dateseps[user_date_sep()];
51 $date_ = trim($date_);
52 $date_ = str_replace($sep, "", $date_);
53 if (strlen($date_) == 6)
57 $day = substr($date_,2,2);
58 $month = substr($date_,0,2);
59 $year = substr($date_,4,2);
63 $day = substr($date_,0,2);
64 $month = substr($date_,2,2);
65 $year = substr($date_,4,2);
69 $day = substr($date_,4,2);
70 $month = substr($date_,2,2);
71 $year = substr($date_,0,2);
74 elseif (strlen($date_) == 8)
78 $day = substr($date_,2,2);
79 $month = substr($date_,0,2);
80 $year = substr($date_,4,4);
84 $day = substr($date_,0,2);
85 $month = substr($date_,2,2);
86 $year = substr($date_,4,4);
90 $day = substr($date_,6,2);
91 $month = substr($date_,4,2);
92 $year = substr($date_,0,4);
95 if (!isset($year)|| (int)$year > 9999)
101 if (is_long((int)$day) && is_long((int)$month) && is_long((int)$year))
104 if ($date_system == 1)
105 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
106 elseif ($date_system == 2)
107 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
108 if (checkdate((int)$month, (int)$day, (int)$year))
118 { /*Can't be in an appropriate DefaultDateFormat */
121 } //end of is_date function
130 if ($date_system == 1)
131 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
132 elseif ($date_system == 2)
133 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
134 return __date($year, $month, $day);
139 if (user_date_format() == 0)
140 return date("h:i a");
145 // Retrieve and optionaly set default date for new document.
147 function new_doc_date($date=null)
149 if (isset($date) && $date != '')
150 $_SESSION['_default_date'] = $date;
152 if (!isset($_SESSION['_default_date']) || !sticky_doc_date())
153 $_SESSION['_default_date'] = Today();
155 return $_SESSION['_default_date'];
158 function is_date_in_fiscalyear($date, $convert=false)
160 global $path_to_root;
161 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
165 $date2 = sql2date($date);
169 if ($_SESSION["wa_current_user"]->can_access('SA_MULTIFISCALYEARS')) // allow all open years for this one
170 return is_date_in_fiscalyears($date2, false);
172 $myrow = get_current_fiscalyear();
173 if ($myrow['closed'] == 1)
176 $begin = sql2date($myrow['begin']);
177 $end = sql2date($myrow['end']);
178 if (date1_greater_date2($begin, $date2) || date1_greater_date2($date2, $end))
185 function begin_fiscalyear()
187 global $path_to_root;
188 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
190 $myrow = get_current_fiscalyear();
191 return sql2date($myrow['begin']);
194 function end_fiscalyear()
196 global $path_to_root;
197 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
199 $myrow = get_current_fiscalyear();
200 return sql2date($myrow['end']);
203 function begin_month($date)
206 list($day, $month, $year) = explode_date_to_dmy($date);
207 if ($date_system == 1)
208 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
209 elseif ($date_system == 2)
210 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
211 return __date($year, $month, 1);
214 function days_in_month($month, $year)
218 if ($date_system == 1)
220 $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));
222 elseif ($date_system == 2)
224 $days_in_month = array(30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, (((((11 * $year) + 14) % 30) < 11) ? 30 : 29));
226 else // gregorian date
227 $days_in_month = array(31, ((!($year % 4 ) && (($year % 100) || !($year % 400)))?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
229 return $days_in_month[$month - 1];
232 function end_month($date)
236 list($day, $month, $year) = explode_date_to_dmy($date);
237 if ($date_system == 1)
239 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
241 elseif ($date_system == 2)
243 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
246 return __date($year, $month, days_in_month($month, $year));
249 function add_days($date, $days) // accepts negative values as well
252 list($day, $month, $year) = explode_date_to_dmy($date);
253 $timet = mktime(0,0,0, $month, $day + $days, $year);
254 if ($date_system == 1 || $date_system == 2)
256 if ($date_system == 1)
257 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
258 elseif ($date_system == 2)
259 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
260 return __date($year, $month, $day);
262 return date(user_date_display(), $timet);
265 function add_months($date, $months) // accepts negative values as well
268 list($day, $month, $year) = explode_date_to_dmy($date);
271 $year += ($month-1)/12;
272 $month = ($month-1)%12 + 1;
274 $timet = mktime(0,0,0, $month, min($day, days_in_month($month, $year)), $year);
276 if ($date_system == 1 || $date_system == 2)
278 if ($date_system == 1)
279 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
280 elseif ($date_system == 2)
281 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
282 return __date($year, $month, $day);
284 return date(user_date_display(), $timet);
287 function add_years($date, $years) // accepts negative values as well
290 list($day, $month, $year) = explode_date_to_dmy($date);
291 $timet = Mktime(0,0,0, $month, $day, $year + $years);
292 if ($date_system == 1 || $date_system == 2)
294 if ($date_system == 1)
295 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
296 elseif ($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);
300 return date(user_date_display(), $timet);
303 //_______________________________________________________________
305 function sql2date($date_)
309 //for MySQL dates are in the format YYYY-mm-dd
310 if ($date_ == null || strlen($date_) == 0)
313 if (strpos($date_, "/"))
314 { // In MySQL it could be either / or -
315 list($year, $month, $day) = explode("/", $date_);
317 elseif (strpos ($date_, "-"))
319 list($year, $month, $day) = explode("-", $date_);
322 if (strlen($day) > 4)
323 { /*chop off the time stuff */
324 $day = substr($day, 0, 2);
326 if ($date_system == 1)
327 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
328 elseif ($date_system == 2)
329 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
330 return __date($year, $month, $day);
331 } // end function sql2date
334 function date2sql($date_)
336 global $dateseps, $date_system;
337 /* takes a date in a the format specified in $DefaultDateFormat
338 and converts to a yyyy/mm/dd format */
340 $how = user_date_format();
341 $sep = $dateseps[user_date_sep()];
343 if ($date_ == null || strlen($date_) == 0)
346 $date_ = trim($date_);
347 $year = $month = $day = 0;
349 // Split up the date by the separator based on "how" to split it
350 if ($how == 0) // MMDDYYYY
351 list($month, $day, $year) = explode($sep, $date_);
352 elseif ($how == 1) // DDMMYYYY
353 list($day, $month, $year) = explode($sep, $date_);
354 else // $how == 2, YYYYMMDD
355 list($year, $month, $day) = explode($sep, $date_);
357 //to modify assumption in 2030
358 if ($date_system == 0 || $date_system == 3)
364 elseif ((int)$year > 59 && (int)$year < 100)
369 if ((int)$year > 9999)
373 if ($date_system == 1)
374 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
375 elseif ($date_system == 2)
376 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
378 return sprintf("%04d-%02d-%02d", $year, $month, $day);
381 function date1_greater_date2 ($date1, $date2)
384 /* returns 1 true if date1 is greater than date_ 2 */
386 $date1 = date2sql($date1);
387 $date2 = date2sql($date2);
389 @list($year1, $month1, $day1) = explode("-", $date1);
390 @list($year2, $month2, $day2) = explode("-", $date2);
396 elseif ($year1 == $year2)
398 if ($month1 > $month2)
402 elseif ($month1 == $month2)
414 function date_diff2 ($date1, $date2, $period)
417 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
418 months are assumed to be 30 days and years 365.25 days This only works
419 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
421 $date1 = date2sql($date1);
422 $date2 = date2sql($date2);
423 list($year1, $month1, $day1) = explode("-", $date1);
424 list($year2, $month2, $day2) = explode("-", $date2);
426 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
427 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
428 $difference = $stamp1 - $stamp2;
430 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
435 return (int)($difference / (24 * 60 * 60));
437 return (int)($difference / (24 * 60 * 60 * 7));
439 return (int)($difference / (24 * 60 * 60 * 30));
443 return (int)($difference / (24 * 60 * 60 * 365.25));
449 function explode_date_to_dmy($date_)
451 $date = date2sql($date_);
456 list($year, $month, $day) = explode("-", $date);
457 return array($day, $month, $year);
462 return (int) ($a / $b);
464 /* Based on convertor to and from Gregorian and Jalali calendars.
465 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
466 Released under GNU General Public License */
468 function gregorian_to_jalali ($g_y, $g_m, $g_d)
470 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
471 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
477 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
479 for ($i = 0; $i < $gm; ++$i)
480 $g_day_no += $g_days_in_month[$i];
481 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
482 /* leap and after Feb */
485 $j_day_no = $g_day_no - 79;
487 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
490 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
494 if ($j_day_no >= 366)
496 $jy += div($j_day_no - 1, 365);
497 $j_day_no = ($j_day_no - 1) % 365;
500 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
501 $j_day_no -= $j_days_in_month[$i];
505 return array($jy, $jm, $jd);
508 function jalali_to_gregorian($j_y, $j_m, $j_d)
510 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
511 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
517 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
518 for ($i = 0; $i < $jm; ++$i)
519 $j_day_no += $j_days_in_month[$i];
523 $g_day_no = $j_day_no + 79;
525 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
529 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
532 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
535 if ($g_day_no >= 365)
541 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
544 if ($g_day_no >= 366)
549 $gy += div($g_day_no, 365);
553 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
554 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
558 return array($gy, $gm, $gd);
560 /* Based on Hidri Date Script
561 Released under GNU General Public License */
562 function gregorian_to_islamic($g_y, $g_m, $g_d)
567 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
568 ($m == 10) && ($d > 14)))
570 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
571 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
572 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
576 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
577 (int)((275 * $m) / 9) + $d + 1729777;
579 $l = $jd - 1948440 + 10632;
580 $n = (int)(($l - 1) / 10631);
581 $l = $l - 10631 * $n + 354;
582 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
583 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
584 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
585 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
586 $m = (int)((24 * $l) / 709);
587 $d = $l - (int)((709 * $m) / 24);
588 $y = 30 * $n + $j - 30;
589 return array($y, $m, $d);
592 function islamic_to_gregorian($i_y, $i_m, $i_d)
598 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
602 $n = (int)((4 * $l) / 146097);
603 $l = $l - (int)((146097 * $n + 3) / 4);
604 $i = (int)((4000 * ($l + 1)) / 1461001);
605 $l = $l - (int)((1461 * $i) / 4) + 31;
606 $j = (int)((80 * $l) / 2447);
607 $d = $l - (int)((2447 * $j) / 80);
609 $m = $j + 2 - 12 * $l;
610 $y = 100 * ($n - 49) + $i + $l;
615 $k = (int)(($j - 1) / 1461);
617 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
618 $i = $l - 365 * $n + 30;
619 $j = (int)((80 * $i) / 2447);
620 $d = $i - (int)((2447 * $j) / 80);
622 $m = $j + 2 - 12 * $i;
623 $y = 4 * $k + $n + $i - 4716;
625 return array($y, $m, $d);