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 // Pad with 0s if needed
355 if (strlen($month) == 1)
357 if (strlen($day) == 1)
360 return $year."-".$month."-".$day;
363 function date1_greater_date2 ($date1, $date2)
366 /* returns 1 true if date1 is greater than date_ 2 */
368 $date1 = date2sql($date1);
369 $date2 = date2sql($date2);
371 @list($year1, $month1, $day1) = explode("-", $date1);
372 @list($year2, $month2, $day2) = explode("-", $date2);
378 elseif ($year1 == $year2)
380 if ($month1 > $month2)
384 elseif ($month1 == $month2)
396 function date_diff2 ($date1, $date2, $period)
399 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
400 months are assumed to be 30 days and years 365.25 days This only works
401 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
403 $date1 = date2sql($date1);
404 $date2 = date2sql($date2);
405 list($year1, $month1, $day1) = explode("-", $date1);
406 list($year2, $month2, $day2) = explode("-", $date2);
408 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
409 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
410 $difference = $stamp1 - $stamp2;
412 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
417 return (int)($difference / (24 * 60 * 60));
419 return (int)($difference / (24 * 60 * 60 * 7));
421 return (int)($difference / (24 * 60 * 60 * 30));
425 return (int)($difference / (24 * 60 * 60 * 365.25));
431 function explode_date_to_dmy($date_)
433 $date = date2sql($date_);
438 list($year, $month, $day) = explode("-", $date);
439 return array($day, $month, $year);
444 return (int) ($a / $b);
446 /* Based on convertor to and from Gregorian and Jalali calendars.
447 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
448 Released under GNU General Public License */
450 function gregorian_to_jalali ($g_y, $g_m, $g_d)
452 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
453 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
459 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
461 for ($i = 0; $i < $gm; ++$i)
462 $g_day_no += $g_days_in_month[$i];
463 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
464 /* leap and after Feb */
467 $j_day_no = $g_day_no - 79;
469 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
472 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
476 if ($j_day_no >= 366)
478 $jy += div($j_day_no - 1, 365);
479 $j_day_no = ($j_day_no - 1) % 365;
482 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
483 $j_day_no -= $j_days_in_month[$i];
487 return array($jy, $jm, $jd);
490 function jalali_to_gregorian($j_y, $j_m, $j_d)
492 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
493 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
499 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
500 for ($i = 0; $i < $jm; ++$i)
501 $j_day_no += $j_days_in_month[$i];
505 $g_day_no = $j_day_no + 79;
507 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
511 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
514 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
517 if ($g_day_no >= 365)
523 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
526 if ($g_day_no >= 366)
531 $gy += div($g_day_no, 365);
535 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
536 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
540 return array($gy, $gm, $gd);
542 /* Based on Hidri Date Script
543 Released under GNU General Public License */
544 function gregorian_to_islamic($g_y, $g_m, $g_d)
549 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
550 ($m == 10) && ($d > 14)))
552 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
553 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
554 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
558 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
559 (int)((275 * $m) / 9) + $d + 1729777;
561 $l = $jd - 1948440 + 10632;
562 $n = (int)(($l - 1) / 10631);
563 $l = $l - 10631 * $n + 354;
564 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
565 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
566 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
567 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
568 $m = (int)((24 * $l) / 709);
569 $d = $l - (int)((709 * $m) / 24);
570 $y = 30 * $n + $j - 30;
571 return array($y, $m, $d);
574 function islamic_to_gregorian($i_y, $i_m, $i_d)
580 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
584 $n = (int)((4 * $l) / 146097);
585 $l = $l - (int)((146097 * $n + 3) / 4);
586 $i = (int)((4000 * ($l + 1)) / 1461001);
587 $l = $l - (int)((1461 * $i) / 4) + 31;
588 $j = (int)((80 * $l) / 2447);
589 $d = $l - (int)((2447 * $j) / 80);
591 $m = $j + 2 - 12 * $l;
592 $y = 100 * ($n - 49) + $i + $l;
597 $k = (int)(($j - 1) / 1461);
599 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
600 $i = $l - 365 * $n + 30;
601 $j = (int)((80 * $i) / 2447);
602 $d = $i - (int)((2447 * $j) / 80);
604 $m = $j + 2 - 12 * $i;
605 $y = 4 * $k + $n + $i - 4716;
607 return array($y, $m, $d);