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");
163 if (user_check_access('SA_MULTIFISCALYEARS')) // allow all open years for this one
164 return is_date_in_fiscalyears($date, false);
165 if (is_date_closed($date))
167 $myrow = get_current_fiscalyear();
169 $date2 = sql2date($date);
172 $begin = sql2date($myrow['begin']);
173 $end = sql2date($myrow['end']);
174 if (date1_greater_date2($begin, $date2) || date1_greater_date2($date2, $end))
181 function is_date_closed($date)
183 return !date1_greater_date2($date, sql2date(get_company_pref('gl_closing_date')));
186 function begin_fiscalyear()
188 global $path_to_root;
189 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
191 $myrow = get_current_fiscalyear();
192 return sql2date($myrow['begin']);
195 function end_fiscalyear()
197 global $path_to_root;
198 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
200 $myrow = get_current_fiscalyear();
201 return sql2date($myrow['end']);
204 function begin_month($date)
207 list($day, $month, $year) = explode_date_to_dmy($date);
208 if ($date_system == 1)
209 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
210 elseif ($date_system == 2)
211 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
212 return __date($year, $month, 1);
215 function end_month($date)
218 list($day, $month, $year) = explode_date_to_dmy($date);
219 if ($date_system == 1)
221 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
222 $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));
224 elseif ($date_system == 2)
226 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
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);
231 return __date($year, $month, $days_in_month[$month - 1]);
234 function add_days($date, $days) // accepts negative values as well
237 list($day, $month, $year) = explode_date_to_dmy($date);
238 $timet = Mktime(0,0,0, $month, $day + $days, $year);
239 if ($date_system == 1 || $date_system == 2)
241 if ($date_system == 1)
242 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
243 elseif ($date_system == 2)
244 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
245 return __date($year, $month, $day);
247 return date(user_date_display(), $timet);
250 function add_months($date, $months) // accepts negative values as well
253 list($day, $month, $year) = explode_date_to_dmy($date);
254 $timet = Mktime(0,0,0, $month + $months, $day, $year);
255 if ($date_system == 1 || $date_system == 2)
257 if ($date_system == 1)
258 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
259 elseif ($date_system == 2)
260 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
261 return __date($year, $month, $day);
263 return date(user_date_display(), $timet);
266 function add_years($date, $years) // accepts negative values as well
269 list($day, $month, $year) = explode_date_to_dmy($date);
270 $timet = Mktime(0,0,0, $month, $day, $year + $years);
271 if ($date_system == 1 || $date_system == 2)
273 if ($date_system == 1)
274 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
275 elseif ($date_system == 2)
276 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
277 return __date($year, $month, $day);
279 return date(user_date_display(), $timet);
282 //_______________________________________________________________
284 function sql2date($date_)
288 //for MySQL dates are in the format YYYY-mm-dd
289 if ($date_ == null || strlen($date_) == 0)
292 if (strpos($date_, "/"))
293 { // In MySQL it could be either / or -
294 list($year, $month, $day) = explode("/", $date_);
296 elseif (strpos ($date_, "-"))
298 list($year, $month, $day) = explode("-", $date_);
301 if (strlen($day) > 4)
302 { /*chop off the time stuff */
303 $day = substr($day, 0, 2);
305 if ($date_system == 1)
306 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
307 elseif ($date_system == 2)
308 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
309 return __date($year, $month, $day);
310 } // end function sql2date
313 function date2sql($date_)
315 global $dateseps, $date_system;
316 /* takes a date in a the format specified in $DefaultDateFormat
317 and converts to a yyyy/mm/dd format */
319 $how = user_date_format();
320 $sep = $dateseps[user_date_sep()];
322 if ($date_ == null || strlen($date_) == 0)
325 $date_ = trim($date_);
326 $year = $month = $day = 0;
328 // Split up the date by the separator based on "how" to split it
329 if ($how == 0) // MMDDYYYY
330 list($month, $day, $year) = explode($sep, $date_);
331 elseif ($how == 1) // DDMMYYYY
332 list($day, $month, $year) = explode($sep, $date_);
333 else // $how == 2, YYYYMMDD
334 list($year, $month, $day) = explode($sep, $date_);
336 //to modify assumption in 2030
337 if ($date_system == 0 || $date_system == 3)
343 elseif ((int)$year > 59 && (int)$year < 100)
348 if ((int)$year > 9999)
352 if ($date_system == 1)
353 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
354 elseif ($date_system == 2)
355 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
357 return sprintf("%04d-%02d-%02d", $year, $month, $day);
360 function date1_greater_date2 ($date1, $date2)
363 /* returns 1 true if date1 is greater than date_ 2 */
365 $date1 = date2sql($date1);
366 $date2 = date2sql($date2);
368 @list($year1, $month1, $day1) = explode("-", $date1);
369 @list($year2, $month2, $day2) = explode("-", $date2);
375 elseif ($year1 == $year2)
377 if ($month1 > $month2)
381 elseif ($month1 == $month2)
393 function date_diff2 ($date1, $date2, $period)
396 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
397 months are assumed to be 30 days and years 365.25 days This only works
398 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
400 $date1 = date2sql($date1);
401 $date2 = date2sql($date2);
402 list($year1, $month1, $day1) = explode("-", $date1);
403 list($year2, $month2, $day2) = explode("-", $date2);
405 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
406 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
407 $difference = $stamp1 - $stamp2;
409 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
414 return (int)($difference / (24 * 60 * 60));
416 return (int)($difference / (24 * 60 * 60 * 7));
418 return (int)($difference / (24 * 60 * 60 * 30));
422 return (int)($difference / (24 * 60 * 60 * 365.25));
428 function explode_date_to_dmy($date_)
430 $date = date2sql($date_);
435 list($year, $month, $day) = explode("-", $date);
436 return array($day, $month, $year);
441 return (int) ($a / $b);
443 /* Based on convertor to and from Gregorian and Jalali calendars.
444 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
445 Released under GNU General Public License */
447 function gregorian_to_jalali ($g_y, $g_m, $g_d)
449 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
450 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
456 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
458 for ($i = 0; $i < $gm; ++$i)
459 $g_day_no += $g_days_in_month[$i];
460 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
461 /* leap and after Feb */
464 $j_day_no = $g_day_no - 79;
466 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
469 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
473 if ($j_day_no >= 366)
475 $jy += div($j_day_no - 1, 365);
476 $j_day_no = ($j_day_no - 1) % 365;
479 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
480 $j_day_no -= $j_days_in_month[$i];
484 return array($jy, $jm, $jd);
487 function jalali_to_gregorian($j_y, $j_m, $j_d)
489 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
490 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
496 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
497 for ($i = 0; $i < $jm; ++$i)
498 $j_day_no += $j_days_in_month[$i];
502 $g_day_no = $j_day_no + 79;
504 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
508 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
511 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
514 if ($g_day_no >= 365)
520 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
523 if ($g_day_no >= 366)
528 $gy += div($g_day_no, 365);
532 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
533 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
537 return array($gy, $gm, $gd);
539 /* Based on Hidri Date Script
540 Released under GNU General Public License */
541 function gregorian_to_islamic($g_y, $g_m, $g_d)
546 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
547 ($m == 10) && ($d > 14)))
549 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
550 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
551 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
555 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
556 (int)((275 * $m) / 9) + $d + 1729777;
558 $l = $jd - 1948440 + 10632;
559 $n = (int)(($l - 1) / 10631);
560 $l = $l - 10631 * $n + 354;
561 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
562 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
563 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
564 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
565 $m = (int)((24 * $l) / 709);
566 $d = $l - (int)((709 * $m) / 24);
567 $y = 30 * $n + $j - 30;
568 return array($y, $m, $d);
571 function islamic_to_gregorian($i_y, $i_m, $i_d)
577 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
581 $n = (int)((4 * $l) / 146097);
582 $l = $l - (int)((146097 * $n + 3) / 4);
583 $i = (int)((4000 * ($l + 1)) / 1461001);
584 $l = $l - (int)((1461 * $i) / 4) + 31;
585 $j = (int)((80 * $l) / 2447);
586 $d = $l - (int)((2447 * $j) / 80);
588 $m = $j + 2 - 12 * $l;
589 $y = 100 * ($n - 49) + $i + $l;
594 $k = (int)(($j - 1) / 1461);
596 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
597 $i = $l - 365 * $n + 30;
598 $j = (int)((80 * $i) / 2447);
599 $d = $i - (int)((2447 * $j) / 80);
601 $m = $j + 2 - 12 * $i;
602 $y = 4 * $k + $n + $i - 4716;
604 return array($y, $m, $d);