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);
269 $months += $year*12+$month;
270 $month = ($months-1)%12+1;
271 $year = ($months-$month)/12;
275 $timet = mktime(0,0,0, $month, min($day, days_in_month($month, $year)), $year);
277 if ($date_system == 1 || $date_system == 2)
279 if ($date_system == 1)
280 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
281 elseif ($date_system == 2)
282 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
283 return __date($year, $month, $day);
285 return date(user_date_display(), $timet);
288 function add_years($date, $years) // accepts negative values as well
291 list($day, $month, $year) = explode_date_to_dmy($date);
292 $timet = Mktime(0,0,0, $month, $day, $year + $years);
293 if ($date_system == 1 || $date_system == 2)
295 if ($date_system == 1)
296 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
297 elseif ($date_system == 2)
298 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
299 return __date($year, $month, $day);
301 return date(user_date_display(), $timet);
304 //_______________________________________________________________
306 function sql2date($date_)
310 //for MySQL dates are in the format YYYY-mm-dd
311 if ($date_ == null || strlen($date_) == 0)
314 if (strpos($date_, "/"))
315 { // In MySQL it could be either / or -
316 list($year, $month, $day) = explode("/", $date_);
318 elseif (strpos ($date_, "-"))
320 list($year, $month, $day) = explode("-", $date_);
323 if (strlen($day) > 4)
324 { /*chop off the time stuff */
325 $day = substr($day, 0, 2);
327 if ($date_system == 1)
328 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
329 elseif ($date_system == 2)
330 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
331 return __date($year, $month, $day);
332 } // end function sql2date
335 function date2sql($date_)
337 global $dateseps, $date_system;
338 /* takes a date in a the format specified in $DefaultDateFormat
339 and converts to a yyyy/mm/dd format */
341 $how = user_date_format();
342 $sep = $dateseps[user_date_sep()];
344 if ($date_ == null || strlen($date_) == 0)
347 $date_ = trim($date_);
348 $year = $month = $day = 0;
350 // Split up the date by the separator based on "how" to split it
351 if ($how == 0) // MMDDYYYY
352 list($month, $day, $year) = explode($sep, $date_);
353 elseif ($how == 1) // DDMMYYYY
354 list($day, $month, $year) = explode($sep, $date_);
355 else // $how == 2, YYYYMMDD
356 list($year, $month, $day) = explode($sep, $date_);
358 //to modify assumption in 2030
359 if ($date_system == 0 || $date_system == 3)
365 elseif ((int)$year > 59 && (int)$year < 100)
370 if ((int)$year > 9999)
374 if ($date_system == 1)
375 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
376 elseif ($date_system == 2)
377 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
379 return sprintf("%04d-%02d-%02d", $year, $month, $day);
382 function date1_greater_date2 ($date1, $date2)
385 /* returns 1 true if date1 is greater than date_ 2 */
387 $date1 = date2sql($date1);
388 $date2 = date2sql($date2);
390 @list($year1, $month1, $day1) = explode("-", $date1);
391 @list($year2, $month2, $day2) = explode("-", $date2);
397 elseif ($year1 == $year2)
399 if ($month1 > $month2)
403 elseif ($month1 == $month2)
415 function date_diff2 ($date1, $date2, $period)
418 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
419 months are assumed to be 30 days and years 365.25 days This only works
420 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
422 $date1 = date2sql($date1);
423 $date2 = date2sql($date2);
424 list($year1, $month1, $day1) = explode("-", $date1);
425 list($year2, $month2, $day2) = explode("-", $date2);
427 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
428 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
429 $difference = $stamp1 - $stamp2;
431 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
436 return (int)($difference / (24 * 60 * 60));
438 return (int)($difference / (24 * 60 * 60 * 7));
440 return (int)($difference / (24 * 60 * 60 * 30));
444 return (int)($difference / (24 * 60 * 60 * 365.25));
450 function explode_date_to_dmy($date_)
452 $date = date2sql($date_);
457 list($year, $month, $day) = explode("-", $date);
458 return array($day, $month, $year);
463 return (int) ($a / $b);
465 /* Based on convertor to and from Gregorian and Jalali calendars.
466 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
467 Released under GNU General Public License */
469 function gregorian_to_jalali ($g_y, $g_m, $g_d)
471 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
472 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
478 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
480 for ($i = 0; $i < $gm; ++$i)
481 $g_day_no += $g_days_in_month[$i];
482 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
483 /* leap and after Feb */
486 $j_day_no = $g_day_no - 79;
488 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
491 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
495 if ($j_day_no >= 366)
497 $jy += div($j_day_no - 1, 365);
498 $j_day_no = ($j_day_no - 1) % 365;
501 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
502 $j_day_no -= $j_days_in_month[$i];
506 return array($jy, $jm, $jd);
509 function jalali_to_gregorian($j_y, $j_m, $j_d)
511 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
512 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
518 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
519 for ($i = 0; $i < $jm; ++$i)
520 $j_day_no += $j_days_in_month[$i];
524 $g_day_no = $j_day_no + 79;
526 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
530 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
533 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
536 if ($g_day_no >= 365)
542 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
545 if ($g_day_no >= 366)
550 $gy += div($g_day_no, 365);
554 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
555 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
559 return array($gy, $gm, $gd);
561 /* Based on Hidri Date Script
562 Released under GNU General Public License */
563 function gregorian_to_islamic($g_y, $g_m, $g_d)
568 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
569 ($m == 10) && ($d > 14)))
571 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
572 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
573 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
577 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
578 (int)((275 * $m) / 9) + $d + 1729777;
580 $l = $jd - 1948440 + 10632;
581 $n = (int)(($l - 1) / 10631);
582 $l = $l - 10631 * $n + 354;
583 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
584 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
585 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
586 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
587 $m = (int)((24 * $l) / 709);
588 $d = $l - (int)((709 * $m) / 24);
589 $y = 30 * $n + $j - 30;
590 return array($y, $m, $d);
593 function islamic_to_gregorian($i_y, $i_m, $i_d)
599 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
603 $n = (int)((4 * $l) / 146097);
604 $l = $l - (int)((146097 * $n + 3) / 4);
605 $i = (int)((4000 * ($l + 1)) / 1461001);
606 $l = $l - (int)((1461 * $i) / 4) + 31;
607 $j = (int)((80 * $l) / 2447);
608 $d = $l - (int)((2447 * $j) / 80);
610 $m = $j + 2 - 12 * $l;
611 $y = 100 * ($n - 49) + $i + $l;
616 $k = (int)(($j - 1) / 1461);
618 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
619 $i = $l - 365 * $n + 30;
620 $j = (int)((80 * $i) / 2447);
621 $d = $i - (int)((2447 * $j) / 80);
623 $m = $j + 2 - 12 * $i;
624 $y = 4 * $k + $n + $i - 4716;
626 return array($y, $m, $d);