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_);
66 $dd = explode($sep, $date_);
70 $month = array_search($dd[0], $tmonths);
76 $month = array_search($dd[1], $tmonths);
82 $month = array_search($dd[1], $tmonths);
88 elseif (strlen($date) == 6)
92 $day = substr($date,2,2);
93 $month = substr($date,0,2);
94 $year = substr($date,4,2);
98 $day = substr($date,0,2);
99 $month = substr($date,2,2);
100 $year = substr($date,4,2);
104 $day = substr($date,4,2);
105 $month = substr($date,2,2);
106 $year = substr($date,0,2);
109 elseif (strlen($date) == 8)
113 $day = substr($date,2,2);
114 $month = substr($date,0,2);
115 $year = substr($date,4,4);
119 $day = substr($date,0,2);
120 $month = substr($date,2,2);
121 $year = substr($date,4,4);
125 $day = substr($date,6,2);
126 $month = substr($date,4,2);
127 $year = substr($date,0,4);
130 if (!isset($year)|| (int)$year > 9999)
135 if (is_long((int)$day) && is_long((int)$month) && is_long((int)$year))
138 if ($date_system == 1)
139 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
140 elseif ($date_system == 2)
141 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
142 if (checkdate((int)$month, (int)$day, (int)$year))
152 { /*Can't be in an appropriate DefaultDateFormat */
155 } //end of is_date function
164 if ($date_system == 1)
165 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
166 elseif ($date_system == 2)
167 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
168 return __date($year, $month, $day);
173 if (user_date_format() == 0)
174 return date("h:i a");
179 // Retrieve and optionaly set default date for new document.
181 function new_doc_date($date=null)
183 if (isset($date) && $date != '')
184 $_SESSION['_default_date'] = $date;
186 if (!isset($_SESSION['_default_date']) || !sticky_doc_date())
187 $_SESSION['_default_date'] = Today();
189 return $_SESSION['_default_date'];
192 function is_date_in_fiscalyear($date, $convert=false)
194 global $path_to_root;
195 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
199 $date2 = sql2date($date);
203 if ($_SESSION["wa_current_user"]->can_access('SA_MULTIFISCALYEARS')) // allow all open years for this one
204 return is_date_in_fiscalyears($date2, false);
206 $myrow = get_current_fiscalyear();
207 if ($myrow['closed'] == 1)
210 $begin = sql2date($myrow['begin']);
211 $end = sql2date($myrow['end']);
212 if (date1_greater_date2($begin, $date2) || date1_greater_date2($date2, $end))
219 function begin_fiscalyear()
221 global $path_to_root;
222 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
224 $myrow = get_current_fiscalyear();
225 return sql2date($myrow['begin']);
228 function end_fiscalyear()
230 global $path_to_root;
231 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
233 $myrow = get_current_fiscalyear();
234 return sql2date($myrow['end']);
237 function begin_month($date)
240 list($day, $month, $year) = explode_date_to_dmy($date);
241 if ($date_system == 1)
242 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
243 elseif ($date_system == 2)
244 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
245 return __date($year, $month, 1);
248 function days_in_month($month, $year)
252 if ($date_system == 1)
254 $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));
256 elseif ($date_system == 2)
258 $days_in_month = array(30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, (((((11 * $year) + 14) % 30) < 11) ? 30 : 29));
260 else // gregorian date
261 $days_in_month = array(31, ((!($year % 4 ) && (($year % 100) || !($year % 400)))?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
263 return $days_in_month[$month - 1];
266 function end_month($date)
270 list($day, $month, $year) = explode_date_to_dmy($date);
271 if ($date_system == 1)
273 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
275 elseif ($date_system == 2)
277 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
280 return __date($year, $month, days_in_month($month, $year));
283 function add_days($date, $days) // accepts negative values as well
286 list($day, $month, $year) = explode_date_to_dmy($date);
287 $timet = mktime(0,0,0, $month, $day + $days, $year);
288 if ($date_system == 1 || $date_system == 2)
290 if ($date_system == 1)
291 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
292 elseif ($date_system == 2)
293 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
294 return __date($year, $month, $day);
296 list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
297 return __date($year, $month, $day);
300 function add_months($date, $months) // accepts negative values as well
303 list($day, $month, $year) = explode_date_to_dmy($date);
305 $months += $year*12+$month;
306 $month = ($months-1)%12+1;
307 $year = ($months-$month)/12;
309 $timet = mktime(0,0,0, $month, min($day, days_in_month($month, $year)), $year);
311 if ($date_system == 1 || $date_system == 2)
313 if ($date_system == 1)
314 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
315 elseif ($date_system == 2)
316 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
317 return __date($year, $month, $day);
319 list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
320 return __date($year, $month, $day);
323 function add_years($date, $years) // accepts negative values as well
326 list($day, $month, $year) = explode_date_to_dmy($date);
327 $timet = Mktime(0,0,0, $month, $day, $year + $years);
328 if ($date_system == 1 || $date_system == 2)
330 if ($date_system == 1)
331 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
332 elseif ($date_system == 2)
333 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
334 return __date($year, $month, $day);
336 list($year, $month, $day) = explode("-", date("Y-m-d", $timet));
337 return __date($year, $month, $day);
340 //_______________________________________________________________
342 function sql2date($date_)
346 //for MySQL dates are in the format YYYY-mm-dd
348 if (strpos($date_, "/"))
349 { // In MySQL it could be either / or -
350 list($year, $month, $day) = explode("/", $date_);
352 elseif (strpos ($date_, "-"))
354 list($year, $month, $day) = explode("-", $date_);
356 if (!isset($day)) // data format error
359 if (strlen($day) > 4)
360 { /*chop off the time stuff */
361 $day = substr($day, 0, 2);
363 if ($date_system == 1)
364 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
365 elseif ($date_system == 2)
366 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
367 return __date($year, $month, $day);
368 } // end function sql2date
371 function date2sql($date_)
373 global $dateseps, $date_system, $tmonths;
374 /* takes a date in a the format specified in $DefaultDateFormat
375 and converts to a yyyy/mm/dd format */
377 $how = user_date_format();
378 $sep = $dateseps[user_date_sep()];
380 if ($date_ == null || strlen($date_) == 0)
383 $date_ = trim($date_);
384 $year = $month = $day = 0;
385 // Split up the date by the separator based on "how" to split it
386 if ($how == 0 || $how == 3) // MMDDYYYY or MmmDDYYYY
387 list($month, $day, $year) = explode($sep, $date_);
388 elseif ($how == 1 || $how == 4) // DDMMYYYY or DDMmYYYY
389 list($day, $month, $year) = explode($sep, $date_);
390 else // $how == 2 || $how == 5, YYYYMMDD or YYYYMmmDD
391 list($year, $month, $day) = explode($sep, $date_);
395 $month = array_search($month, $tmonths);
397 //to modify assumption in 2030
398 if ($date_system == 0 || $date_system == 3)
404 elseif ((int)$year > 59 && (int)$year < 100)
409 if ((int)$year > 9999)
413 if ($date_system == 1)
414 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
415 elseif ($date_system == 2)
416 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
418 return sprintf("%04d-%02d-%02d", $year, $month, $day);
421 function date1_greater_date2 ($date1, $date2)
424 /* returns 1 true if date1 is greater than date_ 2 */
426 $date1 = date2sql($date1);
427 $date2 = date2sql($date2);
429 @list($year1, $month1, $day1) = explode("-", $date1);
430 @list($year2, $month2, $day2) = explode("-", $date2);
436 elseif ($year1 == $year2)
438 if ($month1 > $month2)
442 elseif ($month1 == $month2)
454 function date_diff2 ($date1, $date2, $period)
457 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
458 months are assumed to be 30 days and years 365.25 days This only works
459 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
461 $date1 = date2sql($date1);
462 $date2 = date2sql($date2);
463 list($year1, $month1, $day1) = explode("-", $date1);
464 list($year2, $month2, $day2) = explode("-", $date2);
466 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
467 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
468 $difference = $stamp1 - $stamp2;
470 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
475 return (int)($difference / (24 * 60 * 60));
477 return (int)($difference / (24 * 60 * 60 * 7));
479 return (int)($difference / (24 * 60 * 60 * 30));
483 return (int)($difference / (24 * 60 * 60 * 365.25));
489 function explode_date_to_dmy($date_)
491 $date = date2sql($date_);
496 list($year, $month, $day) = explode("-", $date);
497 return array($day, $month, $year);
502 return (int) ($a / $b);
504 /* Based on convertor to and from Gregorian and Jalali calendars.
505 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
506 Released under GNU General Public License */
508 function gregorian_to_jalali ($g_y, $g_m, $g_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 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
519 for ($i = 0; $i < $gm; ++$i)
520 $g_day_no += $g_days_in_month[$i];
521 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
522 /* leap and after Feb */
525 $j_day_no = $g_day_no - 79;
527 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
530 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
534 if ($j_day_no >= 366)
536 $jy += div($j_day_no - 1, 365);
537 $j_day_no = ($j_day_no - 1) % 365;
540 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
541 $j_day_no -= $j_days_in_month[$i];
545 return array($jy, $jm, $jd);
548 function jalali_to_gregorian($j_y, $j_m, $j_d)
550 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
551 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
557 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
558 for ($i = 0; $i < $jm; ++$i)
559 $j_day_no += $j_days_in_month[$i];
563 $g_day_no = $j_day_no + 79;
565 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
569 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
572 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
575 if ($g_day_no >= 365)
581 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
584 if ($g_day_no >= 366)
589 $gy += div($g_day_no, 365);
593 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
594 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
598 return array($gy, $gm, $gd);
600 /* Based on Hidri Date Script
601 Released under GNU General Public License */
602 function gregorian_to_islamic($g_y, $g_m, $g_d)
607 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
608 ($m == 10) && ($d > 14)))
610 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
611 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
612 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
616 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
617 (int)((275 * $m) / 9) + $d + 1729777;
619 $l = $jd - 1948440 + 10632;
620 $n = (int)(($l - 1) / 10631);
621 $l = $l - 10631 * $n + 354;
622 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
623 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
624 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
625 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
626 $m = (int)((24 * $l) / 709);
627 $d = $l - (int)((709 * $m) / 24);
628 $y = 30 * $n + $j - 30;
629 return array($y, $m, $d);
632 function islamic_to_gregorian($i_y, $i_m, $i_d)
638 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
642 $n = (int)((4 * $l) / 146097);
643 $l = $l - (int)((146097 * $n + 3) / 4);
644 $i = (int)((4000 * ($l + 1)) / 1461001);
645 $l = $l - (int)((1461 * $i) / 4) + 31;
646 $j = (int)((80 * $l) / 2447);
647 $d = $l - (int)((2447 * $j) / 80);
649 $m = $j + 2 - 12 * $l;
650 $y = 100 * ($n - 49) + $i + $l;
655 $k = (int)(($j - 1) / 1461);
657 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
658 $i = $l - 365 * $n + 30;
659 $j = (int)((80 * $i) / 2447);
660 $d = $i - (int)((2447 * $j) / 80);
662 $m = $j + 2 - 12 * $i;
663 $y = 4 * $k + $n + $i - 4716;
665 return array($y, $m, $d);