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");
164 $date2 = sql2date($date);
168 if (user_check_access('SA_MULTIFISCALYEARS')) // allow all open years for this one
169 return is_date_in_fiscalyears($date2, false);
171 if (is_date_closed($date2))
173 $myrow = get_current_fiscalyear();
174 $begin = sql2date($myrow['begin']);
175 $end = sql2date($myrow['end']);
176 if (date1_greater_date2($begin, $date2) || date1_greater_date2($date2, $end))
183 function is_date_closed($date)
185 return !date1_greater_date2($date, sql2date(get_company_pref('gl_closing_date')));
188 function begin_fiscalyear()
190 global $path_to_root;
191 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
193 $myrow = get_current_fiscalyear();
194 return sql2date($myrow['begin']);
197 function end_fiscalyear()
199 global $path_to_root;
200 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
202 $myrow = get_current_fiscalyear();
203 return sql2date($myrow['end']);
206 function begin_month($date)
209 list($day, $month, $year) = explode_date_to_dmy($date);
210 if ($date_system == 1)
211 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
212 elseif ($date_system == 2)
213 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
214 return __date($year, $month, 1);
217 function days_in_month($month, $year)
221 if ($date_system == 1)
223 $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));
225 elseif ($date_system == 2)
227 $days_in_month = array(30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, (((((11 * $year) + 14) % 30) < 11) ? 30 : 29));
229 else // gregorian date
230 $days_in_month = array(31, ((!($year % 4 ) && (($year % 100) || !($year % 400)))?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
232 return $days_in_month[$month - 1];
235 function end_month($date)
239 list($day, $month, $year) = explode_date_to_dmy($date);
240 if ($date_system == 1)
242 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
244 elseif ($date_system == 2)
246 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
249 return __date($year, $month, days_in_month($month, $year));
252 function add_days($date, $days) // accepts negative values as well
255 list($day, $month, $year) = explode_date_to_dmy($date);
256 $timet = mktime(0,0,0, $month, $day + $days, $year);
257 if ($date_system == 1 || $date_system == 2)
259 if ($date_system == 1)
260 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
261 elseif ($date_system == 2)
262 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
263 return __date($year, $month, $day);
265 return date(user_date_display(), $timet);
268 function add_months($date, $months) // accepts negative values as well
271 list($day, $month, $year) = explode_date_to_dmy($date);
273 $months += $year*12+$month;
274 $month = ($months-1)%12+1;
275 $year = ($months-$month)/12;
277 $timet = mktime(0,0,0, $month, min($day, days_in_month($month, $year)), $year);
279 if ($date_system == 1 || $date_system == 2)
281 if ($date_system == 1)
282 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
283 elseif ($date_system == 2)
284 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
285 return __date($year, $month, $day);
287 return date(user_date_display(), $timet);
290 function add_years($date, $years) // accepts negative values as well
293 list($day, $month, $year) = explode_date_to_dmy($date);
294 $timet = Mktime(0,0,0, $month, $day, $year + $years);
295 if ($date_system == 1 || $date_system == 2)
297 if ($date_system == 1)
298 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
299 elseif ($date_system == 2)
300 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
301 return __date($year, $month, $day);
303 return date(user_date_display(), $timet);
306 //_______________________________________________________________
308 function sql2date($date_)
312 //for MySQL dates are in the format YYYY-mm-dd
313 if ($date_ == null || strlen($date_) == 0)
316 if (strpos($date_, "/"))
317 { // In MySQL it could be either / or -
318 list($year, $month, $day) = explode("/", $date_);
320 elseif (strpos ($date_, "-"))
322 list($year, $month, $day) = explode("-", $date_);
325 if (strlen($day) > 4)
326 { /*chop off the time stuff */
327 $day = substr($day, 0, 2);
329 if ($date_system == 1)
330 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
331 elseif ($date_system == 2)
332 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
333 return __date($year, $month, $day);
334 } // end function sql2date
337 function date2sql($date_)
339 global $dateseps, $date_system;
340 /* takes a date in a the format specified in $DefaultDateFormat
341 and converts to a yyyy/mm/dd format */
343 $how = user_date_format();
344 $sep = $dateseps[user_date_sep()];
346 if ($date_ == null || strlen($date_) == 0)
349 $date_ = trim($date_);
350 $year = $month = $day = 0;
352 // Split up the date by the separator based on "how" to split it
353 if ($how == 0) // MMDDYYYY
354 list($month, $day, $year) = explode($sep, $date_);
355 elseif ($how == 1) // DDMMYYYY
356 list($day, $month, $year) = explode($sep, $date_);
357 else // $how == 2, YYYYMMDD
358 list($year, $month, $day) = explode($sep, $date_);
360 //to modify assumption in 2030
361 if ($date_system == 0 || $date_system == 3)
367 elseif ((int)$year > 59 && (int)$year < 100)
372 if ((int)$year > 9999)
376 if ($date_system == 1)
377 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
378 elseif ($date_system == 2)
379 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
381 return sprintf("%04d-%02d-%02d", $year, $month, $day);
384 function date1_greater_date2 ($date1, $date2)
387 /* returns 1 true if date1 is greater than date_ 2 */
389 $date1 = date2sql($date1);
390 $date2 = date2sql($date2);
392 @list($year1, $month1, $day1) = explode("-", $date1);
393 @list($year2, $month2, $day2) = explode("-", $date2);
399 elseif ($year1 == $year2)
401 if ($month1 > $month2)
405 elseif ($month1 == $month2)
417 function date_diff2 ($date1, $date2, $period)
420 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
421 months are assumed to be 30 days and years 365.25 days This only works
422 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
424 $date1 = date2sql($date1);
425 $date2 = date2sql($date2);
426 list($year1, $month1, $day1) = explode("-", $date1);
427 list($year2, $month2, $day2) = explode("-", $date2);
429 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
430 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
431 $difference = $stamp1 - $stamp2;
433 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
438 return (int)($difference / (24 * 60 * 60));
440 return (int)($difference / (24 * 60 * 60 * 7));
442 return (int)($difference / (24 * 60 * 60 * 30));
446 return (int)($difference / (24 * 60 * 60 * 365.25));
452 function explode_date_to_dmy($date_)
454 $date = date2sql($date_);
459 list($year, $month, $day) = explode("-", $date);
460 return array($day, $month, $year);
465 return (int) ($a / $b);
467 /* Based on convertor to and from Gregorian and Jalali calendars.
468 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
469 Released under GNU General Public License */
471 function gregorian_to_jalali ($g_y, $g_m, $g_d)
473 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
474 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
480 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
482 for ($i = 0; $i < $gm; ++$i)
483 $g_day_no += $g_days_in_month[$i];
484 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
485 /* leap and after Feb */
488 $j_day_no = $g_day_no - 79;
490 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
493 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
497 if ($j_day_no >= 366)
499 $jy += div($j_day_no - 1, 365);
500 $j_day_no = ($j_day_no - 1) % 365;
503 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
504 $j_day_no -= $j_days_in_month[$i];
508 return array($jy, $jm, $jd);
511 function jalali_to_gregorian($j_y, $j_m, $j_d)
513 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
514 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
520 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
521 for ($i = 0; $i < $jm; ++$i)
522 $j_day_no += $j_days_in_month[$i];
526 $g_day_no = $j_day_no + 79;
528 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
532 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
535 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
538 if ($g_day_no >= 365)
544 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
547 if ($g_day_no >= 366)
552 $gy += div($g_day_no, 365);
556 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
557 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
561 return array($gy, $gm, $gd);
563 /* Based on Hidri Date Script
564 Released under GNU General Public License */
565 function gregorian_to_islamic($g_y, $g_m, $g_d)
570 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
571 ($m == 10) && ($d > 14)))
573 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
574 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
575 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
579 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
580 (int)((275 * $m) / 9) + $d + 1729777;
582 $l = $jd - 1948440 + 10632;
583 $n = (int)(($l - 1) / 10631);
584 $l = $l - 10631 * $n + 354;
585 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
586 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
587 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
588 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
589 $m = (int)((24 * $l) / 709);
590 $d = $l - (int)((709 * $m) / 24);
591 $y = 30 * $n + $j - 30;
592 return array($y, $m, $d);
595 function islamic_to_gregorian($i_y, $i_m, $i_d)
601 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
605 $n = (int)((4 * $l) / 146097);
606 $l = $l - (int)((146097 * $n + 3) / 4);
607 $i = (int)((4000 * ($l + 1)) / 1461001);
608 $l = $l - (int)((1461 * $i) / 4) + 31;
609 $j = (int)((80 * $l) / 2447);
610 $d = $l - (int)((2447 * $j) / 80);
612 $m = $j + 2 - 12 * $l;
613 $y = 100 * ($n - 49) + $i + $l;
618 $k = (int)(($j - 1) / 1461);
620 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
621 $i = $l - 365 * $n + 30;
622 $j = (int)((80 * $i) / 2447);
623 $d = $i - (int)((2447 * $j) / 80);
625 $m = $j + 2 - 12 * $i;
626 $y = 4 * $k + $n + $i - 4716;
628 return array($y, $m, $d);