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 return date(user_date_display(), $timet);
298 function add_months($date, $months) // accepts negative values as well
301 list($day, $month, $year) = explode_date_to_dmy($date);
303 $months += $year*12+$month;
304 $month = ($months-1)%12+1;
305 $year = ($months-$month)/12;
307 $timet = mktime(0,0,0, $month, min($day, days_in_month($month, $year)), $year);
309 if ($date_system == 1 || $date_system == 2)
311 if ($date_system == 1)
312 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
313 elseif ($date_system == 2)
314 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
315 return __date($year, $month, $day);
317 return date(user_date_display(), $timet);
320 function add_years($date, $years) // accepts negative values as well
323 list($day, $month, $year) = explode_date_to_dmy($date);
324 $timet = Mktime(0,0,0, $month, $day, $year + $years);
325 if ($date_system == 1 || $date_system == 2)
327 if ($date_system == 1)
328 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
329 elseif ($date_system == 2)
330 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
331 return __date($year, $month, $day);
333 return date(user_date_display(), $timet);
336 //_______________________________________________________________
338 function sql2date($date_)
342 //for MySQL dates are in the format YYYY-mm-dd
343 if ($date_ == null || strlen($date_) == 0)
346 if (strpos($date_, "/"))
347 { // In MySQL it could be either / or -
348 list($year, $month, $day) = explode("/", $date_);
350 elseif (strpos ($date_, "-"))
352 list($year, $month, $day) = explode("-", $date_);
355 if (strlen($day) > 4)
356 { /*chop off the time stuff */
357 $day = substr($day, 0, 2);
359 if ($date_system == 1)
360 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
361 elseif ($date_system == 2)
362 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
363 return __date($year, $month, $day);
364 } // end function sql2date
367 function date2sql($date_)
369 global $dateseps, $date_system, $tmonths;
370 /* takes a date in a the format specified in $DefaultDateFormat
371 and converts to a yyyy/mm/dd format */
373 $how = user_date_format();
374 $sep = $dateseps[user_date_sep()];
376 if ($date_ == null || strlen($date_) == 0)
379 $date_ = trim($date_);
380 $year = $month = $day = 0;
381 // Split up the date by the separator based on "how" to split it
382 if ($how == 0 || $how == 3) // MMDDYYYY or MmmDDYYYY
383 list($month, $day, $year) = explode($sep, $date_);
384 elseif ($how == 1 || $how == 4) // DDMMYYYY or DDMmYYYY
385 list($day, $month, $year) = explode($sep, $date_);
386 else // $how == 2 || $how == 5, YYYYMMDD or YYYYMmmDD
387 list($year, $month, $day) = explode($sep, $date_);
391 $month = array_search($month, $tmonths);
393 //to modify assumption in 2030
394 if ($date_system == 0 || $date_system == 3)
400 elseif ((int)$year > 59 && (int)$year < 100)
405 if ((int)$year > 9999)
409 if ($date_system == 1)
410 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
411 elseif ($date_system == 2)
412 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
414 return sprintf("%04d-%02d-%02d", $year, $month, $day);
417 function date1_greater_date2 ($date1, $date2)
420 /* returns 1 true if date1 is greater than date_ 2 */
422 $date1 = date2sql($date1);
423 $date2 = date2sql($date2);
425 @list($year1, $month1, $day1) = explode("-", $date1);
426 @list($year2, $month2, $day2) = explode("-", $date2);
432 elseif ($year1 == $year2)
434 if ($month1 > $month2)
438 elseif ($month1 == $month2)
450 function date_diff2 ($date1, $date2, $period)
453 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
454 months are assumed to be 30 days and years 365.25 days This only works
455 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
457 $date1 = date2sql($date1);
458 $date2 = date2sql($date2);
459 list($year1, $month1, $day1) = explode("-", $date1);
460 list($year2, $month2, $day2) = explode("-", $date2);
462 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
463 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
464 $difference = $stamp1 - $stamp2;
466 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
471 return (int)($difference / (24 * 60 * 60));
473 return (int)($difference / (24 * 60 * 60 * 7));
475 return (int)($difference / (24 * 60 * 60 * 30));
479 return (int)($difference / (24 * 60 * 60 * 365.25));
485 function explode_date_to_dmy($date_)
487 $date = date2sql($date_);
492 list($year, $month, $day) = explode("-", $date);
493 return array($day, $month, $year);
498 return (int) ($a / $b);
500 /* Based on convertor to and from Gregorian and Jalali calendars.
501 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
502 Released under GNU General Public License */
504 function gregorian_to_jalali ($g_y, $g_m, $g_d)
506 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
507 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
513 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
515 for ($i = 0; $i < $gm; ++$i)
516 $g_day_no += $g_days_in_month[$i];
517 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
518 /* leap and after Feb */
521 $j_day_no = $g_day_no - 79;
523 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
526 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
530 if ($j_day_no >= 366)
532 $jy += div($j_day_no - 1, 365);
533 $j_day_no = ($j_day_no - 1) % 365;
536 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
537 $j_day_no -= $j_days_in_month[$i];
541 return array($jy, $jm, $jd);
544 function jalali_to_gregorian($j_y, $j_m, $j_d)
546 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
547 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
553 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
554 for ($i = 0; $i < $jm; ++$i)
555 $j_day_no += $j_days_in_month[$i];
559 $g_day_no = $j_day_no + 79;
561 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
565 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
568 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
571 if ($g_day_no >= 365)
577 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
580 if ($g_day_no >= 366)
585 $gy += div($g_day_no, 365);
589 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
590 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
594 return array($gy, $gm, $gd);
596 /* Based on Hidri Date Script
597 Released under GNU General Public License */
598 function gregorian_to_islamic($g_y, $g_m, $g_d)
603 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
604 ($m == 10) && ($d > 14)))
606 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
607 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
608 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
612 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
613 (int)((275 * $m) / 9) + $d + 1729777;
615 $l = $jd - 1948440 + 10632;
616 $n = (int)(($l - 1) / 10631);
617 $l = $l - 10631 * $n + 354;
618 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
619 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
620 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
621 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
622 $m = (int)((24 * $l) / 709);
623 $d = $l - (int)((709 * $m) / 24);
624 $y = 30 * $n + $j - 30;
625 return array($y, $m, $d);
628 function islamic_to_gregorian($i_y, $i_m, $i_d)
634 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
638 $n = (int)((4 * $l) / 146097);
639 $l = $l - (int)((146097 * $n + 3) / 4);
640 $i = (int)((4000 * ($l + 1)) / 1461001);
641 $l = $l - (int)((1461 * $i) / 4) + 31;
642 $j = (int)((80 * $l) / 2447);
643 $d = $l - (int)((2447 * $j) / 80);
645 $m = $j + 2 - 12 * $l;
646 $y = 100 * ($n - 49) + $i + $l;
651 $k = (int)(($j - 1) / 1461);
653 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
654 $i = $l - 365 * $n + 30;
655 $j = (int)((80 * $i) / 2447);
656 $d = $i - (int)((2447 * $j) / 80);
658 $m = $j + 2 - 12 * $i;
659 $y = 4 * $k + $n + $i - 4716;
661 return array($y, $m, $d);