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.
21 if(function_exists("date_default_timezone_set") && function_exists("date_default_timezone_get"))
22 @date_default_timezone_set(@date_default_timezone_get());
24 function __date($year, $month, $day)
28 $how = user_date_format();
29 $sep = $dateseps[user_date_sep()];
37 return $month.$sep.$day.$sep.$year;
39 return $day.$sep.$month.$sep.$year;
41 return $year.$sep.$month.$sep.$day;
44 function is_date($date_)
48 if ($date_ == null || $date_ == "")
50 $how = user_date_format();
51 $sep = $dateseps[user_date_sep()];
53 $date_ = trim($date_);
54 $date_ = str_replace($sep, "", $date_);
55 if (strlen($date_) == 6)
59 $day = substr($date_,2,2);
60 $month = substr($date_,0,2);
61 $year = substr($date_,4,2);
65 $day = substr($date_,0,2);
66 $month = substr($date_,2,2);
67 $year = substr($date_,4,2);
71 $day = substr($date_,4,2);
72 $month = substr($date_,2,2);
73 $year = substr($date_,0,2);
76 elseif (strlen($date_) == 8)
80 $day = substr($date_,2,2);
81 $month = substr($date_,0,2);
82 $year = substr($date_,4,4);
86 $day = substr($date_,0,2);
87 $month = substr($date_,2,2);
88 $year = substr($date_,4,4);
92 $day = substr($date_,6,2);
93 $month = substr($date_,4,2);
94 $year = substr($date_,0,4);
97 if (!isset($year)|| (int)$year > 9999)
103 if (is_long((int)$day) && is_long((int)$month) && is_long((int)$year))
106 if ($date_system == 1)
107 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
108 elseif ($date_system == 2)
109 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
110 if (checkdate((int)$month, (int)$day, (int)$year))
120 { /*Can't be in an appropriate DefaultDateFormat */
123 } //end of is_date function
132 if ($date_system == 1)
133 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
134 elseif ($date_system == 2)
135 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
136 return __date($year, $month, $day);
141 if (user_date_format() == 0)
142 return date("h:i a");
147 // Retrieve and optionaly set default date for new document.
149 function new_doc_date($date=null)
151 if (isset($date) && $date != '')
152 $_SESSION['_default_date'] = $date;
154 if (!isset($_SESSION['_default_date']) || !sticky_doc_date())
155 $_SESSION['_default_date'] = Today();
157 return $_SESSION['_default_date'];
160 function is_date_in_fiscalyear($date, $convert=false)
162 global $path_to_root;
163 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
165 if ($_SESSION["wa_current_user"]->can_access('SA_MULTIFISCALYEARS')) // allow all open years for this one
166 return is_date_in_fiscalyears($date, false);
167 $myrow = get_current_fiscalyear();
168 if ($myrow['closed'] == 1)
171 $date2 = sql2date($date);
174 $begin = sql2date($myrow['begin']);
175 $end = sql2date($myrow['end']);
176 if (date1_greater_date2($begin, $date2) || date1_greater_date2($date2, $end))
183 function begin_fiscalyear()
185 global $path_to_root;
186 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
188 $myrow = get_current_fiscalyear();
189 return sql2date($myrow['begin']);
192 function end_fiscalyear()
194 global $path_to_root;
195 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
197 $myrow = get_current_fiscalyear();
198 return sql2date($myrow['end']);
201 function begin_month($date)
204 list($day, $month, $year) = explode_date_to_dmy($date);
205 if ($date_system == 1)
206 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
207 elseif ($date_system == 2)
208 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
209 return __date($year, $month, 1);
212 function end_month($date)
215 list($day, $month, $year) = explode_date_to_dmy($date);
216 if ($date_system == 1)
218 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
219 $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));
221 elseif ($date_system == 2)
223 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
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);
228 return __date($year, $month, $days_in_month[$month - 1]);
231 function add_days($date, $days) // accepts negative values as well
234 list($day, $month, $year) = explode_date_to_dmy($date);
235 $timet = Mktime(0,0,0, $month, $day + $days, $year);
236 if ($date_system == 1 || $date_system == 2)
238 if ($date_system == 1)
239 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
240 elseif ($date_system == 2)
241 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
242 return __date($year, $month, $day);
244 return date(user_date_display(), $timet);
247 function add_months($date, $months) // accepts negative values as well
250 list($day, $month, $year) = explode_date_to_dmy($date);
251 $timet = Mktime(0,0,0, $month + $months, $day, $year);
252 if ($date_system == 1 || $date_system == 2)
254 if ($date_system == 1)
255 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
256 elseif ($date_system == 2)
257 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
258 return __date($year, $month, $day);
260 return date(user_date_display(), $timet);
263 function add_years($date, $years) // accepts negative values as well
266 list($day, $month, $year) = explode_date_to_dmy($date);
267 $timet = Mktime(0,0,0, $month, $day, $year + $years);
268 if ($date_system == 1 || $date_system == 2)
270 if ($date_system == 1)
271 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
272 elseif ($date_system == 2)
273 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
274 return __date($year, $month, $day);
276 return date(user_date_display(), $timet);
279 //_______________________________________________________________
281 function sql2date($date_)
285 //for MySQL dates are in the format YYYY-mm-dd
286 if ($date_ == null || strlen($date_) == 0)
289 if (strpos($date_, "/"))
290 { // In MySQL it could be either / or -
291 list($year, $month, $day) = explode("/", $date_);
293 elseif (strpos ($date_, "-"))
295 list($year, $month, $day) = explode("-", $date_);
298 if (strlen($day) > 4)
299 { /*chop off the time stuff */
300 $day = substr($day, 0, 2);
302 if ($date_system == 1)
303 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
304 elseif ($date_system == 2)
305 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
306 return __date($year, $month, $day);
307 } // end function sql2date
310 function date2sql($date_)
312 global $dateseps, $date_system;
313 /* takes a date in a the format specified in $DefaultDateFormat
314 and converts to a yyyy/mm/dd format */
316 $how = user_date_format();
317 $sep = $dateseps[user_date_sep()];
319 if ($date_ == null || strlen($date_) == 0)
322 $date_ = trim($date_);
323 $year = $month = $day = 0;
325 // Split up the date by the separator based on "how" to split it
326 if ($how == 0) // MMDDYYYY
327 list($month, $day, $year) = explode($sep, $date_);
328 elseif ($how == 1) // DDMMYYYY
329 list($day, $month, $year) = explode($sep, $date_);
330 else // $how == 2, YYYYMMDD
331 list($year, $month, $day) = explode($sep, $date_);
333 //to modify assumption in 2030
334 if ($date_system == 0 || $date_system == 3)
340 elseif ((int)$year > 59 && (int)$year < 100)
345 if ((int)$year > 9999)
349 if ($date_system == 1)
350 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
351 elseif ($date_system == 2)
352 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
354 return sprintf("%04d-%02d-%02d", $year, $month, $day);
357 function date1_greater_date2 ($date1, $date2)
360 /* returns 1 true if date1 is greater than date_ 2 */
362 $date1 = date2sql($date1);
363 $date2 = date2sql($date2);
365 @list($year1, $month1, $day1) = explode("-", $date1);
366 @list($year2, $month2, $day2) = explode("-", $date2);
372 elseif ($year1 == $year2)
374 if ($month1 > $month2)
378 elseif ($month1 == $month2)
390 function date_diff2 ($date1, $date2, $period)
393 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
394 months are assumed to be 30 days and years 365.25 days This only works
395 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
397 $date1 = date2sql($date1);
398 $date2 = date2sql($date2);
399 list($year1, $month1, $day1) = explode("-", $date1);
400 list($year2, $month2, $day2) = explode("-", $date2);
402 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
403 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
404 $difference = $stamp1 - $stamp2;
406 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
411 return (int)($difference / (24 * 60 * 60));
413 return (int)($difference / (24 * 60 * 60 * 7));
415 return (int)($difference / (24 * 60 * 60 * 30));
419 return (int)($difference / (24 * 60 * 60 * 365.25));
425 function explode_date_to_dmy($date_)
427 $date = date2sql($date_);
432 list($year, $month, $day) = explode("-", $date);
433 return array($day, $month, $year);
438 return (int) ($a / $b);
440 /* Based on convertor to and from Gregorian and Jalali calendars.
441 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
442 Released under GNU General Public License */
444 function gregorian_to_jalali ($g_y, $g_m, $g_d)
446 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
447 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
453 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
455 for ($i = 0; $i < $gm; ++$i)
456 $g_day_no += $g_days_in_month[$i];
457 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
458 /* leap and after Feb */
461 $j_day_no = $g_day_no - 79;
463 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
466 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
470 if ($j_day_no >= 366)
472 $jy += div($j_day_no - 1, 365);
473 $j_day_no = ($j_day_no - 1) % 365;
476 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
477 $j_day_no -= $j_days_in_month[$i];
481 return array($jy, $jm, $jd);
484 function jalali_to_gregorian($j_y, $j_m, $j_d)
486 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
487 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
493 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
494 for ($i = 0; $i < $jm; ++$i)
495 $j_day_no += $j_days_in_month[$i];
499 $g_day_no = $j_day_no + 79;
501 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
505 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
508 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
511 if ($g_day_no >= 365)
517 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
520 if ($g_day_no >= 366)
525 $gy += div($g_day_no, 365);
529 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
530 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
534 return array($gy, $gm, $gd);
536 /* Based on Hidri Date Script
537 Released under GNU General Public License */
538 function gregorian_to_islamic($g_y, $g_m, $g_d)
543 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
544 ($m == 10) && ($d > 14)))
546 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
547 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
548 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
552 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
553 (int)((275 * $m) / 9) + $d + 1729777;
555 $l = $jd - 1948440 + 10632;
556 $n = (int)(($l - 1) / 10631);
557 $l = $l - 10631 * $n + 354;
558 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
559 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
560 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
561 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
562 $m = (int)((24 * $l) / 709);
563 $d = $l - (int)((709 * $m) / 24);
564 $y = 30 * $n + $j - 30;
565 return array($y, $m, $d);
568 function islamic_to_gregorian($i_y, $i_m, $i_d)
574 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
578 $n = (int)((4 * $l) / 146097);
579 $l = $l - (int)((146097 * $n + 3) / 4);
580 $i = (int)((4000 * ($l + 1)) / 1461001);
581 $l = $l - (int)((1461 * $i) / 4) + 31;
582 $j = (int)((80 * $l) / 2447);
583 $d = $l - (int)((2447 * $j) / 80);
585 $m = $j + 2 - 12 * $l;
586 $y = 100 * ($n - 49) + $i + $l;
591 $k = (int)(($j - 1) / 1461);
593 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
594 $i = $l - 365 * $n + 30;
595 $j = (int)((80 * $i) / 2447);
596 $d = $i - (int)((2447 * $j) / 80);
598 $m = $j + 2 - 12 * $i;
599 $y = 4 * $k + $n + $i - 4716;
601 return array($y, $m, $d);