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)
24 global $dateseps, $tmonths;
26 $how = user_date_format();
27 $sep = $dateseps[user_date_sep()];
38 return $month.$sep.$day.$sep.$year;
40 return $day.$sep.$month.$sep.$year;
42 return $year.$sep.$month.$sep.$day;
44 return $tmonths[$month].$sep.$day.$sep.$year;
46 return $day.$sep.$tmonths[$month].$sep.$year;
48 return $year.$sep.$tmonths[$month].$sep.$day;
51 function is_date($date_)
55 if ($date_ == null || $date_ == "")
57 $how = user_date_format();
58 $sep = $dateseps[user_date_sep()];
60 $date_ = trim($date_);
61 $date = str_replace($sep, "", $date_);
62 if (strlen($date_) == 6)
66 $day = substr($date,2,2);
67 $month = substr($date,0,2);
68 $year = substr($date,4,2);
72 $day = substr($date,0,2);
73 $month = substr($date,2,2);
74 $year = substr($date,4,2);
78 $day = substr($date,4,2);
79 $month = substr($date,2,2);
80 $year = substr($date,0,2);
83 elseif (strlen($date_) == 8)
87 $day = substr($date,2,2);
88 $month = substr($date,0,2);
89 $year = substr($date,4,4);
93 $day = substr($date,0,2);
94 $month = substr($date,2,2);
95 $year = substr($date,4,4);
99 $day = substr($date,6,2);
100 $month = substr($date,4,2);
101 $year = substr($date,0,4);
107 $dd = explode($sep, $date_);
111 $month = array_search($dd[0], $tmonths);
117 $month = array_search($dd[1], $tmonths);
123 $month = array_search($dd[1], $tmonths);
129 if (!isset($year)|| (int)$year > 9999)
134 if (is_long((int)$day) && is_long((int)$month) && is_long((int)$year))
137 if ($date_system == 1)
138 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
139 elseif ($date_system == 2)
140 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
141 if (checkdate((int)$month, (int)$day, (int)$year))
151 { /*Can't be in an appropriate DefaultDateFormat */
154 } //end of is_date function
163 if ($date_system == 1)
164 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
165 elseif ($date_system == 2)
166 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
167 return __date($year, $month, $day);
172 if (user_date_format() == 0)
173 return date("h:i a");
178 // Retrieve and optionaly set default date for new document.
180 function new_doc_date($date=null)
182 if (isset($date) && $date != '')
183 $_SESSION['_default_date'] = $date;
185 if (!isset($_SESSION['_default_date']) || !sticky_doc_date())
186 $_SESSION['_default_date'] = Today();
188 return $_SESSION['_default_date'];
191 function is_date_in_fiscalyear($date, $convert=false)
193 global $path_to_root;
194 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
198 $date2 = sql2date($date);
202 if ($_SESSION["wa_current_user"]->can_access('SA_MULTIFISCALYEARS')) // allow all open years for this one
203 return is_date_in_fiscalyears($date2, false);
205 $myrow = get_current_fiscalyear();
206 if ($myrow['closed'] == 1)
209 $begin = sql2date($myrow['begin']);
210 $end = sql2date($myrow['end']);
211 if (date1_greater_date2($begin, $date2) || date1_greater_date2($date2, $end))
218 function begin_fiscalyear()
220 global $path_to_root;
221 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
223 $myrow = get_current_fiscalyear();
224 return sql2date($myrow['begin']);
227 function end_fiscalyear()
229 global $path_to_root;
230 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
232 $myrow = get_current_fiscalyear();
233 return sql2date($myrow['end']);
236 function begin_month($date)
239 list($day, $month, $year) = explode_date_to_dmy($date);
240 if ($date_system == 1)
241 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
242 elseif ($date_system == 2)
243 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
244 return __date($year, $month, 1);
247 function days_in_month($month, $year)
251 if ($date_system == 1)
253 $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));
255 elseif ($date_system == 2)
257 $days_in_month = array(30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, (((((11 * $year) + 14) % 30) < 11) ? 30 : 29));
259 else // gregorian date
260 $days_in_month = array(31, ((!($year % 4 ) && (($year % 100) || !($year % 400)))?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
262 return $days_in_month[$month - 1];
265 function end_month($date)
269 list($day, $month, $year) = explode_date_to_dmy($date);
270 if ($date_system == 1)
272 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
274 elseif ($date_system == 2)
276 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
279 return __date($year, $month, days_in_month($month, $year));
282 function add_days($date, $days) // accepts negative values as well
285 list($day, $month, $year) = explode_date_to_dmy($date);
286 $timet = mktime(0,0,0, $month, $day + $days, $year);
287 if ($date_system == 1 || $date_system == 2)
289 if ($date_system == 1)
290 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
291 elseif ($date_system == 2)
292 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
293 return __date($year, $month, $day);
295 list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
296 return __date($year, $month, $day);
299 function add_months($date, $months) // accepts negative values as well
302 list($day, $month, $year) = explode_date_to_dmy($date);
304 $months += $year*12+$month;
305 $month = ($months-1)%12+1;
306 $year = ($months-$month)/12;
308 $timet = mktime(0,0,0, $month, min($day, days_in_month($month, $year)), $year);
310 if ($date_system == 1 || $date_system == 2)
312 if ($date_system == 1)
313 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
314 elseif ($date_system == 2)
315 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
316 return __date($year, $month, $day);
318 list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
319 return __date($year, $month, $day);
322 function add_years($date, $years) // accepts negative values as well
325 list($day, $month, $year) = explode_date_to_dmy($date);
326 $timet = Mktime(0,0,0, $month, $day, $year + $years);
327 if ($date_system == 1 || $date_system == 2)
329 if ($date_system == 1)
330 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
331 elseif ($date_system == 2)
332 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
333 return __date($year, $month, $day);
335 list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
336 return __date($year, $month, $day);
339 //_______________________________________________________________
341 function sql2date($date_)
345 //for MySQL dates are in the format YYYY-mm-dd
346 if ($date_ == null || strlen($date_) == 0)
349 if (strpos($date_, "/"))
350 { // In MySQL it could be either / or -
351 list($year, $month, $day) = explode("/", $date_);
353 elseif (strpos ($date_, "-"))
355 list($year, $month, $day) = explode("-", $date_);
358 if (strlen($day) > 4)
359 { /*chop off the time stuff */
360 $day = substr($day, 0, 2);
362 if ($date_system == 1)
363 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
364 elseif ($date_system == 2)
365 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
366 return __date($year, $month, $day);
367 } // end function sql2date
370 function date2sql($date_)
372 global $dateseps, $date_system, $tmonths;
373 /* takes a date in a the format specified in $DefaultDateFormat
374 and converts to a yyyy/mm/dd format */
376 $how = user_date_format();
377 $sep = $dateseps[user_date_sep()];
379 if ($date_ == null || strlen($date_) == 0)
382 $date_ = trim($date_);
383 $year = $month = $day = 0;
384 // Split up the date by the separator based on "how" to split it
385 if ($how == 0 || $how == 3) // MMDDYYYY or MmmDDYYYY
386 list($month, $day, $year) = explode($sep, $date_);
387 elseif ($how == 1 || $how == 4) // DDMMYYYY or DDMmYYYY
388 list($day, $month, $year) = explode($sep, $date_);
389 else // $how == 2 || $how == 5, YYYYMMDD or YYYYMmmDD
390 list($year, $month, $day) = explode($sep, $date_);
394 $month = array_search($month, $tmonths);
396 //to modify assumption in 2030
397 if ($date_system == 0 || $date_system == 3)
403 elseif ((int)$year > 59 && (int)$year < 100)
408 if ((int)$year > 9999)
412 if ($date_system == 1)
413 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
414 elseif ($date_system == 2)
415 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
417 return sprintf("%04d-%02d-%02d", $year, $month, $day);
420 function date1_greater_date2 ($date1, $date2)
423 /* returns 1 true if date1 is greater than date_ 2 */
425 $date1 = date2sql($date1);
426 $date2 = date2sql($date2);
428 @list($year1, $month1, $day1) = explode("-", $date1);
429 @list($year2, $month2, $day2) = explode("-", $date2);
435 elseif ($year1 == $year2)
437 if ($month1 > $month2)
441 elseif ($month1 == $month2)
453 function date_diff2 ($date1, $date2, $period)
456 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
457 months are assumed to be 30 days and years 365.25 days This only works
458 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
460 $date1 = date2sql($date1);
461 $date2 = date2sql($date2);
462 list($year1, $month1, $day1) = explode("-", $date1);
463 list($year2, $month2, $day2) = explode("-", $date2);
465 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
466 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
467 $difference = $stamp1 - $stamp2;
469 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
474 return (int)($difference / (24 * 60 * 60));
476 return (int)($difference / (24 * 60 * 60 * 7));
478 return (int)($difference / (24 * 60 * 60 * 30));
482 return (int)($difference / (24 * 60 * 60 * 365.25));
488 function explode_date_to_dmy($date_)
490 $date = date2sql($date_);
495 list($year, $month, $day) = explode("-", $date);
496 return array($day, $month, $year);
501 return (int) ($a / $b);
503 /* Based on convertor to and from Gregorian and Jalali calendars.
504 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
505 Released under GNU General Public License */
507 function gregorian_to_jalali ($g_y, $g_m, $g_d)
509 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
510 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
516 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
518 for ($i = 0; $i < $gm; ++$i)
519 $g_day_no += $g_days_in_month[$i];
520 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
521 /* leap and after Feb */
524 $j_day_no = $g_day_no - 79;
526 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
529 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
533 if ($j_day_no >= 366)
535 $jy += div($j_day_no - 1, 365);
536 $j_day_no = ($j_day_no - 1) % 365;
539 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
540 $j_day_no -= $j_days_in_month[$i];
544 return array($jy, $jm, $jd);
547 function jalali_to_gregorian($j_y, $j_m, $j_d)
549 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
550 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
556 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
557 for ($i = 0; $i < $jm; ++$i)
558 $j_day_no += $j_days_in_month[$i];
562 $g_day_no = $j_day_no + 79;
564 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
568 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
571 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
574 if ($g_day_no >= 365)
580 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
583 if ($g_day_no >= 366)
588 $gy += div($g_day_no, 365);
592 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
593 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
597 return array($gy, $gm, $gd);
599 /* Based on Hidri Date Script
600 Released under GNU General Public License */
601 function gregorian_to_islamic($g_y, $g_m, $g_d)
606 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
607 ($m == 10) && ($d > 14)))
609 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
610 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
611 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
615 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
616 (int)((275 * $m) / 9) + $d + 1729777;
618 $l = $jd - 1948440 + 10632;
619 $n = (int)(($l - 1) / 10631);
620 $l = $l - 10631 * $n + 354;
621 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
622 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
623 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
624 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
625 $m = (int)((24 * $l) / 709);
626 $d = $l - (int)((709 * $m) / 24);
627 $y = 30 * $n + $j - 30;
628 return array($y, $m, $d);
631 function islamic_to_gregorian($i_y, $i_m, $i_d)
637 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
641 $n = (int)((4 * $l) / 146097);
642 $l = $l - (int)((146097 * $n + 3) / 4);
643 $i = (int)((4000 * ($l + 1)) / 1461001);
644 $l = $l - (int)((1461 * $i) / 4) + 31;
645 $j = (int)((80 * $l) / 2447);
646 $d = $l - (int)((2447 * $j) / 80);
648 $m = $j + 2 - 12 * $l;
649 $y = 100 * ($n - 49) + $i + $l;
654 $k = (int)(($j - 1) / 1461);
656 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
657 $i = $l - 365 * $n + 30;
658 $j = (int)((80 * $i) / 2447);
659 $d = $i - (int)((2447 * $j) / 80);
661 $m = $j + 2 - 12 * $i;
662 $y = 4 * $k + $n + $i - 4716;
664 return array($y, $m, $d);