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)
26 $how = user_date_format();
27 $sep = $dateseps[user_date_sep()];
35 return $month.$sep.$day.$sep.$year;
37 return $day.$sep.$month.$sep.$year;
39 return $year.$sep.$month.$sep.$day;
42 function is_date($date_)
46 if ($date_ == null || $date_ == "")
48 $how = user_date_format();
49 $sep = $dateseps[user_date_sep()];
51 $date_ = trim($date_);
52 $date_ = str_replace($sep, "", $date_);
53 if (strlen($date_) == 6)
57 $day = substr($date_,2,2);
58 $month = substr($date_,0,2);
59 $year = substr($date_,4,2);
63 $day = substr($date_,0,2);
64 $month = substr($date_,2,2);
65 $year = substr($date_,4,2);
69 $day = substr($date_,4,2);
70 $month = substr($date_,2,2);
71 $year = substr($date_,0,2);
74 elseif (strlen($date_) == 8)
78 $day = substr($date_,2,2);
79 $month = substr($date_,0,2);
80 $year = substr($date_,4,4);
84 $day = substr($date_,0,2);
85 $month = substr($date_,2,2);
86 $year = substr($date_,4,4);
90 $day = substr($date_,6,2);
91 $month = substr($date_,4,2);
92 $year = substr($date_,0,4);
95 if (!isset($year)|| (int)$year > 9999)
101 if (is_long((int)$day) && is_long((int)$month) && is_long((int)$year))
104 if ($date_system == 1)
105 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
106 elseif ($date_system == 2)
107 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
108 if (checkdate((int)$month, (int)$day, (int)$year))
118 { /*Can't be in an appropriate DefaultDateFormat */
121 } //end of is_date function
130 if ($date_system == 1)
131 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
132 elseif ($date_system == 2)
133 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
134 return __date($year, $month, $day);
139 if (user_date_format() == 0)
140 return date("h:i a");
145 // Retrieve and optionaly set default date for new document.
147 function new_doc_date($date=null)
149 if (isset($date) && $date != '')
150 $_SESSION['_default_date'] = $date;
152 if (!isset($_SESSION['_default_date']) || !sticky_doc_date())
153 $_SESSION['_default_date'] = Today();
155 return $_SESSION['_default_date'];
158 function is_date_in_fiscalyear($date, $convert=false)
160 global $path_to_root;
161 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
163 if ($_SESSION["wa_current_user"]->can_access('SA_MULTIFISCALYEARS')) // allow all open years for this one
164 return is_date_in_fiscalyears($date, false);
165 $myrow = get_current_fiscalyear();
166 if ($myrow['closed'] == 1)
169 $date2 = sql2date($date);
172 $begin = sql2date($myrow['begin']);
173 $end = sql2date($myrow['end']);
174 if (date1_greater_date2($begin, $date2) || date1_greater_date2($date2, $end))
181 function begin_fiscalyear()
183 global $path_to_root;
184 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
186 $myrow = get_current_fiscalyear();
187 return sql2date($myrow['begin']);
190 function end_fiscalyear()
192 global $path_to_root;
193 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
195 $myrow = get_current_fiscalyear();
196 return sql2date($myrow['end']);
199 function begin_month($date)
202 list($day, $month, $year) = explode_date_to_dmy($date);
203 if ($date_system == 1)
204 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
205 elseif ($date_system == 2)
206 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
207 return __date($year, $month, 1);
210 function end_month($date)
213 list($day, $month, $year) = explode_date_to_dmy($date);
214 if ($date_system == 1)
216 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
217 $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));
219 elseif ($date_system == 2)
221 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
222 $days_in_month = array(30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, (((((11 * $year) + 14) % 30) < 11) ? 30 : 29));
224 else // gregorian date
225 $days_in_month = array(31, ((!($year % 4 ) && (($year % 100) || !($year % 400)))?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
226 return __date($year, $month, $days_in_month[$month - 1]);
229 function add_days($date, $days) // accepts negative values as well
232 list($day, $month, $year) = explode_date_to_dmy($date);
233 $timet = Mktime(0,0,0, $month, $day + $days, $year);
234 if ($date_system == 1 || $date_system == 2)
236 if ($date_system == 1)
237 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
238 elseif ($date_system == 2)
239 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
240 return __date($year, $month, $day);
242 return date(user_date_display(), $timet);
245 function add_months($date, $months) // accepts negative values as well
248 list($day, $month, $year) = explode_date_to_dmy($date);
249 $timet = Mktime(0,0,0, $month + $months, $day, $year);
250 if ($date_system == 1 || $date_system == 2)
252 if ($date_system == 1)
253 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
254 elseif ($date_system == 2)
255 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
256 return __date($year, $month, $day);
258 return date(user_date_display(), $timet);
261 function add_years($date, $years) // accepts negative values as well
264 list($day, $month, $year) = explode_date_to_dmy($date);
265 $timet = Mktime(0,0,0, $month, $day, $year + $years);
266 if ($date_system == 1 || $date_system == 2)
268 if ($date_system == 1)
269 list($year, $month, $day) = gregorian_to_jalali(date("Y", $timet), date("n", $timet), date("j", $timet));
270 elseif ($date_system == 2)
271 list($year, $month, $day) = gregorian_to_islamic(date("Y", $timet), date("n", $timet), date("j", $timet));
272 return __date($year, $month, $day);
274 return date(user_date_display(), $timet);
277 //_______________________________________________________________
279 function sql2date($date_)
283 //for MySQL dates are in the format YYYY-mm-dd
284 if ($date_ == null || strlen($date_) == 0)
287 if (strpos($date_, "/"))
288 { // In MySQL it could be either / or -
289 list($year, $month, $day) = explode("/", $date_);
291 elseif (strpos ($date_, "-"))
293 list($year, $month, $day) = explode("-", $date_);
296 if (strlen($day) > 4)
297 { /*chop off the time stuff */
298 $day = substr($day, 0, 2);
300 if ($date_system == 1)
301 list($year, $month, $day) = gregorian_to_jalali($year, $month, $day);
302 elseif ($date_system == 2)
303 list($year, $month, $day) = gregorian_to_islamic($year, $month, $day);
304 return __date($year, $month, $day);
305 } // end function sql2date
308 function date2sql($date_)
310 global $dateseps, $date_system;
311 /* takes a date in a the format specified in $DefaultDateFormat
312 and converts to a yyyy/mm/dd format */
314 $how = user_date_format();
315 $sep = $dateseps[user_date_sep()];
317 if ($date_ == null || strlen($date_) == 0)
320 $date_ = trim($date_);
321 $year = $month = $day = 0;
323 // Split up the date by the separator based on "how" to split it
324 if ($how == 0) // MMDDYYYY
325 list($month, $day, $year) = explode($sep, $date_);
326 elseif ($how == 1) // DDMMYYYY
327 list($day, $month, $year) = explode($sep, $date_);
328 else // $how == 2, YYYYMMDD
329 list($year, $month, $day) = explode($sep, $date_);
331 //to modify assumption in 2030
332 if ($date_system == 0 || $date_system == 3)
338 elseif ((int)$year > 59 && (int)$year < 100)
343 if ((int)$year > 9999)
347 if ($date_system == 1)
348 list($year, $month, $day) = jalali_to_gregorian($year, $month, $day);
349 elseif ($date_system == 2)
350 list($year, $month, $day) = islamic_to_gregorian($year, $month, $day);
352 return sprintf("%04d-%02d-%02d", $year, $month, $day);
355 function date1_greater_date2 ($date1, $date2)
358 /* returns 1 true if date1 is greater than date_ 2 */
360 $date1 = date2sql($date1);
361 $date2 = date2sql($date2);
363 @list($year1, $month1, $day1) = explode("-", $date1);
364 @list($year2, $month2, $day2) = explode("-", $date2);
370 elseif ($year1 == $year2)
372 if ($month1 > $month2)
376 elseif ($month1 == $month2)
388 function date_diff2 ($date1, $date2, $period)
391 /* expects dates in the format specified in $DefaultDateFormat - period can be one of 'd','w','y','m'
392 months are assumed to be 30 days and years 365.25 days This only works
393 provided that both dates are after 1970. Also only works for dates up to the year 2035 ish */
395 $date1 = date2sql($date1);
396 $date2 = date2sql($date2);
397 list($year1, $month1, $day1) = explode("-", $date1);
398 list($year2, $month2, $day2) = explode("-", $date2);
400 $stamp1 = mktime(0,0,0, (int)$month1, (int)$day1, (int)$year1);
401 $stamp2 = mktime(0,0,0, (int)$month2, (int)$day2, (int)$year2);
402 $difference = $stamp1 - $stamp2;
404 /* difference is the number of seconds between each date negative if date_ 2 > date_ 1 */
409 return (int)($difference / (24 * 60 * 60));
411 return (int)($difference / (24 * 60 * 60 * 7));
413 return (int)($difference / (24 * 60 * 60 * 30));
417 return (int)($difference / (24 * 60 * 60 * 365.25));
423 function explode_date_to_dmy($date_)
425 $date = date2sql($date_);
430 list($year, $month, $day) = explode("-", $date);
431 return array($day, $month, $year);
436 return (int) ($a / $b);
438 /* Based on convertor to and from Gregorian and Jalali calendars.
439 Copyright (C) 2000 Roozbeh Pournader and Mohammad Toossi
440 Released under GNU General Public License */
442 function gregorian_to_jalali ($g_y, $g_m, $g_d)
444 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
445 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
451 $g_day_no = 365 * $gy + div($gy + 3, 4) - div($gy + 99, 100) + div($gy + 399, 400);
453 for ($i = 0; $i < $gm; ++$i)
454 $g_day_no += $g_days_in_month[$i];
455 if ($gm > 1 && (($gy % 4 == 0 && $gy % 100 != 0) || ($gy % 400 == 0)))
456 /* leap and after Feb */
459 $j_day_no = $g_day_no - 79;
461 $j_np = div($j_day_no, 12053); /* 12053 = 365*33 + 32/4 */
464 $jy = 979 + 33 * $j_np + 4 * div($j_day_no, 1461); /* 1461 = 365*4 + 4/4 */
468 if ($j_day_no >= 366)
470 $jy += div($j_day_no - 1, 365);
471 $j_day_no = ($j_day_no - 1) % 365;
474 for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
475 $j_day_no -= $j_days_in_month[$i];
479 return array($jy, $jm, $jd);
482 function jalali_to_gregorian($j_y, $j_m, $j_d)
484 $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
485 $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
491 $j_day_no = 365 * $jy + div($jy, 33) * 8 + div($jy % 33 + 3, 4);
492 for ($i = 0; $i < $jm; ++$i)
493 $j_day_no += $j_days_in_month[$i];
497 $g_day_no = $j_day_no + 79;
499 $gy = 1600 + 400 * div($g_day_no, 146097); /* 146097 = 365*400 + 400/4 - 400/100 + 400/400 */
503 if ($g_day_no >= 36525) /* 36525 = 365*100 + 100/4 */
506 $gy += 100 * div($g_day_no, 36524); /* 36524 = 365*100 + 100/4 - 100/100 */
509 if ($g_day_no >= 365)
515 $gy += 4 * div($g_day_no, 1461); /* 1461 = 365*4 + 4/4 */
518 if ($g_day_no >= 366)
523 $gy += div($g_day_no, 365);
527 for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
528 $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
532 return array($gy, $gm, $gd);
534 /* Based on Hidri Date Script
535 Released under GNU General Public License */
536 function gregorian_to_islamic($g_y, $g_m, $g_d)
541 if (($y > 1582) || (($y == 1582) && ($m > 10)) || (($y == 1582) &&
542 ($m == 10) && ($d > 14)))
544 $jd = (int)((1461 * ($y + 4800 + (int)(($m - 14) / 12)))/ 4) +
545 (int)((367 * ($m - 2 - 12 * ((int)(($m - 14) / 12)))) / 12) -
546 (int)((3 * ((int)(($y + 4900 + (int)(($m - 14) / 12)) / 100))) / 4) + $d - 32075;
550 $jd = 367 * $y - (int)((7 * ($y + 5001 + (int)(($m - 9) / 7))) / 4) +
551 (int)((275 * $m) / 9) + $d + 1729777;
553 $l = $jd - 1948440 + 10632;
554 $n = (int)(($l - 1) / 10631);
555 $l = $l - 10631 * $n + 354;
556 $j = ((int)((10985 - $l) / 5316)) * ((int)((50 * $l) / 17719)) +
557 ((int)($l / 5670)) * ((int)((43 * $l) / 15238));
558 $l = $l - ((int)((30 - $j) / 15)) * ((int)((17719 * $j) / 50)) -
559 ((int)($j / 16)) * ((int)((15238 * $j) / 43)) + 29;
560 $m = (int)((24 * $l) / 709);
561 $d = $l - (int)((709 * $m) / 24);
562 $y = 30 * $n + $j - 30;
563 return array($y, $m, $d);
566 function islamic_to_gregorian($i_y, $i_m, $i_d)
572 $jd = (int)((11 * $y + 3) / 30) + 354 * $y + 30 * $m - (int)(($m - 1) / 2) + $d + 1948440 - 385;
576 $n = (int)((4 * $l) / 146097);
577 $l = $l - (int)((146097 * $n + 3) / 4);
578 $i = (int)((4000 * ($l + 1)) / 1461001);
579 $l = $l - (int)((1461 * $i) / 4) + 31;
580 $j = (int)((80 * $l) / 2447);
581 $d = $l - (int)((2447 * $j) / 80);
583 $m = $j + 2 - 12 * $l;
584 $y = 100 * ($n - 49) + $i + $l;
589 $k = (int)(($j - 1) / 1461);
591 $n = (int)(($l - 1) / 365) - (int)($l / 1461);
592 $i = $l - 365 * $n + 30;
593 $j = (int)((80 * $i) / 2447);
594 $d = $i - (int)((2447 * $j) / 80);
596 $m = $j + 2 - 12 * $i;
597 $y = 4 * $k + $n + $i - 4716;
599 return array($y, $m, $d);