57398335c85c96519084e57e767e75cb5b0c1765
[openemr.git] / interface / main / calendar / modules / PostCalendar / pnincludes / Date / Calc.php
blob57398335c85c96519084e57e767e75cb5b0c1765
1 <?php
3 // The constant telling us what day starts the week. Monday (1) is the
4 // international standard. Redefine this to 0 if you want weeks to
5 // begin on Sunday.
6 //define('DATE_CALC_BEGIN_WEEKDAY', 1);
8 /**
9 * Date_Calc is a calendar class used to calculate and
10 * manipulate calendar dates and retrieve dates in a calendar
11 * format. It does not rely on 32-bit system date stamps, so
12 * you can display calendars and compare dates that date
13 * pre 1970 and post 2038.
15 * This source file is subject to version 2.02 of the PHP license,
16 * that is bundled with this package in the file LICENSE, and is
17 * available at through the world-wide-web at
18 * http://www.php.net/license/2_02.txt.
19 * If you did not receive a copy of the PHP license and are unable to
20 * obtain it through the world-wide-web, please send a note to
21 * license@php.net so we can mail you a copy immediately.
23 * Copyright (c) 1999, 2000 ispi
25 * @access public
27 * @version 1.2.5
28 * @author Monte Ohrt <monte@ispi.net>
31 class Date_Calc {
33 /**
34 * Returns the current local date. NOTE: This function
35 * retrieves the local date using strftime(), which may
36 * or may not be 32-bit safe on your system.
38 * @param string the strftime() format to return the date
40 * @access public
42 * @return string the current date in specified format
45 function dateNow($format="%Y%m%d")
47 return(strftime($format,time()));
49 } // end func dateNow
51 /**
52 * Returns true for valid date, false for invalid date.
54 * @param string year in format CCYY
55 * @param string month in format MM
56 * @param string day in format DD
58 * @access public
60 * @return boolean true/false
63 function isValidDate($day, $month, $year)
66 if(empty($year) || empty($month) || empty($day))
67 return false;
69 // must be digits only
70 if(preg_match("/\D/",$year))
71 return false;
72 if(preg_match("/\D/",$month))
73 return false;
74 if(preg_match("/\D/",$day))
75 return false;
77 if($year < 0 || $year > 9999)
78 return false;
79 if($month < 1 || $month > 12)
80 return false;
81 if($day < 1 || $day > 31 || $day > Date_Calc::daysInMonth($month,$year))
82 return false;
84 return true;
86 } // end func isValidDate
88 function isLeapYear($year="")
91 if(empty($year))
92 $year = Date_Calc::dateNow("%Y");
94 if(strlen($year) != 4)
95 return false;
97 if(preg_match("/\D/",$year))
98 return false;
100 return (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0);
102 } // end func isLeapYear
105 * Determines if given date is a future date from now.
107 * @param string year in format CCYY
108 * @param string month in format MM
109 * @param string day in format DD
111 * @access public
113 * @return boolean true/false
116 function isFutureDate($day,$month,$year)
118 $this_year = Date_Calc::dateNow("%Y");
119 $this_month = Date_Calc::dateNow("%m");
120 $this_day = Date_Calc::dateNow("%d");
123 if($year > $this_year)
124 return true;
125 elseif($year == $this_year)
126 if($month > $this_month)
127 return true;
128 elseif($month == $this_month)
129 if($day > $this_day)
130 return true;
132 return false;
134 } // end func isFutureDate
137 * Determines if given date is a past date from now.
139 * @param string year in format CCYY
140 * @param string month in format MM
141 * @param string day in format DD
143 * @access public
145 * @return boolean true/false
148 function isPastDate($day,$month,$year)
150 $this_year = Date_Calc::dateNow("%Y");
151 $this_month = Date_Calc::dateNow("%m");
152 $this_day = Date_Calc::dateNow("%d");
155 if($year < $this_year)
156 return true;
157 elseif($year == $this_year)
158 if($month < $this_month)
159 return true;
160 elseif($month == $this_month)
161 if($day < $this_day)
162 return true;
164 return false;
166 } // end func isPastDate
169 * Returns day of week for given date, 0=Sunday
171 * @param string year in format CCYY, default is current local year
172 * @param string month in format MM, default is current local month
173 * @param string day in format DD, default is current local day
175 * @access public
177 * @return int $weekday_number
180 function dayOfWeek($day="",$month="",$year="")
183 if(empty($year))
184 $year = Date_Calc::dateNow("%Y");
185 if(empty($month))
186 $month = Date_Calc::dateNow("%m");
187 if(empty($day))
188 $day = Date_Calc::dateNow("%d");
190 if($month > 2)
191 $month -= 2;
192 else
194 $month += 10;
195 $year--;
198 $day = ( floor((13 * $month - 1) / 5) +
199 $day + ($year % 100) +
200 floor(($year % 100) / 4) +
201 floor(($year / 100) / 4) - 2 *
202 floor($year / 100) + 77);
204 $weekday_number = (($day - 7 * floor($day / 7)));
206 return $weekday_number;
208 } // end func dayOfWeek
211 * Returns week of the year, first Sunday is first day of first week
213 * @param string day in format DD
214 * @param string month in format MM
215 * @param string year in format CCYY
217 * @access public
219 * @return integer $week_number
222 function weekOfYear($day,$month,$year)
224 if(empty($year))
225 $year = Date_Calc::dateNow("%Y");
226 if(empty($month))
227 $month = Date_Calc::dateNow("%m");
228 if(empty($day))
229 $day = Date_Calc::dateNow("%d");
231 $week_year = $year - 1501;
232 $week_day = $week_year * 365 + floor($week_year / 4) - 29872 + 1
233 - floor($week_year / 100) + floor(($week_year - 300) / 400);
235 $week_number =
236 ceil((Date_Calc::julianDate($day,$month,$year) + floor(($week_day + 4) % 7)) / 7);
238 return $week_number;
240 } // end func weekOfYear
243 * Returns number of days since 31 December of year before given date.
245 * @param string year in format CCYY, default is current local year
246 * @param string month in format MM, default is current local month
247 * @param string day in format DD, default is current local day
249 * @access public
251 * @return int $julian
254 function julianDate($day="",$month="",$year="")
256 if(empty($year))
257 $year = Date_Calc::dateNow("%Y");
258 if(empty($month))
259 $month = Date_Calc::dateNow("%m");
260 if(empty($day))
261 $day = Date_Calc::dateNow("%d");
263 $days = array(0,31,59,90,120,151,181,212,243,273,304,334);
265 $julian = ($days[$month - 1] + $day);
267 if($month > 2 && Date_Calc::isLeapYear($year))
268 $julian++;
270 return($julian);
272 } // end func julianDate
275 * Returns quarter of the year for given date
277 * @param string year in format CCYY, default current local year
278 * @param string month in format MM, default current local month
279 * @param string day in format DD, default current local day
281 * @access public
283 * @return int $year_quarter
286 function quarterOfYear($day="",$month="",$year="")
288 if(empty($year))
289 $year = Date_Calc::dateNow("%Y");
290 if(empty($month))
291 $month = Date_Calc::dateNow("%m");
292 if(empty($day))
293 $day = Date_Calc::dateNow("%d");
295 $year_quarter = (intval(($month - 1) / 3 + 1));
297 return $year_quarter;
299 } // end func quarterOfYear
302 * Returns date of begin of next month of given date.
304 * @param string year in format CCYY, default current local year
305 * @param string month in format MM, default current local month
306 * @param string day in format DD, default current local day
307 * @param string format for returned date
309 * @access public
311 * @return string date in given format
314 function beginOfNextMonth($day="",$month="",$year="",$format="%Y%m%d")
316 if(empty($year))
317 $year = Date_Calc::dateNow("%Y");
318 if(empty($month))
319 $month = Date_Calc::dateNow("%m");
320 if(empty($day))
321 $day = Date_Calc::dateNow("%d");
323 if($month < 12)
325 $month++;
326 $day=1;
328 else
330 $year++;
331 $month=1;
332 $day=1;
335 return Date_Calc::dateFormat($day,$month,$year,$format);
337 } // end func beginOfNextMonth
340 * Returns date of the last day of next month of given date.
342 * @param string year in format CCYY, default current local year
343 * @param string month in format MM, default current local month
344 * @param string day in format DD, default current local day
345 * @param string format for returned date
347 * @access public
349 * @return string date in given format
352 function endOfNextMonth($day="",$month="",$year="",$format="%Y%m%d")
354 if(empty($year))
355 $year = Date_Calc::dateNow("%Y");
356 if(empty($month))
357 $month = Date_Calc::dateNow("%m");
358 if(empty($day))
359 $day = Date_Calc::dateNow("%d");
362 if($month < 12)
364 $month++;
366 else
368 $year++;
369 $month=1;
372 $day = Date_Calc::daysInMonth($month,$year);
374 return Date_Calc::dateFormat($day,$month,$year,$format);
376 } // end func endOfNextMonth
379 * Returns date of the first day of previous month of given date.
381 * @param string year in format CCYY, default current local year
382 * @param string month in format MM, default current local month
383 * @param string day in format DD, default current local day
384 * @param string format for returned date
386 * @access public
388 * @return string date in given format
391 function beginOfPrevMonth($day="",$month="",$year="",$format="%Y%m%d")
393 if(empty($year))
394 $year = Date_Calc::dateNow("%Y");
395 if(empty($month))
396 $month = Date_Calc::dateNow("%m");
397 if(empty($day))
398 $day = Date_Calc::dateNow("%d");
400 if($month > 1)
402 $month--;
403 $day=1;
405 else
407 $year--;
408 $month=12;
409 $day=1;
412 return Date_Calc::dateFormat($day,$month,$year,$format);
414 } // end func beginOfPrevMonth
417 * Returns date of the last day of previous month for given date.
419 * @param string year in format CCYY, default current local year
420 * @param string month in format MM, default current local month
421 * @param string day in format DD, default current local day
422 * @param string format for returned date
424 * @access public
426 * @return string date in given format
429 function endOfPrevMonth($day="",$month="",$year="",$format="%Y%m%d")
431 if(empty($year))
432 $year = Date_Calc::dateNow("%Y");
433 if(empty($month))
434 $month = Date_Calc::dateNow("%m");
435 if(empty($day))
436 $day = Date_Calc::dateNow("%d");
438 if($month > 1)
440 $month--;
442 else
444 $year--;
445 $month=12;
448 $day = Date_Calc::daysInMonth($month,$year);
450 return Date_Calc::dateFormat($day,$month,$year,$format);
452 } // end func endOfPrevMonth
455 * Returns date of the next weekday of given date,
456 * skipping from Friday to Monday.
458 * @param string year in format CCYY, default current local year
459 * @param string month in format MM, default current local month
460 * @param string day in format DD, default current local day
461 * @param string format for returned date
463 * @access public
465 * @return string date in given format
468 function nextWeekday($day="",$month="",$year="",$format="%Y%m%d")
470 if(empty($year))
471 $year = Date_Calc::dateNow("%Y");
472 if(empty($month))
473 $month = Date_Calc::dateNow("%m");
474 if(empty($day))
475 $day = Date_Calc::dateNow("%d");
477 $days = Date_Calc::dateToDays($day,$month,$year);
479 if(Date_Calc::dayOfWeek($day,$month,$year) == 5)
480 $days += 3;
481 elseif(Date_Calc::dayOfWeek($day,$month,$year) == 6)
482 $days += 2;
483 else
484 $days += 1;
486 return(Date_Calc::daysToDate($days,$format));
488 } // end func nextWeekday
491 * Returns date of the previous weekday,
492 * skipping from Monday to Friday.
494 * @param string year in format CCYY, default current local year
495 * @param string month in format MM, default current local month
496 * @param string day in format DD, default current local day
497 * @param string format for returned date
499 * @access public
501 * @return string date in given format
504 function prevWeekday($day="",$month="",$year="",$format="%Y%m%d")
506 if(empty($year))
507 $year = Date_Calc::dateNow("%Y");
508 if(empty($month))
509 $month = Date_Calc::dateNow("%m");
510 if(empty($day))
511 $day = Date_Calc::dateNow("%d");
513 $days = Date_Calc::dateToDays($day,$month,$year);
515 if(Date_Calc::dayOfWeek($day,$month,$year) == 1)
516 $days -= 3;
517 elseif(Date_Calc::dayOfWeek($day,$month,$year) == 0)
518 $days -= 2;
519 else
520 $days -= 1;
522 return(Date_Calc::daysToDate($days,$format));
524 } // end func prevWeekday
527 * Returns date of the next specific day of the week
528 * from the given date.
530 * @param int day of week, 0=Sunday
531 * @param string year in format CCYY, default current local year
532 * @param string month in format MM, default current local month
533 * @param string day in format DD, default current local day
534 * @param boolean onOrAfter if true and days are same, returns current day
535 * @param string format for returned date
537 * @access public
539 * @return string date in given format
542 function nextDayOfWeek($dow,$day="",$month="",$year="",$format="%Y%m%d",$onOrAfter=false)
544 if(empty($year))
545 $year = Date_Calc::dateNow("%Y");
546 if(empty($month))
547 $month = Date_Calc::dateNow("%m");
548 if(empty($day))
549 $day = Date_Calc::dateNow("%d");
551 $days = Date_Calc::dateToDays($day,$month,$year);
552 $curr_weekday = Date_Calc::dayOfWeek($day,$month,$year);
554 if($curr_weekday == $dow)
556 if(!$onOrAfter)
557 $days += 7;
559 elseif($curr_weekday > $dow)
560 $days += 7 - ( $curr_weekday - $dow );
561 else
562 $days += $dow - $curr_weekday;
564 return(Date_Calc::daysToDate($days,$format));
566 } // end func nextDayOfWeek
569 * Returns date of the previous specific day of the week
570 * from the given date.
572 * @param int day of week, 0=Sunday
573 * @param string year in format CCYY, default current local year
574 * @param string month in format MM, default current local month
575 * @param string day in format DD, default current local day
576 * @param boolean onOrBefore if true and days are same, returns current day
577 * @param string format for returned date
579 * @access public
581 * @return string date in given format
584 function prevDayOfWeek($dow,$day="",$month="",$year="",$format="%Y%m%d",$onOrBefore=false)
586 if(empty($year))
587 $year = Date_Calc::dateNow("%Y");
588 if(empty($month))
589 $month = Date_Calc::dateNow("%m");
590 if(empty($day))
591 $day = Date_Calc::dateNow("%d");
593 $days = Date_Calc::dateToDays($day,$month,$year);
594 $curr_weekday = Date_Calc::dayOfWeek($day,$month,$year);
596 if($curr_weekday == $dow)
598 if(!$onOrBefore)
599 $days -= 7;
601 elseif($curr_weekday < $dow)
602 $days -= 7 - ( $dow - $curr_weekday );
603 else
604 $days -= $curr_weekday - $dow;
606 return(Date_Calc::daysToDate($days,$format));
608 } // end func prevDayOfWeek
611 * Returns date of the next specific day of the week
612 * on or before the given date.
614 * @param int day of week, 0=Sunday
615 * @param string year in format CCYY, default current local year
616 * @param string month in format MM, default current local month
617 * @param string day in format DD, default current local day
618 * @param string format for returned date
620 * @access public
622 * @return string date in given format
625 function nextDayOfWeekOnOrAfter($dow,$day="",$month="",$year="",$format="%Y%m%d")
627 return(Date_Calc::nextDayOfWeek($dow,$day="",$month="",$year="",$format="%Y%m%d",true));
628 } // end func nextDayOfWeekOnOrAfter
631 * Returns date of the previous specific day of the week
632 * on or before the given date.
634 * @param int day of week, 0=Sunday
635 * @param string year in format CCYY, default current local year
636 * @param string month in format MM, default current local month
637 * @param string day in format DD, default current local day
638 * @param string format for returned date
640 * @access public
642 * @return string date in given format
645 function prevDayOfWeekOnOrBefore($dow,$day="",$month="",$year="",$format="%Y%m%d")
647 return(Date_Calc::prevDayOfWeek($dow,$day="",$month="",$year="",$format="%Y%m%d",true));
649 } // end func prevDayOfWeekOnOrAfter
652 * Returns date of day after given date.
654 * @param string year in format CCYY, default current local year
655 * @param string month in format MM, default current local month
656 * @param string day in format DD, default current local day
657 * @param string format for returned date
659 * @access public
661 * @return string date in given format
664 function nextDay($day="",$month="",$year="",$format="%Y%m%d")
666 if(empty($year))
667 $year = Date_Calc::dateNow("%Y");
668 if(empty($month))
669 $month = Date_Calc::dateNow("%m");
670 if(empty($day))
671 $day = Date_Calc::dateNow("%d");
673 $days = Date_Calc::dateToDays($day,$month,$year);
675 return(Date_Calc::daysToDate($days + 1,$format));
677 } // end func nextDay
680 * Returns date of day before given date.
682 * @param string year in format CCYY, default current local year
683 * @param string month in format MM, default current local month
684 * @param string day in format DD, default current local day
685 * @param string format for returned date
687 * @access public
689 * @return string date in given format
692 function prevDay($day="",$month="",$year="",$format="%Y%m%d")
694 if(empty($year))
695 $year = Date_Calc::dateNow("%Y");
696 if(empty($month))
697 $month = Date_Calc::dateNow("%m");
698 if(empty($day))
699 $day = Date_Calc::dateNow("%d");
701 $days = Date_Calc::dateToDays($day,$month,$year);
703 return(Date_Calc::daysToDate($days - 1,$format));
705 } // end func prevDay
708 * Sets century for 2 digit year.
709 * 51-99 is 19, else 20
711 * @param string 2 digit year
713 * @access public
715 * @return string 4 digit year
718 function defaultCentury($year)
720 if(strlen($year) == 1)
721 $year = "0$year";
722 if($year > 50)
723 return( "19$year" );
724 else
725 return( "20$year" );
727 } // end func defaultCentury
730 * Returns number of days between two given dates.
732 * @param string year in format CCYY
733 * @param string month in format MM
734 * @param string day in format DD
735 * @param string year in format CCYY
736 * @param string month in format MM
737 * @param string day in format DD
739 * @access public
741 * @return int absolute number of days between dates,
742 * -1 if there is an error.
745 function dateDiff($day1,$month1,$year1,$day2,$month2,$year2)
747 if(!Date_Calc::isValidDate($day1,$month1,$year1))
748 return -1;
749 if(!Date_Calc::isValidDate($day2,$month2,$year2))
750 return -1;
752 return(abs((Date_Calc::dateToDays($day1,$month1,$year1))
753 - (Date_Calc::dateToDays($day2,$month2,$year2))));
755 } // end func dateDiff
758 * Find the number of days in the given month.
760 * @param string month in format MM, default current local month
762 * @access public
764 * @return int number of days
767 function daysInMonth($month="",$year="")
769 if(empty($year))
770 $year = Date_Calc::dateNow("%Y");
771 if(empty($month))
772 $month = Date_Calc::dateNow("%m");
774 if($month == 2)
776 if(Date_Calc::isLeapYear($year))
777 return 29;
778 else
779 return 28;
781 elseif($month == 4 or $month == 6 or $month == 9 or $month == 11)
782 return 30;
783 else
784 return 31;
786 } // end func daysInMonth
789 * Returns the number of rows on a calendar month. Useful for
790 * determining the number of rows when displaying a typical
791 * month calendar.
793 * @param string month in format MM, default current local month
794 * @param string year in format YYCC, default current local year
796 * @access public
798 * @return int number of weeks
801 function weeksInMonth($month="",$year="")
803 if(empty($year)) {
804 $year = Date_Calc::dateNow("%Y");
806 if(empty($month)) {
807 $month = Date_Calc::dateNow("%m");
809 // starts on monday
810 if(DATE_CALC_BEGIN_WEEKDAY == 1)
811 { if(Date_Calc::firstOfMonthWeekday($month,$year) == 0) {
812 $first_week_days = 1;
813 } else {
814 $first_week_days = 7 - (Date_Calc::firstOfMonthWeekday($month,$year) - 1);
816 // starts on saturday
817 } elseif(DATE_CALC_BEGIN_WEEKDAY == 6) {
818 if(Date_Calc::firstOfMonthWeekday($month,$year) == 0) {
819 $first_week_days = 6;
820 } else {
821 $first_week_days = 7 - (Date_Calc::firstOfMonthWeekday($month,$year) + 1);
823 // starts on sunday
824 } else {
825 $first_week_days = 7 - Date_Calc::firstOfMonthWeekday($month,$year);
827 return ceil(((Date_Calc::daysInMonth($month,$year) - $first_week_days) / 7) + 1);
828 } // end func weeksInMonth
831 * Find the day of the week for the first of the month of given date.
833 * @param string year in format CCYY, default to current local year
834 * @param string month in format MM, default to current local month
836 * @access public
838 * @return int number of weekday for the first day, 0=Sunday
841 function firstOfMonthWeekday($month="",$year="")
843 if(empty($year))
844 $year = Date_Calc::dateNow("%Y");
845 if(empty($month))
846 $month = Date_Calc::dateNow("%m");
848 return(Date_Calc::dayOfWeek("01",$month,$year));
850 } // end func firstOfMonthWeekday
853 * Return date of first day of month of given date.
855 * @param string year in format CCYY, default current local year
856 * @param string month in format MM, default current local month
857 * @param string format for returned date
859 * @access public
861 * @return string date in given format
864 function beginOfMonth($month="",$year="",$format="%Y%m%d")
866 if(empty($year))
867 $year = Date_Calc::dateNow("%Y");
868 if(empty($month))
869 $month = Date_Calc::dateNow("%m");
871 return(Date_Calc::dateFormat("01",$month,$year,$format));
873 } // end of func beginOfMonth
876 * Find the month day of the beginning of week for given date,
877 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
879 * @param string year in format CCYY, default current local year
880 * @param string month in format MM, default current local month
881 * @param string day in format DD, default current local day
882 * @param string format for returned date
884 * @access public
886 * @return string date in given format
889 function beginOfWeek($day="",$month="",$year="",$format="%Y%m%d")
891 if(empty($year))
892 $year = Date_Calc::dateNow("%Y");
893 if(empty($month))
894 $month = Date_Calc::dateNow("%m");
895 if(empty($day))
896 $day = Date_Calc::dateNow("%d");
898 $this_weekday = Date_Calc::dayOfWeek($day,$month,$year);
900 if(DATE_CALC_BEGIN_WEEKDAY == 1)
902 if($this_weekday == 0)
903 $beginOfWeek = Date_Calc::dateToDays($day,$month,$year) - 6;
904 else
905 $beginOfWeek = Date_Calc::dateToDays($day,$month,$year)
906 - $this_weekday + 1;
908 else
909 $beginOfWeek = (Date_Calc::dateToDays($day,$month,$year)
910 - $this_weekday);
913 /* $beginOfWeek = (Date_Calc::dateToDays($day,$month,$year)
914 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY)); */
916 return(Date_Calc::daysToDate($beginOfWeek,$format));
918 } // end of func beginOfWeek
921 * Find the month day of the end of week for given date,
922 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday
923 * of following month.)
925 * @param string year in format CCYY, default current local year
926 * @param string month in format MM, default current local month
927 * @param string day in format DD, default current local day
928 * @param string format for returned date
930 * @access public
932 * @return string date in given format
935 function endOfWeek($day="",$month="",$year="",$format="%Y%m%d")
937 if(empty($year))
938 $year = Date_Calc::dateNow("%Y");
939 if(empty($month))
940 $month = Date_Calc::dateNow("%m");
941 if(empty($day))
942 $day = Date_Calc::dateNow("%d");
944 $this_weekday = Date_Calc::dayOfWeek($day,$month,$year);
946 $last_dayOfWeek = (Date_Calc::dateToDays($day,$month,$year)
947 + (6 - $this_weekday + DATE_CALC_BEGIN_WEEKDAY));
949 return(Date_Calc::daysToDate($last_dayOfWeek,$format));
951 } // end func endOfWeek
954 * Find the month day of the beginning of week after given date,
955 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
957 * @param string year in format CCYY, default current local year
958 * @param string month in format MM, default current local month
959 * @param string day in format DD, default current local day
960 * @param string format for returned date
962 * @access public
964 * @return string date in given format
967 function beginOfNextWeek($day="",$month="",$year="",$format="%Y%m%d")
969 if(empty($year))
970 $year = Date_Calc::dateNow("%Y");
971 if(empty($month))
972 $month = Date_Calc::dateNow("%m");
973 if(empty($day))
974 $day = Date_Calc::dateNow("%d");
976 $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day+7,$month,$year),"%Y%m%d");
978 $next_week_year = substr($date,0,4);
979 $next_week_month = substr($date,4,2);
980 $next_week_day = substr($date,6,2);
982 $this_weekday = Date_Calc::dayOfWeek($next_week_day,$next_week_month,$next_week_year);
984 $beginOfWeek = (Date_Calc::dateToDays($next_week_day,$next_week_month,$next_week_year)
985 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY));
987 return(Date_Calc::daysToDate($beginOfWeek,$format));
989 } // end func beginOfNextWeek
992 * Find the month day of the beginning of week before given date,
993 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
995 * @param string year in format CCYY, default current local year
996 * @param string month in format MM, default current local month
997 * @param string day in format DD, default current local day
998 * @param string format for returned date
1000 * @access public
1002 * @return string date in given format
1005 function beginOfPrevWeek($day="",$month="",$year="",$format="%Y%m%d")
1007 if(empty($year))
1008 $year = Date_Calc::dateNow("%Y");
1009 if(empty($month))
1010 $month = Date_Calc::dateNow("%m");
1011 if(empty($day))
1012 $day = Date_Calc::dateNow("%d");
1014 $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day-7,$month,$year),"%Y%m%d");
1016 $next_week_year = substr($date,0,4);
1017 $next_week_month = substr($date,4,2);
1018 $next_week_day = substr($date,6,2);
1020 $this_weekday = Date_Calc::dayOfWeek($next_week_day,$next_week_month,$next_week_year);
1022 $beginOfWeek = (Date_Calc::dateToDays($next_week_day,$next_week_month,$next_week_year)
1023 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY));
1025 return(Date_Calc::daysToDate($beginOfWeek,$format));
1027 } // end func beginOfPrevWeek
1030 * Return an array with days in week
1032 * @param string year in format CCYY, default current local year
1033 * @param string month in format MM, default current local month
1034 * @param string day in format DD, default current local day
1035 * @param string format for returned date
1037 * @access public
1039 * @return array $week[$weekday]
1042 function getCalendarWeek($day="",$month="",$year="",$format="%Y%m%d")
1044 if(empty($year))
1045 $year = Date_Calc::dateNow("%Y");
1046 if(empty($month))
1047 $month = Date_Calc::dateNow("%m");
1048 if(empty($day))
1049 $day = Date_Calc::dateNow("%d");
1051 $week_array = array();
1053 // date for the column of week
1055 $curr_day = Date_Calc::beginOfWeek($day,$month,$year,"%E");
1057 for($counter=0; $counter <= 6; $counter++)
1059 $week_array[$counter] = Date_Calc::daysToDate($curr_day,$format);
1060 $curr_day++;
1063 return $week_array;
1065 } // end func getCalendarWeek
1068 * Return a set of arrays to construct a calendar month for
1069 * the given date.
1071 * @param string year in format CCYY, default current local year
1072 * @param string month in format MM, default current local month
1073 * @param string format for returned date
1075 * @access public
1077 * @return array $month[$row][$col]
1080 function getCalendarMonth($month="",$year="",$format="%Y%m%d")
1082 if(empty($year)) $year = Date_Calc::dateNow("%Y");
1083 if(empty($month)) $month = Date_Calc::dateNow("%m");
1084 $month_array = array();
1085 // starts on monday
1086 if(DATE_CALC_BEGIN_WEEKDAY == 1) {
1087 if(Date_Calc::firstOfMonthWeekday($month,$year) == 0) {
1088 $curr_day = Date_Calc::dateToDays("01",$month,$year) - 6;
1089 } else {
1090 $curr_day = Date_Calc::dateToDays("01",$month,$year) - Date_Calc::firstOfMonthWeekday($month,$year) + 1;
1092 // starts on saturday
1093 } elseif(DATE_CALC_BEGIN_WEEKDAY == 6) {
1094 if(Date_Calc::firstOfMonthWeekday($month,$year) == 0) {
1095 $curr_day = Date_Calc::dateToDays("01",$month,$year) - 1;
1096 } else {
1097 $curr_day = Date_Calc::dateToDays("01",$month,$year) - Date_Calc::firstOfMonthWeekday($month,$year) - 1;
1099 // starts on sunday
1100 } else {
1101 $curr_day = (Date_Calc::dateToDays("01",$month,$year) - Date_Calc::firstOfMonthWeekday($month,$year));
1103 // number of days in this month
1104 $daysInMonth = Date_Calc::daysInMonth($month,$year);
1106 $weeksInMonth = Date_Calc::weeksInMonth($month,$year);
1107 for($row_counter=0; $row_counter < $weeksInMonth; $row_counter++)
1109 for($column_counter=0; $column_counter <= 6; $column_counter++)
1111 $month_array[$row_counter][$column_counter] = Date_Calc::daysToDate($curr_day,$format);
1112 $curr_day++;
1116 return $month_array;
1118 } // end func getCalendarMonth
1121 * Return a set of arrays to construct a calendar year for
1122 * the given date.
1124 * @param string year in format CCYY, default current local year
1125 * @param string format for returned date
1127 * @access public
1129 * @return array $year[$month][$row][$col]
1132 function getCalendarYear($year="",$format="%Y%m%d")
1134 if(empty($year))
1135 $year = Date_Calc::dateNow("%Y");
1137 $year_array = array();
1139 for($curr_month=0; $curr_month <=11; $curr_month++)
1140 $year_array[$curr_month] = Date_Calc::getCalendarMonth(sprintf("%02d",$curr_month+1),$year,$format);
1142 return $year_array;
1144 } // end func getCalendarYear
1147 * Converts a date to number of days since a
1148 * distant unspecified epoch.
1150 * @param string year in format CCYY
1151 * @param string month in format MM
1152 * @param string day in format DD
1154 * @access public
1156 * @return integer number of days
1159 function dateToDays($day,$month,$year)
1162 $century = substr($year,0,2);
1163 $year = substr($year,2,2);
1165 if($month > 2)
1166 $month -= 3;
1167 else
1169 $month += 9;
1170 if($year)
1171 $year--;
1172 else
1174 $year = 99;
1175 $century --;
1179 return ( floor(( 146097 * $century) / 4 ) +
1180 floor(( 1461 * $year) / 4 ) +
1181 floor(( 153 * $month + 2) / 5 ) +
1182 $day + 1721119);
1184 } // end func dateToDays
1187 * Converts number of days to a distant unspecified epoch.
1189 * @param int number of days
1190 * @param string format for returned date
1192 * @access public
1194 * @return string date in specified format
1197 function daysToDate($days,$format="%Y%m%d")
1200 $days -= 1721119;
1201 $century = floor(( 4 * $days - 1) / 146097);
1202 $days = floor(4 * $days - 1 - 146097 * $century);
1203 $day = floor($days / 4);
1205 $year = floor(( 4 * $day + 3) / 1461);
1206 $day = floor(4 * $day + 3 - 1461 * $year);
1207 $day = floor(($day + 4) / 4);
1209 $month = floor(( 5 * $day - 3) / 153);
1210 $day = floor(5 * $day - 3 - 153 * $month);
1211 $day = floor(($day + 5) / 5);
1213 if($month < 10)
1214 $month +=3;
1215 else
1217 $month -=9;
1218 if($year++ == 99)
1220 $year = 0;
1221 $century++;
1225 $century = sprintf("%02d",$century);
1226 $year = sprintf("%02d",$year);
1228 return(Date_Calc::dateFormat($day,$month,$century.$year,$format));
1230 } // end func daysToDate
1233 * Calculates the date of the Nth weekday of the month,
1234 * such as the second Saturday of January 2000.
1236 * @param string occurance: 1=first, 2=second, 3=third, etc.
1237 * @param string dayOfWeek: 0=Sunday, 1=Monday, etc.
1238 * @param string year in format CCYY
1239 * @param string month in format MM
1240 * @param string format for returned date
1242 * @access public
1244 * @return string date in given format
1247 function NWeekdayOfMonth($occurance,$dayOfWeek,$month,$year,$format="%Y%m%d") {
1249 $year = sprintf("%04d",$year);
1250 $month = sprintf("%02d",$month);
1252 $DOW1day = sprintf("%02d",(($occurance - 1) * 7 + 1));
1253 $DOW1 = Date_Calc::dayOfWeek($DOW1day,$month,$year);
1255 $wdate = ($occurance - 1) * 7 + 1 +
1256 (7 + $dayOfWeek - $DOW1) % 7;
1258 if( $wdate > Date_Calc::daysInMonth($month,$year))
1259 return -1;
1260 else
1261 return(Date_Calc::dateFormat($wdate,$month,$year,$format));
1263 } // end func NWeekdayOfMonth
1266 * Formats the date in the given format, much like
1267 * strfmt(). This function is used to alleviate the
1268 * problem with 32-bit numbers for dates pre 1970
1269 * or post 2038, as strfmt() has on most systems.
1270 * Most of the formatting options are compatible.
1272 * formatting options:
1274 * %a abbreviated weekday name (Sun, Mon, Tue)
1275 * %A full weekday name (Sunday, Monday, Tuesday)
1276 * %b abbreviated month name (Jan, Feb, Mar)
1277 * %B full month name (January, February, March)
1278 * %d day of month (range 00 to 31)
1279 * %e day of month, single digit (range 0 to 31)
1280 * %E number of days since unspecified epoch (integer)
1281 * (%E is useful for passing a date in a URL as
1282 * an integer value. Then simply use
1283 * daysToDate() to convert back to a date.)
1284 * %j day of year (range 001 to 366)
1285 * %m month as decimal number (range 1 to 12)
1286 * %n newline character (\n)
1287 * %t tab character (\t)
1288 * %w weekday as decimal (0 = Sunday)
1289 * %U week number of current year, first sunday as first week
1290 * %y year as decimal (range 00 to 99)
1291 * %Y year as decimal including century (range 0000 to 9999)
1292 * %% literal '%'
1294 * @param string year in format CCYY
1295 * @param string month in format MM
1296 * @param string day in format DD
1297 * @param string format for returned date
1299 * @access public
1301 * @return string date in given format
1304 function dateFormat($day,$month,$year,$format)
1306 if(!Date_Calc::isValidDate($day,$month,$year))
1308 $year = Date_Calc::dateNow("%Y");
1309 $month = Date_Calc::dateNow("%m");
1310 $day = Date_Calc::dateNow("%d");
1313 $output = "";
1315 for($strpos = 0; $strpos < strlen($format); $strpos++)
1317 $char = substr($format,$strpos,1);
1318 if($char == "%")
1320 $nextchar = substr($format,$strpos + 1,1);
1321 switch($nextchar)
1323 case "a":
1324 $output .= Date_Calc::getWeekdayAbbrname($day,$month,$year);
1325 break;
1326 case "A":
1327 $output .= Date_Calc::getWeekdayFullname($day,$month,$year);
1328 break;
1329 case "b":
1330 $output .= Date_Calc::getMonthAbbrname($month);
1331 break;
1332 case "B":
1333 $output .= Date_Calc::getMonthFullname($month);
1334 break;
1335 case "d":
1336 $output .= sprintf("%02d",$day);
1337 break;
1338 case "e":
1339 $output .= $day;
1340 break;
1341 case "E":
1342 $output .= Date_Calc::dateToDays($day,$month,$year);
1343 break;
1344 case "j":
1345 $output .= Date_Calc::julianDate($day,$month,$year);
1346 break;
1347 case "m":
1348 $output .= sprintf("%02d",$month);
1349 break;
1350 case "n":
1351 $output .= "\n";
1352 break;
1353 case "t":
1354 $output .= "\t";
1355 break;
1356 case "w":
1357 $output .= Date_Calc::dayOfWeek($day,$month,$year);
1358 break;
1359 case "U":
1360 $output .= Date_Calc::weekOfYear($day,$month,$year);
1361 break;
1362 case "y":
1363 $output .= substr($year,2,2);
1364 break;
1365 case "Y":
1366 $output .= $year;
1367 break;
1368 case "%":
1369 $output .= "%";
1370 break;
1371 default:
1372 $output .= $char.$nextchar;
1374 $strpos++;
1376 else
1378 $output .= $char;
1381 return $output;
1383 } // end func dateFormat
1386 * Returns the current local year in format CCYY
1388 * @access public
1390 * @return string year in format CCYY
1393 function getYear()
1395 return Date_Calc::dateNow("%Y");
1397 } // end func getYear
1400 * Returns the current local month in format MM
1402 * @access public
1404 * @return string month in format MM
1407 function getMonth()
1409 return Date_Calc::dateNow("%m");
1411 } // end func getMonth
1414 * Returns the current local day in format DD
1416 * @access public
1418 * @return string day in format DD
1421 function getDay()
1423 return Date_Calc::dateNow("%d");
1425 } // end func getDay
1428 * Returns the full month name for the given month
1430 * @param string month in format MM
1432 * @access public
1434 * @return string full month name
1437 function getMonthFullname($month)
1439 $month = (int)$month;
1441 if(empty($month))
1442 $month = Date_Calc::dateNow("%m");
1444 $month_names = Date_Calc::getMonthNames();
1445 return $month_names[$month];
1446 // getMonthNames returns months with correct indexes
1447 //return $month_names[($month - 1)];
1449 } // end func getMonthFullname
1452 * Returns the abbreviated month name for the given month
1454 * @param string month in format MM
1455 * @param int optional length of abbreviation, default is 3
1457 * @access public
1459 * @return string abbreviated month name
1460 * @see Date_Calc::getMonthFullname
1463 function getMonthAbbrname($month,$length=3)
1465 $month = (int)$month;
1467 if(empty($month))
1468 $month = Date_Calc::dateNow("%m");
1469 return substr(Date_Calc::getMonthFullname($month), 0, $length);
1470 } // end func getMonthAbbrname
1473 * Returns the full weekday name for the given date
1475 * @param string year in format CCYY, default current local year
1476 * @param string month in format MM, default current local month
1477 * @param string day in format DD, default current local day
1479 * @access public
1481 * @return string full month name
1484 function getWeekdayFullname($day="",$month="",$year="")
1486 if(empty($year))
1487 $year = Date_Calc::dateNow("%Y");
1488 if(empty($month))
1489 $month = Date_Calc::dateNow("%m");
1490 if(empty($day))
1491 $day = Date_Calc::dateNow("%d");
1493 $weekday_names = Date_Calc::getWeekDays();
1494 $weekday = Date_Calc::dayOfWeek($day,$month,$year);
1496 return $weekday_names[$weekday];
1498 } // end func getWeekdayFullname
1501 * Returns the abbreviated weekday name for the given date
1503 * @param string year in format CCYY, default current local year
1504 * @param string month in format MM, default current local month
1505 * @param string day in format DD, default current local day
1506 * @param int optional length of abbreviation, default is 3
1508 * @access public
1510 * @return string full month name
1511 * @see Date_Calc::getWeekdayFullname
1514 function getWeekdayAbbrname($day="",$month="",$year="",$length=3)
1516 if(empty($year))
1517 $year = Date_Calc::dateNow("%Y");
1518 if(empty($month))
1519 $month = Date_Calc::dateNow("%m");
1520 if(empty($day))
1521 $day = Date_Calc::dateNow("%d");
1522 return substr(Date_Calc::getWeekdayFullname($day,$month,$year),0,$length);
1523 } // end func getWeekdayFullname
1526 * Returns the numeric month from the month name or an abreviation
1528 * Both August and Aug would return 8.
1529 * Month name is case insensitive.
1531 * @param string month name
1532 * @return integer month number
1534 function getMonthFromFullName($month){
1535 $month = strtolower($month);
1536 $months = Date_Calc::getMonthNames();
1537 while(list($id, $name) = each($months)){
1538 if(ereg($month, strtolower($name))){
1539 return($id);
1542 return(0);
1546 * Retunrs an array of month names
1548 * Used to take advantage of the setlocale function to return
1549 * language specific month names.
1550 * XXX cache values to some global array to avoid preformace hits when called more than once.
1552 * @returns array An array of month names
1554 function getMonthNames(){
1555 for($i=1;$i<13;$i++){
1556 $months[$i] = strftime('%B', mktime(0, 0, 0, $i, 1, 2001));
1558 return($months);
1562 * Returns an array of week days
1564 * Used to take advantage of the setlocale function to
1565 * return language specific week days
1566 * XXX cache values to some global array to avoid preformace hits when called more than once.
1568 * @returns array An array of week day names
1570 function getWeekDays(){
1571 for($i=0;$i<7;$i++){
1572 $weekdays[$i] = strftime('%A', mktime(0, 0, 0, 1, $i, 2001));
1574 return($weekdays);
1577 } // end class Date_calendar