psr12 fixes for new PHP_CodeSniffer (#4795)
[openemr.git] / interface / main / calendar / modules / PostCalendar / pnincludes / Date / Calc.php
blobf3f175bdbc7cf2cd2b03efb7b866f98ce4ab5d8c
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 static function dateNow($format = "%Y%m%d")
47 return(strftime($format, time()));
48 } // end func dateNow
50 /**
51 * Returns true for valid date, false for invalid date.
53 * @param string year in format CCYY
54 * @param string month in format MM
55 * @param string day in format DD
57 * @access public
59 * @return boolean true/false
62 static function isValidDate($day, $month, $year)
65 if (empty($year) || empty($month) || empty($day)) {
66 return false;
69 // must be digits only
70 if (preg_match("/\D/", $year)) {
71 return false;
74 if (preg_match("/\D/", $month)) {
75 return false;
78 if (preg_match("/\D/", $day)) {
79 return false;
82 if ($year < 0 || $year > 9999) {
83 return false;
86 if ($month < 1 || $month > 12) {
87 return false;
90 if ($day < 1 || $day > 31 || $day > Date_Calc::daysInMonth($month, $year)) {
91 return false;
94 return true;
95 } // end func isValidDate
97 static function isLeapYear($year = "")
100 if (empty($year)) {
101 $year = Date_Calc::dateNow("%Y");
104 if (strlen($year) != 4) {
105 return false;
108 if (preg_match("/\D/", $year)) {
109 return false;
112 return (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0);
113 } // end func isLeapYear
116 * Determines if given date is a future date from now.
118 * @param string year in format CCYY
119 * @param string month in format MM
120 * @param string day in format DD
122 * @access public
124 * @return boolean true/false
127 static function isFutureDate($day, $month, $year)
129 $this_year = Date_Calc::dateNow("%Y");
130 $this_month = Date_Calc::dateNow("%m");
131 $this_day = Date_Calc::dateNow("%d");
134 if ($year > $this_year) {
135 return true;
136 } elseif ($year == $this_year) {
137 if ($month > $this_month) {
138 return true;
139 } elseif ($month == $this_month) {
140 if ($day > $this_day) {
141 return true;
146 return false;
147 } // end func isFutureDate
150 * Determines if given date is a past date from now.
152 * @param string year in format CCYY
153 * @param string month in format MM
154 * @param string day in format DD
156 * @access public
158 * @return boolean true/false
161 static function isPastDate($day, $month, $year)
163 $this_year = Date_Calc::dateNow("%Y");
164 $this_month = Date_Calc::dateNow("%m");
165 $this_day = Date_Calc::dateNow("%d");
168 if ($year < $this_year) {
169 return true;
170 } elseif ($year == $this_year) {
171 if ($month < $this_month) {
172 return true;
173 } elseif ($month == $this_month) {
174 if ($day < $this_day) {
175 return true;
180 return false;
181 } // end func isPastDate
184 * Returns day of week for given date, 0=Sunday
186 * @param string year in format CCYY, default is current local year
187 * @param string month in format MM, default is current local month
188 * @param string day in format DD, default is current local day
190 * @access public
192 * @return int $weekday_number
195 static function dayOfWeek($day = "", $month = "", $year = "")
198 if (empty($year)) {
199 $year = Date_Calc::dateNow("%Y");
202 if (empty($month)) {
203 $month = Date_Calc::dateNow("%m");
206 if (empty($day)) {
207 $day = Date_Calc::dateNow("%d");
210 if ($month > 2) {
211 $month -= 2;
212 } else {
213 $month += 10;
214 $year--;
217 $day = ( floor((13 * $month - 1) / 5) +
218 $day + ($year % 100) +
219 floor(($year % 100) / 4) +
220 floor(($year / 100) / 4) - 2 *
221 floor($year / 100) + 77);
223 $weekday_number = (($day - 7 * floor($day / 7)));
225 return $weekday_number;
226 } // end func dayOfWeek
229 * Returns week of the year, first Sunday is first day of first week
231 * @param string day in format DD
232 * @param string month in format MM
233 * @param string year in format CCYY
235 * @access public
237 * @return integer $week_number
240 static function weekOfYear($day, $month, $year)
242 if (empty($year)) {
243 $year = Date_Calc::dateNow("%Y");
246 if (empty($month)) {
247 $month = Date_Calc::dateNow("%m");
250 if (empty($day)) {
251 $day = Date_Calc::dateNow("%d");
254 $week_year = $year - 1501;
255 $week_day = $week_year * 365 + floor($week_year / 4) - 29872 + 1
256 - floor($week_year / 100) + floor(($week_year - 300) / 400);
258 $week_number =
259 ceil((Date_Calc::julianDate($day, $month, $year) + floor(($week_day + 4) % 7)) / 7);
261 return $week_number;
262 } // end func weekOfYear
265 * Returns number of days since 31 December of year before given date.
267 * @param string year in format CCYY, default is current local year
268 * @param string month in format MM, default is current local month
269 * @param string day in format DD, default is current local day
271 * @access public
273 * @return int $julian
276 static function julianDate($day = "", $month = "", $year = "")
278 if (empty($year)) {
279 $year = Date_Calc::dateNow("%Y");
282 if (empty($month)) {
283 $month = Date_Calc::dateNow("%m");
286 if (empty($day)) {
287 $day = Date_Calc::dateNow("%d");
290 $days = array(0,31,59,90,120,151,181,212,243,273,304,334);
292 $julian = ($days[$month - 1] + $day);
294 if ($month > 2 && Date_Calc::isLeapYear($year)) {
295 $julian++;
298 return($julian);
299 } // end func julianDate
302 * Returns quarter of the year for 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
308 * @access public
310 * @return int $year_quarter
313 static function quarterOfYear($day = "", $month = "", $year = "")
315 if (empty($year)) {
316 $year = Date_Calc::dateNow("%Y");
319 if (empty($month)) {
320 $month = Date_Calc::dateNow("%m");
323 if (empty($day)) {
324 $day = Date_Calc::dateNow("%d");
327 $year_quarter = (intval(($month - 1) / 3 + 1));
329 return $year_quarter;
330 } // end func quarterOfYear
333 * Returns date of begin of next month of given date.
335 * @param string year in format CCYY, default current local year
336 * @param string month in format MM, default current local month
337 * @param string day in format DD, default current local day
338 * @param string format for returned date
340 * @access public
342 * @return string date in given format
345 static function beginOfNextMonth($day = "", $month = "", $year = "", $format = "%Y%m%d")
347 if (empty($year)) {
348 $year = Date_Calc::dateNow("%Y");
351 if (empty($month)) {
352 $month = Date_Calc::dateNow("%m");
355 if (empty($day)) {
356 $day = Date_Calc::dateNow("%d");
359 if ($month < 12) {
360 $month++;
361 $day = 1;
362 } else {
363 $year++;
364 $month = 1;
365 $day = 1;
368 return Date_Calc::dateFormat($day, $month, $year, $format);
369 } // end func beginOfNextMonth
372 * Returns date of the last day of next month of given date.
374 * @param string year in format CCYY, default current local year
375 * @param string month in format MM, default current local month
376 * @param string day in format DD, default current local day
377 * @param string format for returned date
379 * @access public
381 * @return string date in given format
384 static function endOfNextMonth($day = "", $month = "", $year = "", $format = "%Y%m%d")
386 if (empty($year)) {
387 $year = Date_Calc::dateNow("%Y");
390 if (empty($month)) {
391 $month = Date_Calc::dateNow("%m");
394 if (empty($day)) {
395 $day = Date_Calc::dateNow("%d");
399 if ($month < 12) {
400 $month++;
401 } else {
402 $year++;
403 $month = 1;
406 $day = Date_Calc::daysInMonth($month, $year);
408 return Date_Calc::dateFormat($day, $month, $year, $format);
409 } // end func endOfNextMonth
412 * Returns date of the first day of previous month of given date.
414 * @param string year in format CCYY, default current local year
415 * @param string month in format MM, default current local month
416 * @param string day in format DD, default current local day
417 * @param string format for returned date
419 * @access public
421 * @return string date in given format
424 static function beginOfPrevMonth($day = "", $month = "", $year = "", $format = "%Y%m%d")
426 if (empty($year)) {
427 $year = Date_Calc::dateNow("%Y");
430 if (empty($month)) {
431 $month = Date_Calc::dateNow("%m");
434 if (empty($day)) {
435 $day = Date_Calc::dateNow("%d");
438 if ($month > 1) {
439 $month--;
440 $day = 1;
441 } else {
442 $year--;
443 $month = 12;
444 $day = 1;
447 return Date_Calc::dateFormat($day, $month, $year, $format);
448 } // end func beginOfPrevMonth
451 * Returns date of the last day of previous month for given date.
453 * @param string year in format CCYY, default current local year
454 * @param string month in format MM, default current local month
455 * @param string day in format DD, default current local day
456 * @param string format for returned date
458 * @access public
460 * @return string date in given format
463 static function endOfPrevMonth($day = "", $month = "", $year = "", $format = "%Y%m%d")
465 if (empty($year)) {
466 $year = Date_Calc::dateNow("%Y");
469 if (empty($month)) {
470 $month = Date_Calc::dateNow("%m");
473 if (empty($day)) {
474 $day = Date_Calc::dateNow("%d");
477 if ($month > 1) {
478 $month--;
479 } else {
480 $year--;
481 $month = 12;
484 $day = Date_Calc::daysInMonth($month, $year);
486 return Date_Calc::dateFormat($day, $month, $year, $format);
487 } // end func endOfPrevMonth
490 * Returns date of the next weekday of given date,
491 * skipping from Friday to Monday.
493 * @param string year in format CCYY, default current local year
494 * @param string month in format MM, default current local month
495 * @param string day in format DD, default current local day
496 * @param string format for returned date
498 * @access public
500 * @return string date in given format
503 static function nextWeekday($day = "", $month = "", $year = "", $format = "%Y%m%d")
505 if (empty($year)) {
506 $year = Date_Calc::dateNow("%Y");
509 if (empty($month)) {
510 $month = Date_Calc::dateNow("%m");
513 if (empty($day)) {
514 $day = Date_Calc::dateNow("%d");
517 $days = Date_Calc::dateToDays($day, $month, $year);
519 if (Date_Calc::dayOfWeek($day, $month, $year) == 5) {
520 $days += 3;
521 } elseif (Date_Calc::dayOfWeek($day, $month, $year) == 6) {
522 $days += 2;
523 } else {
524 $days += 1;
527 return(Date_Calc::daysToDate($days, $format));
528 } // end func nextWeekday
531 * Returns date of the previous weekday,
532 * skipping from Monday to Friday.
534 * @param string year in format CCYY, default current local year
535 * @param string month in format MM, default current local month
536 * @param string day in format DD, default current local day
537 * @param string format for returned date
539 * @access public
541 * @return string date in given format
544 static function prevWeekday($day = "", $month = "", $year = "", $format = "%Y%m%d")
546 if (empty($year)) {
547 $year = Date_Calc::dateNow("%Y");
550 if (empty($month)) {
551 $month = Date_Calc::dateNow("%m");
554 if (empty($day)) {
555 $day = Date_Calc::dateNow("%d");
558 $days = Date_Calc::dateToDays($day, $month, $year);
560 if (Date_Calc::dayOfWeek($day, $month, $year) == 1) {
561 $days -= 3;
562 } elseif (Date_Calc::dayOfWeek($day, $month, $year) == 0) {
563 $days -= 2;
564 } else {
565 $days -= 1;
568 return(Date_Calc::daysToDate($days, $format));
569 } // end func prevWeekday
572 * Returns date of the next specific day of the week
573 * from the given date.
575 * @param int day of week, 0=Sunday
576 * @param string year in format CCYY, default current local year
577 * @param string month in format MM, default current local month
578 * @param string day in format DD, default current local day
579 * @param boolean onOrAfter if true and days are same, returns current day
580 * @param string format for returned date
582 * @access public
584 * @return string date in given format
587 static function nextDayOfWeek($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d", $onOrAfter = false)
589 if (empty($year)) {
590 $year = Date_Calc::dateNow("%Y");
593 if (empty($month)) {
594 $month = Date_Calc::dateNow("%m");
597 if (empty($day)) {
598 $day = Date_Calc::dateNow("%d");
601 $days = Date_Calc::dateToDays($day, $month, $year);
602 $curr_weekday = Date_Calc::dayOfWeek($day, $month, $year);
604 if ($curr_weekday == $dow) {
605 if (!$onOrAfter) {
606 $days += 7;
608 } elseif ($curr_weekday > $dow) {
609 $days += 7 - ( $curr_weekday - $dow );
610 } else {
611 $days += $dow - $curr_weekday;
614 return(Date_Calc::daysToDate($days, $format));
615 } // end func nextDayOfWeek
618 * Returns date of the previous specific day of the week
619 * from the given date.
621 * @param int day of week, 0=Sunday
622 * @param string year in format CCYY, default current local year
623 * @param string month in format MM, default current local month
624 * @param string day in format DD, default current local day
625 * @param boolean onOrBefore if true and days are same, returns current day
626 * @param string format for returned date
628 * @access public
630 * @return string date in given format
633 static function prevDayOfWeek($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d", $onOrBefore = false)
635 if (empty($year)) {
636 $year = Date_Calc::dateNow("%Y");
639 if (empty($month)) {
640 $month = Date_Calc::dateNow("%m");
643 if (empty($day)) {
644 $day = Date_Calc::dateNow("%d");
647 $days = Date_Calc::dateToDays($day, $month, $year);
648 $curr_weekday = Date_Calc::dayOfWeek($day, $month, $year);
650 if ($curr_weekday == $dow) {
651 if (!$onOrBefore) {
652 $days -= 7;
654 } elseif ($curr_weekday < $dow) {
655 $days -= 7 - ( $dow - $curr_weekday );
656 } else {
657 $days -= $curr_weekday - $dow;
660 return(Date_Calc::daysToDate($days, $format));
661 } // end func prevDayOfWeek
664 * Returns date of the next specific day of the week
665 * on or before the given date.
667 * @param int day of week, 0=Sunday
668 * @param string year in format CCYY, default current local year
669 * @param string month in format MM, default current local month
670 * @param string day in format DD, default current local day
671 * @param string format for returned date
673 * @access public
675 * @return string date in given format
678 static function nextDayOfWeekOnOrAfter($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d")
680 return(Date_Calc::nextDayOfWeek($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d", true));
681 } // end func nextDayOfWeekOnOrAfter
684 * Returns date of the previous specific day of the week
685 * on or before the given date.
687 * @param int day of week, 0=Sunday
688 * @param string year in format CCYY, default current local year
689 * @param string month in format MM, default current local month
690 * @param string day in format DD, default current local day
691 * @param string format for returned date
693 * @access public
695 * @return string date in given format
698 static function prevDayOfWeekOnOrBefore($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d")
700 return(Date_Calc::prevDayOfWeek($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d", true));
701 } // end func prevDayOfWeekOnOrAfter
704 * Returns date of day after given date.
706 * @param string year in format CCYY, default current local year
707 * @param string month in format MM, default current local month
708 * @param string day in format DD, default current local day
709 * @param string format for returned date
711 * @access public
713 * @return string date in given format
716 static function nextDay($day = "", $month = "", $year = "", $format = "%Y%m%d")
718 if (empty($year)) {
719 $year = Date_Calc::dateNow("%Y");
722 if (empty($month)) {
723 $month = Date_Calc::dateNow("%m");
726 if (empty($day)) {
727 $day = Date_Calc::dateNow("%d");
730 $days = Date_Calc::dateToDays($day, $month, $year);
732 return(Date_Calc::daysToDate($days + 1, $format));
733 } // end func nextDay
736 * Returns date of day before given date.
738 * @param string year in format CCYY, default current local year
739 * @param string month in format MM, default current local month
740 * @param string day in format DD, default current local day
741 * @param string format for returned date
743 * @access public
745 * @return string date in given format
748 static function prevDay($day = "", $month = "", $year = "", $format = "%Y%m%d")
750 if (empty($year)) {
751 $year = Date_Calc::dateNow("%Y");
754 if (empty($month)) {
755 $month = Date_Calc::dateNow("%m");
758 if (empty($day)) {
759 $day = Date_Calc::dateNow("%d");
762 $days = Date_Calc::dateToDays($day, $month, $year);
764 return(Date_Calc::daysToDate($days - 1, $format));
765 } // end func prevDay
768 * Sets century for 2 digit year.
769 * 51-99 is 19, else 20
771 * @param string 2 digit year
773 * @access public
775 * @return string 4 digit year
778 static function defaultCentury($year)
780 if (strlen($year) == 1) {
781 $year = "0$year";
784 if ($year > 50) {
785 return( "19$year" );
786 } else {
787 return( "20$year" );
789 } // end func defaultCentury
792 * Returns number of days between two given dates.
794 * @param string year in format CCYY
795 * @param string month in format MM
796 * @param string day in format DD
797 * @param string year in format CCYY
798 * @param string month in format MM
799 * @param string day in format DD
801 * @access public
803 * @return int absolute number of days between dates,
804 * -1 if there is an error.
807 static function dateDiff($day1, $month1, $year1, $day2, $month2, $year2)
809 if (!Date_Calc::isValidDate($day1, $month1, $year1)) {
810 return -1;
813 if (!Date_Calc::isValidDate($day2, $month2, $year2)) {
814 return -1;
817 return(abs((Date_Calc::dateToDays($day1, $month1, $year1))
818 - (Date_Calc::dateToDays($day2, $month2, $year2))));
819 } // end func dateDiff
822 * Find the number of days in the given month.
824 * @param string month in format MM, default current local month
826 * @access public
828 * @return int number of days
831 static function daysInMonth($month = "", $year = "")
833 if (empty($year)) {
834 $year = Date_Calc::dateNow("%Y");
837 if (empty($month)) {
838 $month = Date_Calc::dateNow("%m");
841 if ($month == 2) {
842 if (Date_Calc::isLeapYear($year)) {
843 return 29;
844 } else {
845 return 28;
847 } elseif ($month == 4 or $month == 6 or $month == 9 or $month == 11) {
848 return 30;
849 } else {
850 return 31;
852 } // end func daysInMonth
855 * Returns the number of rows on a calendar month. Useful for
856 * determining the number of rows when displaying a typical
857 * month calendar.
859 * @param string month in format MM, default current local month
860 * @param string year in format YYCC, default current local year
862 * @access public
864 * @return int number of weeks
867 static function weeksInMonth($month = "", $year = "")
869 if (empty($year)) {
870 $year = Date_Calc::dateNow("%Y");
873 if (empty($month)) {
874 $month = Date_Calc::dateNow("%m");
877 // starts on monday
878 if (DATE_CALC_BEGIN_WEEKDAY == 1) {
879 if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
880 $first_week_days = 1;
881 } else {
882 $first_week_days = 7 - (Date_Calc::firstOfMonthWeekday($month, $year) - 1);
885 // starts on saturday
886 } elseif (DATE_CALC_BEGIN_WEEKDAY == 6) {
887 if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
888 $first_week_days = 6;
889 } else {
890 $first_week_days = 7 - (Date_Calc::firstOfMonthWeekday($month, $year) + 1);
893 // starts on sunday
894 } else {
895 $first_week_days = 7 - Date_Calc::firstOfMonthWeekday($month, $year);
898 return ceil(((Date_Calc::daysInMonth($month, $year) - $first_week_days) / 7) + 1);
899 } // end func weeksInMonth
902 * Find the day of the week for the first of the month of given date.
904 * @param string year in format CCYY, default to current local year
905 * @param string month in format MM, default to current local month
907 * @access public
909 * @return int number of weekday for the first day, 0=Sunday
912 static function firstOfMonthWeekday($month = "", $year = "")
914 if (empty($year)) {
915 $year = Date_Calc::dateNow("%Y");
918 if (empty($month)) {
919 $month = Date_Calc::dateNow("%m");
922 return(Date_Calc::dayOfWeek("01", $month, $year));
923 } // end func firstOfMonthWeekday
926 * Return date of first day of month of given date.
928 * @param string year in format CCYY, default current local year
929 * @param string month in format MM, default current local month
930 * @param string format for returned date
932 * @access public
934 * @return string date in given format
937 static function beginOfMonth($month = "", $year = "", $format = "%Y%m%d")
939 if (empty($year)) {
940 $year = Date_Calc::dateNow("%Y");
943 if (empty($month)) {
944 $month = Date_Calc::dateNow("%m");
947 return(Date_Calc::dateFormat("01", $month, $year, $format));
948 } // end of func beginOfMonth
951 * Find the month day of the beginning of week for given date,
952 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
954 * @param string year in format CCYY, default current local year
955 * @param string month in format MM, default current local month
956 * @param string day in format DD, default current local day
957 * @param string format for returned date
959 * @access public
961 * @return string date in given format
964 static function beginOfWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
966 if (empty($year)) {
967 $year = Date_Calc::dateNow("%Y");
970 if (empty($month)) {
971 $month = Date_Calc::dateNow("%m");
974 if (empty($day)) {
975 $day = Date_Calc::dateNow("%d");
978 $this_weekday = Date_Calc::dayOfWeek($day, $month, $year);
980 if (DATE_CALC_BEGIN_WEEKDAY == 1) {
981 if ($this_weekday == 0) {
982 $beginOfWeek = Date_Calc::dateToDays($day, $month, $year) - 6;
983 } else {
984 $beginOfWeek = Date_Calc::dateToDays($day, $month, $year)
985 - $this_weekday + 1;
987 } else {
988 $beginOfWeek = (Date_Calc::dateToDays($day, $month, $year)
989 - $this_weekday);
993 /* $beginOfWeek = (Date_Calc::dateToDays($day,$month,$year)
994 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY)); */
996 return(Date_Calc::daysToDate($beginOfWeek, $format));
997 } // end of func beginOfWeek
1000 * Find the month day of the end of week for given date,
1001 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday
1002 * of following month.)
1004 * @param string year in format CCYY, default current local year
1005 * @param string month in format MM, default current local month
1006 * @param string day in format DD, default current local day
1007 * @param string format for returned date
1009 * @access public
1011 * @return string date in given format
1014 static function endOfWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
1016 if (empty($year)) {
1017 $year = Date_Calc::dateNow("%Y");
1020 if (empty($month)) {
1021 $month = Date_Calc::dateNow("%m");
1024 if (empty($day)) {
1025 $day = Date_Calc::dateNow("%d");
1028 $this_weekday = Date_Calc::dayOfWeek($day, $month, $year);
1030 $last_dayOfWeek = (Date_Calc::dateToDays($day, $month, $year)
1031 + (6 - $this_weekday + DATE_CALC_BEGIN_WEEKDAY));
1033 return(Date_Calc::daysToDate($last_dayOfWeek, $format));
1034 } // end func endOfWeek
1037 * Find the month day of the beginning of week after given date,
1038 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
1040 * @param string year in format CCYY, default current local year
1041 * @param string month in format MM, default current local month
1042 * @param string day in format DD, default current local day
1043 * @param string format for returned date
1045 * @access public
1047 * @return string date in given format
1050 static function beginOfNextWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
1052 if (empty($year)) {
1053 $year = Date_Calc::dateNow("%Y");
1056 if (empty($month)) {
1057 $month = Date_Calc::dateNow("%m");
1060 if (empty($day)) {
1061 $day = Date_Calc::dateNow("%d");
1064 $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day + 7, $month, $year), "%Y%m%d");
1066 $next_week_year = substr($date, 0, 4);
1067 $next_week_month = substr($date, 4, 2);
1068 $next_week_day = substr($date, 6, 2);
1070 $this_weekday = Date_Calc::dayOfWeek($next_week_day, $next_week_month, $next_week_year);
1072 $beginOfWeek = (Date_Calc::dateToDays($next_week_day, $next_week_month, $next_week_year)
1073 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY));
1075 return(Date_Calc::daysToDate($beginOfWeek, $format));
1076 } // end func beginOfNextWeek
1079 * Find the month day of the beginning of week before given date,
1080 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
1082 * @param string year in format CCYY, default current local year
1083 * @param string month in format MM, default current local month
1084 * @param string day in format DD, default current local day
1085 * @param string format for returned date
1087 * @access public
1089 * @return string date in given format
1092 static function beginOfPrevWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
1094 if (empty($year)) {
1095 $year = Date_Calc::dateNow("%Y");
1098 if (empty($month)) {
1099 $month = Date_Calc::dateNow("%m");
1102 if (empty($day)) {
1103 $day = Date_Calc::dateNow("%d");
1106 $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day - 7, $month, $year), "%Y%m%d");
1108 $next_week_year = substr($date, 0, 4);
1109 $next_week_month = substr($date, 4, 2);
1110 $next_week_day = substr($date, 6, 2);
1112 $this_weekday = Date_Calc::dayOfWeek($next_week_day, $next_week_month, $next_week_year);
1114 $beginOfWeek = (Date_Calc::dateToDays($next_week_day, $next_week_month, $next_week_year)
1115 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY));
1117 return(Date_Calc::daysToDate($beginOfWeek, $format));
1118 } // end func beginOfPrevWeek
1121 * Return an array with days in week
1123 * @param string year in format CCYY, default current local year
1124 * @param string month in format MM, default current local month
1125 * @param string day in format DD, default current local day
1126 * @param string format for returned date
1128 * @access public
1130 * @return array $week[$weekday]
1133 static function getCalendarWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
1135 if (empty($year)) {
1136 $year = Date_Calc::dateNow("%Y");
1139 if (empty($month)) {
1140 $month = Date_Calc::dateNow("%m");
1143 if (empty($day)) {
1144 $day = Date_Calc::dateNow("%d");
1147 $week_array = array();
1149 // date for the column of week
1151 $curr_day = Date_Calc::beginOfWeek($day, $month, $year, "%E");
1153 for ($counter = 0; $counter <= 6; $counter++) {
1154 $week_array[$counter] = Date_Calc::daysToDate($curr_day, $format);
1155 $curr_day++;
1158 return $week_array;
1159 } // end func getCalendarWeek
1162 * Return a set of arrays to construct a calendar month for
1163 * the given date.
1165 * @param string year in format CCYY, default current local year
1166 * @param string month in format MM, default current local month
1167 * @param string format for returned date
1169 * @access public
1171 * @return array $month[$row][$col]
1174 static function getCalendarMonth($month = "", $year = "", $format = "%Y%m%d")
1176 if (empty($year)) {
1177 $year = Date_Calc::dateNow("%Y");
1180 if (empty($month)) {
1181 $month = Date_Calc::dateNow("%m");
1184 $month_array = array();
1185 // starts on monday
1186 if (DATE_CALC_BEGIN_WEEKDAY == 1) {
1187 if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
1188 $curr_day = Date_Calc::dateToDays("01", $month, $year) - 6;
1189 } else {
1190 $curr_day = Date_Calc::dateToDays("01", $month, $year) - Date_Calc::firstOfMonthWeekday($month, $year) + 1;
1193 // starts on saturday
1194 } elseif (DATE_CALC_BEGIN_WEEKDAY == 6) {
1195 if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
1196 $curr_day = Date_Calc::dateToDays("01", $month, $year) - 1;
1197 } else {
1198 $curr_day = Date_Calc::dateToDays("01", $month, $year) - Date_Calc::firstOfMonthWeekday($month, $year) - 1;
1201 // starts on sunday
1202 } else {
1203 $curr_day = (Date_Calc::dateToDays("01", $month, $year) - Date_Calc::firstOfMonthWeekday($month, $year));
1206 // number of days in this month
1207 $daysInMonth = Date_Calc::daysInMonth($month, $year);
1209 $weeksInMonth = Date_Calc::weeksInMonth($month, $year);
1210 for ($row_counter = 0; $row_counter < $weeksInMonth; $row_counter++) {
1211 for ($column_counter = 0; $column_counter <= 6; $column_counter++) {
1212 $month_array[$row_counter][$column_counter] = Date_Calc::daysToDate($curr_day, $format);
1213 $curr_day++;
1217 return $month_array;
1218 } // end func getCalendarMonth
1221 * Return a set of arrays to construct a calendar year for
1222 * the given date.
1224 * @param string year in format CCYY, default current local year
1225 * @param string format for returned date
1227 * @access public
1229 * @return array $year[$month][$row][$col]
1232 static function getCalendarYear($year = "", $format = "%Y%m%d")
1234 if (empty($year)) {
1235 $year = Date_Calc::dateNow("%Y");
1238 $year_array = array();
1240 for ($curr_month = 0; $curr_month <= 11; $curr_month++) {
1241 $year_array[$curr_month] = Date_Calc::getCalendarMonth(sprintf("%02d", $curr_month + 1), $year, $format);
1244 return $year_array;
1245 } // end func getCalendarYear
1248 * Converts a date to number of days since a
1249 * distant unspecified epoch.
1251 * @param string year in format CCYY
1252 * @param string month in format MM
1253 * @param string day in format DD
1255 * @access public
1257 * @return integer number of days
1260 static function dateToDays($day, $month, $year)
1263 $century = substr($year, 0, 2);
1264 $year = substr($year, 2, 2);
1266 if ($month > 2) {
1267 $month -= 3;
1268 } else {
1269 $month += 9;
1270 if ($year) {
1271 $year--;
1272 } else {
1273 $year = 99;
1274 $century--;
1278 return ( floor(( 146097 * $century) / 4) +
1279 floor(( 1461 * $year) / 4) +
1280 floor(( 153 * $month + 2) / 5) +
1281 $day + 1721119);
1282 } // end func dateToDays
1285 * Converts number of days to a distant unspecified epoch.
1287 * @param int number of days
1288 * @param string format for returned date
1290 * @access public
1292 * @return string date in specified format
1295 static function daysToDate($days, $format = "%Y%m%d")
1298 $days -= 1721119;
1299 $century = floor(( 4 * $days - 1) / 146097);
1300 $days = floor(4 * $days - 1 - 146097 * $century);
1301 $day = floor($days / 4);
1303 $year = floor(( 4 * $day + 3) / 1461);
1304 $day = floor(4 * $day + 3 - 1461 * $year);
1305 $day = floor(($day + 4) / 4);
1307 $month = floor(( 5 * $day - 3) / 153);
1308 $day = floor(5 * $day - 3 - 153 * $month);
1309 $day = floor(($day + 5) / 5);
1311 if ($month < 10) {
1312 $month += 3;
1313 } else {
1314 $month -= 9;
1315 if ($year++ == 99) {
1316 $year = 0;
1317 $century++;
1321 $century = sprintf("%02d", $century);
1322 $year = sprintf("%02d", $year);
1324 return(Date_Calc::dateFormat($day, $month, $century . $year, $format));
1325 } // end func daysToDate
1328 * Calculates the date of the Nth weekday of the month,
1329 * such as the second Saturday of January 2000.
1331 * @param string occurance: 1=first, 2=second, 3=third, etc.
1332 * @param string dayOfWeek: 0=Sunday, 1=Monday, etc.
1333 * @param string year in format CCYY
1334 * @param string month in format MM
1335 * @param string format for returned date
1337 * @access public
1339 * @return string date in given format
1342 static function NWeekdayOfMonth($occurance, $dayOfWeek, $month, $year, $format = "%Y%m%d")
1345 $year = sprintf("%04d", $year);
1346 $month = sprintf("%02d", $month);
1348 $DOW1day = sprintf("%02d", (($occurance - 1) * 7 + 1));
1349 $DOW1 = Date_Calc::dayOfWeek($DOW1day, $month, $year);
1351 $wdate = ($occurance - 1) * 7 + 1 +
1352 (7 + $dayOfWeek - $DOW1) % 7;
1354 if ($wdate > Date_Calc::daysInMonth($month, $year)) {
1355 return -1;
1356 } else {
1357 return(Date_Calc::dateFormat($wdate, $month, $year, $format));
1359 } // end func NWeekdayOfMonth
1362 * Formats the date in the given format, much like
1363 * strfmt(). This function is used to alleviate the
1364 * problem with 32-bit numbers for dates pre 1970
1365 * or post 2038, as strfmt() has on most systems.
1366 * Most of the formatting options are compatible.
1368 * formatting options:
1370 * %a abbreviated weekday name (Sun, Mon, Tue)
1371 * %A full weekday name (Sunday, Monday, Tuesday)
1372 * %b abbreviated month name (Jan, Feb, Mar)
1373 * %B full month name (January, February, March)
1374 * %d day of month (range 00 to 31)
1375 * %e day of month, single digit (range 0 to 31)
1376 * %E number of days since unspecified epoch (integer)
1377 * (%E is useful for passing a date in a URL as
1378 * an integer value. Then simply use
1379 * daysToDate() to convert back to a date.)
1380 * %j day of year (range 001 to 366)
1381 * %m month as decimal number (range 1 to 12)
1382 * %n newline character (\n)
1383 * %t tab character (\t)
1384 * %w weekday as decimal (0 = Sunday)
1385 * %U week number of current year, first sunday as first week
1386 * %y year as decimal (range 00 to 99)
1387 * %Y year as decimal including century (range 0000 to 9999)
1388 * %% literal '%'
1390 * @param string year in format CCYY
1391 * @param string month in format MM
1392 * @param string day in format DD
1393 * @param string format for returned date
1395 * @access public
1397 * @return string date in given format
1400 static function dateFormat($day, $month, $year, $format)
1402 if (!Date_Calc::isValidDate($day, $month, $year)) {
1403 $year = Date_Calc::dateNow("%Y");
1404 $month = Date_Calc::dateNow("%m");
1405 $day = Date_Calc::dateNow("%d");
1408 $output = "";
1410 for ($strpos = 0; $strpos < strlen($format); $strpos++) {
1411 $char = substr($format, $strpos, 1);
1412 if ($char == "%") {
1413 $nextchar = substr($format, $strpos + 1, 1);
1414 switch ($nextchar) {
1415 case "a":
1416 $output .= Date_Calc::getWeekdayAbbrname($day, $month, $year);
1417 break;
1418 case "A":
1419 $output .= Date_Calc::getWeekdayFullname($day, $month, $year);
1420 break;
1421 case "b":
1422 $output .= Date_Calc::getMonthAbbrname($month);
1423 break;
1424 case "B":
1425 $output .= Date_Calc::getMonthFullname($month);
1426 break;
1427 case "d":
1428 $output .= sprintf("%02d", $day);
1429 break;
1430 case "e":
1431 $output .= $day;
1432 break;
1433 case "E":
1434 $output .= Date_Calc::dateToDays($day, $month, $year);
1435 break;
1436 case "j":
1437 $output .= Date_Calc::julianDate($day, $month, $year);
1438 break;
1439 case "m":
1440 $output .= sprintf("%02d", $month);
1441 break;
1442 case "n":
1443 $output .= "\n";
1444 break;
1445 case "t":
1446 $output .= "\t";
1447 break;
1448 case "w":
1449 $output .= Date_Calc::dayOfWeek($day, $month, $year);
1450 break;
1451 case "U":
1452 $output .= Date_Calc::weekOfYear($day, $month, $year);
1453 break;
1454 case "y":
1455 $output .= substr($year, 2, 2);
1456 break;
1457 case "Y":
1458 $output .= $year;
1459 break;
1460 case "%":
1461 $output .= "%";
1462 break;
1463 default:
1464 $output .= $char . $nextchar;
1467 $strpos++;
1468 } else {
1469 $output .= $char;
1473 return $output;
1474 } // end func dateFormat
1477 * Returns the current local year in format CCYY
1479 * @access public
1481 * @return string year in format CCYY
1484 static function getYear()
1486 return Date_Calc::dateNow("%Y");
1487 } // end func getYear
1490 * Returns the current local month in format MM
1492 * @access public
1494 * @return string month in format MM
1497 static function getMonth()
1499 return Date_Calc::dateNow("%m");
1500 } // end func getMonth
1503 * Returns the current local day in format DD
1505 * @access public
1507 * @return string day in format DD
1510 static function getDay()
1512 return Date_Calc::dateNow("%d");
1513 } // end func getDay
1516 * Returns the full month name for the given month
1518 * @param string month in format MM
1520 * @access public
1522 * @return string full month name
1525 static function getMonthFullname($month)
1527 $month = (int)$month;
1529 if (empty($month)) {
1530 $month = Date_Calc::dateNow("%m");
1533 $month_names = Date_Calc::getMonthNames();
1534 return $month_names[$month];
1535 // getMonthNames returns months with correct indexes
1536 //return $month_names[($month - 1)];
1537 } // end func getMonthFullname
1540 * Returns the abbreviated month name for the given month
1542 * @param string month in format MM
1543 * @param int optional length of abbreviation, default is 3
1545 * @access public
1547 * @return string abbreviated month name
1548 * @see Date_Calc::getMonthFullname
1551 static function getMonthAbbrname($month, $length = 3)
1553 $month = (int)$month;
1555 if (empty($month)) {
1556 $month = Date_Calc::dateNow("%m");
1559 return substr(Date_Calc::getMonthFullname($month), 0, $length);
1560 } // end func getMonthAbbrname
1563 * Returns the full weekday name for the given date
1565 * @param string year in format CCYY, default current local year
1566 * @param string month in format MM, default current local month
1567 * @param string day in format DD, default current local day
1569 * @access public
1571 * @return string full month name
1574 static function getWeekdayFullname($day = "", $month = "", $year = "")
1576 if (empty($year)) {
1577 $year = Date_Calc::dateNow("%Y");
1580 if (empty($month)) {
1581 $month = Date_Calc::dateNow("%m");
1584 if (empty($day)) {
1585 $day = Date_Calc::dateNow("%d");
1588 $weekday_names = Date_Calc::getWeekDays();
1589 $weekday = Date_Calc::dayOfWeek($day, $month, $year);
1591 return $weekday_names[$weekday];
1592 } // end func getWeekdayFullname
1595 * Returns the abbreviated weekday name for the given date
1597 * @param string year in format CCYY, default current local year
1598 * @param string month in format MM, default current local month
1599 * @param string day in format DD, default current local day
1600 * @param int optional length of abbreviation, default is 3
1602 * @access public
1604 * @return string full month name
1605 * @see Date_Calc::getWeekdayFullname
1608 static function getWeekdayAbbrname($day = "", $month = "", $year = "", $length = 3)
1610 if (empty($year)) {
1611 $year = Date_Calc::dateNow("%Y");
1614 if (empty($month)) {
1615 $month = Date_Calc::dateNow("%m");
1618 if (empty($day)) {
1619 $day = Date_Calc::dateNow("%d");
1622 return substr(Date_Calc::getWeekdayFullname($day, $month, $year), 0, $length);
1623 } // end func getWeekdayFullname
1626 * Returns the numeric month from the month name or an abreviation
1628 * Both August and Aug would return 8.
1629 * Month name is case insensitive.
1631 * @param string month name
1632 * @return integer month number
1634 static function getMonthFromFullName($month)
1636 $month = strtolower($month);
1637 $months = Date_Calc::getMonthNames();
1638 foreach ($months as $id => $name) {
1639 if (preg_match("/" . addcslashes($month, '/') . "/", strtolower($name))) {
1640 return($id);
1644 return(0);
1648 * Retunrs an array of month names
1650 * Used to take advantage of the setlocale function to return
1651 * language specific month names.
1652 * XXX cache values to some global array to avoid preformace hits when called more than once.
1654 * @returns array An array of month names
1656 static function getMonthNames()
1658 for ($i = 1; $i < 13; $i++) {
1659 $months[$i] = strftime('%B', mktime(0, 0, 0, $i, 1, 2001));
1662 return($months);
1666 * Returns an array of week days
1668 * Used to take advantage of the setlocale function to
1669 * return language specific week days
1670 * XXX cache values to some global array to avoid preformace hits when called more than once.
1672 * @returns array An array of week day names
1674 static function getWeekDays()
1676 for ($i = 0; $i < 7; $i++) {
1677 $weekdays[$i] = strftime('%A', mktime(0, 0, 0, 1, $i, 2001));
1680 return($weekdays);
1682 } // end class Date_calendar