Highway to PSR2
[openemr.git] / interface / main / calendar / modules / PostCalendar / pnincludes / Date / Calc.php
blob3e086c721049ab23b805ae415b6c673675662c69
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
34 /**
35 * Returns the current local date. NOTE: This function
36 * retrieves the local date using strftime(), which may
37 * or may not be 32-bit safe on your system.
39 * @param string the strftime() format to return the date
41 * @access public
43 * @return string the current date in specified format
46 static function dateNow($format = "%Y%m%d")
48 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 static function isValidDate($day, $month, $year)
66 if (empty($year) || empty($month) || empty($day)) {
67 return false;
70 // must be digits only
71 if (preg_match("/\D/", $year)) {
72 return false;
75 if (preg_match("/\D/", $month)) {
76 return false;
79 if (preg_match("/\D/", $day)) {
80 return false;
83 if ($year < 0 || $year > 9999) {
84 return false;
87 if ($month < 1 || $month > 12) {
88 return false;
91 if ($day < 1 || $day > 31 || $day > Date_Calc::daysInMonth($month, $year)) {
92 return false;
95 return true;
96 } // end func isValidDate
98 static function isLeapYear($year = "")
101 if (empty($year)) {
102 $year = Date_Calc::dateNow("%Y");
105 if (strlen($year) != 4) {
106 return false;
109 if (preg_match("/\D/", $year)) {
110 return false;
113 return (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0);
114 } // end func isLeapYear
117 * Determines if given date is a future date from now.
119 * @param string year in format CCYY
120 * @param string month in format MM
121 * @param string day in format DD
123 * @access public
125 * @return boolean true/false
128 static function isFutureDate($day, $month, $year)
130 $this_year = Date_Calc::dateNow("%Y");
131 $this_month = Date_Calc::dateNow("%m");
132 $this_day = Date_Calc::dateNow("%d");
135 if ($year > $this_year) {
136 return true;
137 } elseif ($year == $this_year) {
138 if ($month > $this_month) {
139 return true;
140 } elseif ($month == $this_month) {
141 if ($day > $this_day) {
142 return true;
147 return false;
148 } // end func isFutureDate
151 * Determines if given date is a past date from now.
153 * @param string year in format CCYY
154 * @param string month in format MM
155 * @param string day in format DD
157 * @access public
159 * @return boolean true/false
162 static function isPastDate($day, $month, $year)
164 $this_year = Date_Calc::dateNow("%Y");
165 $this_month = Date_Calc::dateNow("%m");
166 $this_day = Date_Calc::dateNow("%d");
169 if ($year < $this_year) {
170 return true;
171 } elseif ($year == $this_year) {
172 if ($month < $this_month) {
173 return true;
174 } elseif ($month == $this_month) {
175 if ($day < $this_day) {
176 return true;
181 return false;
182 } // end func isPastDate
185 * Returns day of week for given date, 0=Sunday
187 * @param string year in format CCYY, default is current local year
188 * @param string month in format MM, default is current local month
189 * @param string day in format DD, default is current local day
191 * @access public
193 * @return int $weekday_number
196 static function dayOfWeek($day = "", $month = "", $year = "")
199 if (empty($year)) {
200 $year = Date_Calc::dateNow("%Y");
203 if (empty($month)) {
204 $month = Date_Calc::dateNow("%m");
207 if (empty($day)) {
208 $day = Date_Calc::dateNow("%d");
211 if ($month > 2) {
212 $month -= 2;
213 } else {
214 $month += 10;
215 $year--;
218 $day = ( floor((13 * $month - 1) / 5) +
219 $day + ($year % 100) +
220 floor(($year % 100) / 4) +
221 floor(($year / 100) / 4) - 2 *
222 floor($year / 100) + 77);
224 $weekday_number = (($day - 7 * floor($day / 7)));
226 return $weekday_number;
227 } // end func dayOfWeek
230 * Returns week of the year, first Sunday is first day of first week
232 * @param string day in format DD
233 * @param string month in format MM
234 * @param string year in format CCYY
236 * @access public
238 * @return integer $week_number
241 static function weekOfYear($day, $month, $year)
243 if (empty($year)) {
244 $year = Date_Calc::dateNow("%Y");
247 if (empty($month)) {
248 $month = Date_Calc::dateNow("%m");
251 if (empty($day)) {
252 $day = Date_Calc::dateNow("%d");
255 $week_year = $year - 1501;
256 $week_day = $week_year * 365 + floor($week_year / 4) - 29872 + 1
257 - floor($week_year / 100) + floor(($week_year - 300) / 400);
259 $week_number =
260 ceil((Date_Calc::julianDate($day, $month, $year) + floor(($week_day + 4) % 7)) / 7);
262 return $week_number;
263 } // end func weekOfYear
266 * Returns number of days since 31 December of year before given date.
268 * @param string year in format CCYY, default is current local year
269 * @param string month in format MM, default is current local month
270 * @param string day in format DD, default is current local day
272 * @access public
274 * @return int $julian
277 static function julianDate($day = "", $month = "", $year = "")
279 if (empty($year)) {
280 $year = Date_Calc::dateNow("%Y");
283 if (empty($month)) {
284 $month = Date_Calc::dateNow("%m");
287 if (empty($day)) {
288 $day = Date_Calc::dateNow("%d");
291 $days = array(0,31,59,90,120,151,181,212,243,273,304,334);
293 $julian = ($days[$month - 1] + $day);
295 if ($month > 2 && Date_Calc::isLeapYear($year)) {
296 $julian++;
299 return($julian);
300 } // end func julianDate
303 * Returns quarter of the year for given date
305 * @param string year in format CCYY, default current local year
306 * @param string month in format MM, default current local month
307 * @param string day in format DD, default current local day
309 * @access public
311 * @return int $year_quarter
314 static function quarterOfYear($day = "", $month = "", $year = "")
316 if (empty($year)) {
317 $year = Date_Calc::dateNow("%Y");
320 if (empty($month)) {
321 $month = Date_Calc::dateNow("%m");
324 if (empty($day)) {
325 $day = Date_Calc::dateNow("%d");
328 $year_quarter = (intval(($month - 1) / 3 + 1));
330 return $year_quarter;
331 } // end func quarterOfYear
334 * Returns date of begin of next month of given date.
336 * @param string year in format CCYY, default current local year
337 * @param string month in format MM, default current local month
338 * @param string day in format DD, default current local day
339 * @param string format for returned date
341 * @access public
343 * @return string date in given format
346 static function beginOfNextMonth($day = "", $month = "", $year = "", $format = "%Y%m%d")
348 if (empty($year)) {
349 $year = Date_Calc::dateNow("%Y");
352 if (empty($month)) {
353 $month = Date_Calc::dateNow("%m");
356 if (empty($day)) {
357 $day = Date_Calc::dateNow("%d");
360 if ($month < 12) {
361 $month++;
362 $day=1;
363 } else {
364 $year++;
365 $month=1;
366 $day=1;
369 return Date_Calc::dateFormat($day, $month, $year, $format);
370 } // end func beginOfNextMonth
373 * Returns date of the last day of next month of given date.
375 * @param string year in format CCYY, default current local year
376 * @param string month in format MM, default current local month
377 * @param string day in format DD, default current local day
378 * @param string format for returned date
380 * @access public
382 * @return string date in given format
385 static function endOfNextMonth($day = "", $month = "", $year = "", $format = "%Y%m%d")
387 if (empty($year)) {
388 $year = Date_Calc::dateNow("%Y");
391 if (empty($month)) {
392 $month = Date_Calc::dateNow("%m");
395 if (empty($day)) {
396 $day = Date_Calc::dateNow("%d");
400 if ($month < 12) {
401 $month++;
402 } else {
403 $year++;
404 $month=1;
407 $day = Date_Calc::daysInMonth($month, $year);
409 return Date_Calc::dateFormat($day, $month, $year, $format);
410 } // end func endOfNextMonth
413 * Returns date of the first day of previous month of given date.
415 * @param string year in format CCYY, default current local year
416 * @param string month in format MM, default current local month
417 * @param string day in format DD, default current local day
418 * @param string format for returned date
420 * @access public
422 * @return string date in given format
425 static function beginOfPrevMonth($day = "", $month = "", $year = "", $format = "%Y%m%d")
427 if (empty($year)) {
428 $year = Date_Calc::dateNow("%Y");
431 if (empty($month)) {
432 $month = Date_Calc::dateNow("%m");
435 if (empty($day)) {
436 $day = Date_Calc::dateNow("%d");
439 if ($month > 1) {
440 $month--;
441 $day=1;
442 } else {
443 $year--;
444 $month=12;
445 $day=1;
448 return Date_Calc::dateFormat($day, $month, $year, $format);
449 } // end func beginOfPrevMonth
452 * Returns date of the last day of previous month for given date.
454 * @param string year in format CCYY, default current local year
455 * @param string month in format MM, default current local month
456 * @param string day in format DD, default current local day
457 * @param string format for returned date
459 * @access public
461 * @return string date in given format
464 static function endOfPrevMonth($day = "", $month = "", $year = "", $format = "%Y%m%d")
466 if (empty($year)) {
467 $year = Date_Calc::dateNow("%Y");
470 if (empty($month)) {
471 $month = Date_Calc::dateNow("%m");
474 if (empty($day)) {
475 $day = Date_Calc::dateNow("%d");
478 if ($month > 1) {
479 $month--;
480 } else {
481 $year--;
482 $month=12;
485 $day = Date_Calc::daysInMonth($month, $year);
487 return Date_Calc::dateFormat($day, $month, $year, $format);
488 } // end func endOfPrevMonth
491 * Returns date of the next weekday of given date,
492 * skipping from Friday to Monday.
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 static function nextWeekday($day = "", $month = "", $year = "", $format = "%Y%m%d")
506 if (empty($year)) {
507 $year = Date_Calc::dateNow("%Y");
510 if (empty($month)) {
511 $month = Date_Calc::dateNow("%m");
514 if (empty($day)) {
515 $day = Date_Calc::dateNow("%d");
518 $days = Date_Calc::dateToDays($day, $month, $year);
520 if (Date_Calc::dayOfWeek($day, $month, $year) == 5) {
521 $days += 3;
522 } elseif (Date_Calc::dayOfWeek($day, $month, $year) == 6) {
523 $days += 2;
524 } else {
525 $days += 1;
528 return(Date_Calc::daysToDate($days, $format));
529 } // end func nextWeekday
532 * Returns date of the previous weekday,
533 * skipping from Monday to Friday.
535 * @param string year in format CCYY, default current local year
536 * @param string month in format MM, default current local month
537 * @param string day in format DD, default current local day
538 * @param string format for returned date
540 * @access public
542 * @return string date in given format
545 static function prevWeekday($day = "", $month = "", $year = "", $format = "%Y%m%d")
547 if (empty($year)) {
548 $year = Date_Calc::dateNow("%Y");
551 if (empty($month)) {
552 $month = Date_Calc::dateNow("%m");
555 if (empty($day)) {
556 $day = Date_Calc::dateNow("%d");
559 $days = Date_Calc::dateToDays($day, $month, $year);
561 if (Date_Calc::dayOfWeek($day, $month, $year) == 1) {
562 $days -= 3;
563 } elseif (Date_Calc::dayOfWeek($day, $month, $year) == 0) {
564 $days -= 2;
565 } else {
566 $days -= 1;
569 return(Date_Calc::daysToDate($days, $format));
570 } // end func prevWeekday
573 * Returns date of the next specific day of the week
574 * from the given date.
576 * @param int day of week, 0=Sunday
577 * @param string year in format CCYY, default current local year
578 * @param string month in format MM, default current local month
579 * @param string day in format DD, default current local day
580 * @param boolean onOrAfter if true and days are same, returns current day
581 * @param string format for returned date
583 * @access public
585 * @return string date in given format
588 static function nextDayOfWeek($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d", $onOrAfter = false)
590 if (empty($year)) {
591 $year = Date_Calc::dateNow("%Y");
594 if (empty($month)) {
595 $month = Date_Calc::dateNow("%m");
598 if (empty($day)) {
599 $day = Date_Calc::dateNow("%d");
602 $days = Date_Calc::dateToDays($day, $month, $year);
603 $curr_weekday = Date_Calc::dayOfWeek($day, $month, $year);
605 if ($curr_weekday == $dow) {
606 if (!$onOrAfter) {
607 $days += 7;
609 } elseif ($curr_weekday > $dow) {
610 $days += 7 - ( $curr_weekday - $dow );
611 } else {
612 $days += $dow - $curr_weekday;
615 return(Date_Calc::daysToDate($days, $format));
616 } // end func nextDayOfWeek
619 * Returns date of the previous specific day of the week
620 * from the given date.
622 * @param int day of week, 0=Sunday
623 * @param string year in format CCYY, default current local year
624 * @param string month in format MM, default current local month
625 * @param string day in format DD, default current local day
626 * @param boolean onOrBefore if true and days are same, returns current day
627 * @param string format for returned date
629 * @access public
631 * @return string date in given format
634 static function prevDayOfWeek($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d", $onOrBefore = false)
636 if (empty($year)) {
637 $year = Date_Calc::dateNow("%Y");
640 if (empty($month)) {
641 $month = Date_Calc::dateNow("%m");
644 if (empty($day)) {
645 $day = Date_Calc::dateNow("%d");
648 $days = Date_Calc::dateToDays($day, $month, $year);
649 $curr_weekday = Date_Calc::dayOfWeek($day, $month, $year);
651 if ($curr_weekday == $dow) {
652 if (!$onOrBefore) {
653 $days -= 7;
655 } elseif ($curr_weekday < $dow) {
656 $days -= 7 - ( $dow - $curr_weekday );
657 } else {
658 $days -= $curr_weekday - $dow;
661 return(Date_Calc::daysToDate($days, $format));
662 } // end func prevDayOfWeek
665 * Returns date of the next specific day of the week
666 * on or before the given date.
668 * @param int day of week, 0=Sunday
669 * @param string year in format CCYY, default current local year
670 * @param string month in format MM, default current local month
671 * @param string day in format DD, default current local day
672 * @param string format for returned date
674 * @access public
676 * @return string date in given format
679 static function nextDayOfWeekOnOrAfter($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d")
681 return(Date_Calc::nextDayOfWeek($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d", true));
682 } // end func nextDayOfWeekOnOrAfter
685 * Returns date of the previous specific day of the week
686 * on or before the given date.
688 * @param int day of week, 0=Sunday
689 * @param string year in format CCYY, default current local year
690 * @param string month in format MM, default current local month
691 * @param string day in format DD, default current local day
692 * @param string format for returned date
694 * @access public
696 * @return string date in given format
699 static function prevDayOfWeekOnOrBefore($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d")
701 return(Date_Calc::prevDayOfWeek($dow, $day = "", $month = "", $year = "", $format = "%Y%m%d", true));
702 } // end func prevDayOfWeekOnOrAfter
705 * Returns date of day after given date.
707 * @param string year in format CCYY, default current local year
708 * @param string month in format MM, default current local month
709 * @param string day in format DD, default current local day
710 * @param string format for returned date
712 * @access public
714 * @return string date in given format
717 static function nextDay($day = "", $month = "", $year = "", $format = "%Y%m%d")
719 if (empty($year)) {
720 $year = Date_Calc::dateNow("%Y");
723 if (empty($month)) {
724 $month = Date_Calc::dateNow("%m");
727 if (empty($day)) {
728 $day = Date_Calc::dateNow("%d");
731 $days = Date_Calc::dateToDays($day, $month, $year);
733 return(Date_Calc::daysToDate($days + 1, $format));
734 } // end func nextDay
737 * Returns date of day before given date.
739 * @param string year in format CCYY, default current local year
740 * @param string month in format MM, default current local month
741 * @param string day in format DD, default current local day
742 * @param string format for returned date
744 * @access public
746 * @return string date in given format
749 static function prevDay($day = "", $month = "", $year = "", $format = "%Y%m%d")
751 if (empty($year)) {
752 $year = Date_Calc::dateNow("%Y");
755 if (empty($month)) {
756 $month = Date_Calc::dateNow("%m");
759 if (empty($day)) {
760 $day = Date_Calc::dateNow("%d");
763 $days = Date_Calc::dateToDays($day, $month, $year);
765 return(Date_Calc::daysToDate($days - 1, $format));
766 } // end func prevDay
769 * Sets century for 2 digit year.
770 * 51-99 is 19, else 20
772 * @param string 2 digit year
774 * @access public
776 * @return string 4 digit year
779 static function defaultCentury($year)
781 if (strlen($year) == 1) {
782 $year = "0$year";
785 if ($year > 50) {
786 return( "19$year" );
787 } else {
788 return( "20$year" );
790 } // end func defaultCentury
793 * Returns number of days between two given dates.
795 * @param string year in format CCYY
796 * @param string month in format MM
797 * @param string day in format DD
798 * @param string year in format CCYY
799 * @param string month in format MM
800 * @param string day in format DD
802 * @access public
804 * @return int absolute number of days between dates,
805 * -1 if there is an error.
808 static function dateDiff($day1, $month1, $year1, $day2, $month2, $year2)
810 if (!Date_Calc::isValidDate($day1, $month1, $year1)) {
811 return -1;
814 if (!Date_Calc::isValidDate($day2, $month2, $year2)) {
815 return -1;
818 return(abs((Date_Calc::dateToDays($day1, $month1, $year1))
819 - (Date_Calc::dateToDays($day2, $month2, $year2))));
820 } // end func dateDiff
823 * Find the number of days in the given month.
825 * @param string month in format MM, default current local month
827 * @access public
829 * @return int number of days
832 static function daysInMonth($month = "", $year = "")
834 if (empty($year)) {
835 $year = Date_Calc::dateNow("%Y");
838 if (empty($month)) {
839 $month = Date_Calc::dateNow("%m");
842 if ($month == 2) {
843 if (Date_Calc::isLeapYear($year)) {
844 return 29;
845 } else {
846 return 28;
848 } elseif ($month == 4 or $month == 6 or $month == 9 or $month == 11) {
849 return 30;
850 } else {
851 return 31;
853 } // end func daysInMonth
856 * Returns the number of rows on a calendar month. Useful for
857 * determining the number of rows when displaying a typical
858 * month calendar.
860 * @param string month in format MM, default current local month
861 * @param string year in format YYCC, default current local year
863 * @access public
865 * @return int number of weeks
868 static function weeksInMonth($month = "", $year = "")
870 if (empty($year)) {
871 $year = Date_Calc::dateNow("%Y");
874 if (empty($month)) {
875 $month = Date_Calc::dateNow("%m");
878 // starts on monday
879 if (DATE_CALC_BEGIN_WEEKDAY == 1) {
880 if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
881 $first_week_days = 1;
882 } else {
883 $first_week_days = 7 - (Date_Calc::firstOfMonthWeekday($month, $year) - 1);
886 // starts on saturday
887 } elseif (DATE_CALC_BEGIN_WEEKDAY == 6) {
888 if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
889 $first_week_days = 6;
890 } else {
891 $first_week_days = 7 - (Date_Calc::firstOfMonthWeekday($month, $year) + 1);
894 // starts on sunday
895 } else {
896 $first_week_days = 7 - Date_Calc::firstOfMonthWeekday($month, $year);
899 return ceil(((Date_Calc::daysInMonth($month, $year) - $first_week_days) / 7) + 1);
900 } // end func weeksInMonth
903 * Find the day of the week for the first of the month of given date.
905 * @param string year in format CCYY, default to current local year
906 * @param string month in format MM, default to current local month
908 * @access public
910 * @return int number of weekday for the first day, 0=Sunday
913 static function firstOfMonthWeekday($month = "", $year = "")
915 if (empty($year)) {
916 $year = Date_Calc::dateNow("%Y");
919 if (empty($month)) {
920 $month = Date_Calc::dateNow("%m");
923 return(Date_Calc::dayOfWeek("01", $month, $year));
924 } // end func firstOfMonthWeekday
927 * Return date of first day of month of given date.
929 * @param string year in format CCYY, default current local year
930 * @param string month in format MM, default current local month
931 * @param string format for returned date
933 * @access public
935 * @return string date in given format
938 static function beginOfMonth($month = "", $year = "", $format = "%Y%m%d")
940 if (empty($year)) {
941 $year = Date_Calc::dateNow("%Y");
944 if (empty($month)) {
945 $month = Date_Calc::dateNow("%m");
948 return(Date_Calc::dateFormat("01", $month, $year, $format));
949 } // end of func beginOfMonth
952 * Find the month day of the beginning of week for given date,
953 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
955 * @param string year in format CCYY, default current local year
956 * @param string month in format MM, default current local month
957 * @param string day in format DD, default current local day
958 * @param string format for returned date
960 * @access public
962 * @return string date in given format
965 static function beginOfWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
967 if (empty($year)) {
968 $year = Date_Calc::dateNow("%Y");
971 if (empty($month)) {
972 $month = Date_Calc::dateNow("%m");
975 if (empty($day)) {
976 $day = Date_Calc::dateNow("%d");
979 $this_weekday = Date_Calc::dayOfWeek($day, $month, $year);
981 if (DATE_CALC_BEGIN_WEEKDAY == 1) {
982 if ($this_weekday == 0) {
983 $beginOfWeek = Date_Calc::dateToDays($day, $month, $year) - 6;
984 } else {
985 $beginOfWeek = Date_Calc::dateToDays($day, $month, $year)
986 - $this_weekday + 1;
988 } else {
989 $beginOfWeek = (Date_Calc::dateToDays($day, $month, $year)
990 - $this_weekday);
994 /* $beginOfWeek = (Date_Calc::dateToDays($day,$month,$year)
995 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY)); */
997 return(Date_Calc::daysToDate($beginOfWeek, $format));
998 } // end of func beginOfWeek
1001 * Find the month day of the end of week for given date,
1002 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday
1003 * of following month.)
1005 * @param string year in format CCYY, default current local year
1006 * @param string month in format MM, default current local month
1007 * @param string day in format DD, default current local day
1008 * @param string format for returned date
1010 * @access public
1012 * @return string date in given format
1015 static function endOfWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
1017 if (empty($year)) {
1018 $year = Date_Calc::dateNow("%Y");
1021 if (empty($month)) {
1022 $month = Date_Calc::dateNow("%m");
1025 if (empty($day)) {
1026 $day = Date_Calc::dateNow("%d");
1029 $this_weekday = Date_Calc::dayOfWeek($day, $month, $year);
1031 $last_dayOfWeek = (Date_Calc::dateToDays($day, $month, $year)
1032 + (6 - $this_weekday + DATE_CALC_BEGIN_WEEKDAY));
1034 return(Date_Calc::daysToDate($last_dayOfWeek, $format));
1035 } // end func endOfWeek
1038 * Find the month day of the beginning of week after given date,
1039 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
1041 * @param string year in format CCYY, default current local year
1042 * @param string month in format MM, default current local month
1043 * @param string day in format DD, default current local day
1044 * @param string format for returned date
1046 * @access public
1048 * @return string date in given format
1051 static function beginOfNextWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
1053 if (empty($year)) {
1054 $year = Date_Calc::dateNow("%Y");
1057 if (empty($month)) {
1058 $month = Date_Calc::dateNow("%m");
1061 if (empty($day)) {
1062 $day = Date_Calc::dateNow("%d");
1065 $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day+7, $month, $year), "%Y%m%d");
1067 $next_week_year = substr($date, 0, 4);
1068 $next_week_month = substr($date, 4, 2);
1069 $next_week_day = substr($date, 6, 2);
1071 $this_weekday = Date_Calc::dayOfWeek($next_week_day, $next_week_month, $next_week_year);
1073 $beginOfWeek = (Date_Calc::dateToDays($next_week_day, $next_week_month, $next_week_year)
1074 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY));
1076 return(Date_Calc::daysToDate($beginOfWeek, $format));
1077 } // end func beginOfNextWeek
1080 * Find the month day of the beginning of week before given date,
1081 * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
1083 * @param string year in format CCYY, default current local year
1084 * @param string month in format MM, default current local month
1085 * @param string day in format DD, default current local day
1086 * @param string format for returned date
1088 * @access public
1090 * @return string date in given format
1093 static function beginOfPrevWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
1095 if (empty($year)) {
1096 $year = Date_Calc::dateNow("%Y");
1099 if (empty($month)) {
1100 $month = Date_Calc::dateNow("%m");
1103 if (empty($day)) {
1104 $day = Date_Calc::dateNow("%d");
1107 $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day-7, $month, $year), "%Y%m%d");
1109 $next_week_year = substr($date, 0, 4);
1110 $next_week_month = substr($date, 4, 2);
1111 $next_week_day = substr($date, 6, 2);
1113 $this_weekday = Date_Calc::dayOfWeek($next_week_day, $next_week_month, $next_week_year);
1115 $beginOfWeek = (Date_Calc::dateToDays($next_week_day, $next_week_month, $next_week_year)
1116 - ($this_weekday - DATE_CALC_BEGIN_WEEKDAY));
1118 return(Date_Calc::daysToDate($beginOfWeek, $format));
1119 } // end func beginOfPrevWeek
1122 * Return an array with days in week
1124 * @param string year in format CCYY, default current local year
1125 * @param string month in format MM, default current local month
1126 * @param string day in format DD, default current local day
1127 * @param string format for returned date
1129 * @access public
1131 * @return array $week[$weekday]
1134 static function getCalendarWeek($day = "", $month = "", $year = "", $format = "%Y%m%d")
1136 if (empty($year)) {
1137 $year = Date_Calc::dateNow("%Y");
1140 if (empty($month)) {
1141 $month = Date_Calc::dateNow("%m");
1144 if (empty($day)) {
1145 $day = Date_Calc::dateNow("%d");
1148 $week_array = array();
1150 // date for the column of week
1152 $curr_day = Date_Calc::beginOfWeek($day, $month, $year, "%E");
1154 for ($counter=0; $counter <= 6; $counter++) {
1155 $week_array[$counter] = Date_Calc::daysToDate($curr_day, $format);
1156 $curr_day++;
1159 return $week_array;
1160 } // end func getCalendarWeek
1163 * Return a set of arrays to construct a calendar month for
1164 * the given date.
1166 * @param string year in format CCYY, default current local year
1167 * @param string month in format MM, default current local month
1168 * @param string format for returned date
1170 * @access public
1172 * @return array $month[$row][$col]
1175 static function getCalendarMonth($month = "", $year = "", $format = "%Y%m%d")
1177 if (empty($year)) {
1178 $year = Date_Calc::dateNow("%Y");
1181 if (empty($month)) {
1182 $month = Date_Calc::dateNow("%m");
1185 $month_array = array();
1186 // starts on monday
1187 if (DATE_CALC_BEGIN_WEEKDAY == 1) {
1188 if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
1189 $curr_day = Date_Calc::dateToDays("01", $month, $year) - 6;
1190 } else {
1191 $curr_day = Date_Calc::dateToDays("01", $month, $year) - Date_Calc::firstOfMonthWeekday($month, $year) + 1;
1194 // starts on saturday
1195 } elseif (DATE_CALC_BEGIN_WEEKDAY == 6) {
1196 if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
1197 $curr_day = Date_Calc::dateToDays("01", $month, $year) - 1;
1198 } else {
1199 $curr_day = Date_Calc::dateToDays("01", $month, $year) - Date_Calc::firstOfMonthWeekday($month, $year) - 1;
1202 // starts on sunday
1203 } else {
1204 $curr_day = (Date_Calc::dateToDays("01", $month, $year) - Date_Calc::firstOfMonthWeekday($month, $year));
1207 // number of days in this month
1208 $daysInMonth = Date_Calc::daysInMonth($month, $year);
1210 $weeksInMonth = Date_Calc::weeksInMonth($month, $year);
1211 for ($row_counter=0; $row_counter < $weeksInMonth; $row_counter++) {
1212 for ($column_counter=0; $column_counter <= 6; $column_counter++) {
1213 $month_array[$row_counter][$column_counter] = Date_Calc::daysToDate($curr_day, $format);
1214 $curr_day++;
1218 return $month_array;
1219 } // end func getCalendarMonth
1222 * Return a set of arrays to construct a calendar year for
1223 * the given date.
1225 * @param string year in format CCYY, default current local year
1226 * @param string format for returned date
1228 * @access public
1230 * @return array $year[$month][$row][$col]
1233 static function getCalendarYear($year = "", $format = "%Y%m%d")
1235 if (empty($year)) {
1236 $year = Date_Calc::dateNow("%Y");
1239 $year_array = array();
1241 for ($curr_month=0; $curr_month <=11; $curr_month++) {
1242 $year_array[$curr_month] = Date_Calc::getCalendarMonth(sprintf("%02d", $curr_month+1), $year, $format);
1245 return $year_array;
1246 } // end func getCalendarYear
1249 * Converts a date to number of days since a
1250 * distant unspecified epoch.
1252 * @param string year in format CCYY
1253 * @param string month in format MM
1254 * @param string day in format DD
1256 * @access public
1258 * @return integer number of days
1261 static function dateToDays($day, $month, $year)
1264 $century = substr($year, 0, 2);
1265 $year = substr($year, 2, 2);
1267 if ($month > 2) {
1268 $month -= 3;
1269 } else {
1270 $month += 9;
1271 if ($year) {
1272 $year--;
1273 } else {
1274 $year = 99;
1275 $century --;
1279 return ( floor(( 146097 * $century) / 4) +
1280 floor(( 1461 * $year) / 4) +
1281 floor(( 153 * $month + 2) / 5) +
1282 $day + 1721119);
1283 } // end func dateToDays
1286 * Converts number of days to a distant unspecified epoch.
1288 * @param int number of days
1289 * @param string format for returned date
1291 * @access public
1293 * @return string date in specified format
1296 static function daysToDate($days, $format = "%Y%m%d")
1299 $days -= 1721119;
1300 $century = floor(( 4 * $days - 1) / 146097);
1301 $days = floor(4 * $days - 1 - 146097 * $century);
1302 $day = floor($days / 4);
1304 $year = floor(( 4 * $day + 3) / 1461);
1305 $day = floor(4 * $day + 3 - 1461 * $year);
1306 $day = floor(($day + 4) / 4);
1308 $month = floor(( 5 * $day - 3) / 153);
1309 $day = floor(5 * $day - 3 - 153 * $month);
1310 $day = floor(($day + 5) / 5);
1312 if ($month < 10) {
1313 $month +=3;
1314 } else {
1315 $month -=9;
1316 if ($year++ == 99) {
1317 $year = 0;
1318 $century++;
1322 $century = sprintf("%02d", $century);
1323 $year = sprintf("%02d", $year);
1325 return(Date_Calc::dateFormat($day, $month, $century.$year, $format));
1326 } // end func daysToDate
1329 * Calculates the date of the Nth weekday of the month,
1330 * such as the second Saturday of January 2000.
1332 * @param string occurance: 1=first, 2=second, 3=third, etc.
1333 * @param string dayOfWeek: 0=Sunday, 1=Monday, etc.
1334 * @param string year in format CCYY
1335 * @param string month in format MM
1336 * @param string format for returned date
1338 * @access public
1340 * @return string date in given format
1343 static function NWeekdayOfMonth($occurance, $dayOfWeek, $month, $year, $format = "%Y%m%d")
1346 $year = sprintf("%04d", $year);
1347 $month = sprintf("%02d", $month);
1349 $DOW1day = sprintf("%02d", (($occurance - 1) * 7 + 1));
1350 $DOW1 = Date_Calc::dayOfWeek($DOW1day, $month, $year);
1352 $wdate = ($occurance - 1) * 7 + 1 +
1353 (7 + $dayOfWeek - $DOW1) % 7;
1355 if ($wdate > Date_Calc::daysInMonth($month, $year)) {
1356 return -1;
1357 } else {
1358 return(Date_Calc::dateFormat($wdate, $month, $year, $format));
1360 } // end func NWeekdayOfMonth
1363 * Formats the date in the given format, much like
1364 * strfmt(). This function is used to alleviate the
1365 * problem with 32-bit numbers for dates pre 1970
1366 * or post 2038, as strfmt() has on most systems.
1367 * Most of the formatting options are compatible.
1369 * formatting options:
1371 * %a abbreviated weekday name (Sun, Mon, Tue)
1372 * %A full weekday name (Sunday, Monday, Tuesday)
1373 * %b abbreviated month name (Jan, Feb, Mar)
1374 * %B full month name (January, February, March)
1375 * %d day of month (range 00 to 31)
1376 * %e day of month, single digit (range 0 to 31)
1377 * %E number of days since unspecified epoch (integer)
1378 * (%E is useful for passing a date in a URL as
1379 * an integer value. Then simply use
1380 * daysToDate() to convert back to a date.)
1381 * %j day of year (range 001 to 366)
1382 * %m month as decimal number (range 1 to 12)
1383 * %n newline character (\n)
1384 * %t tab character (\t)
1385 * %w weekday as decimal (0 = Sunday)
1386 * %U week number of current year, first sunday as first week
1387 * %y year as decimal (range 00 to 99)
1388 * %Y year as decimal including century (range 0000 to 9999)
1389 * %% literal '%'
1391 * @param string year in format CCYY
1392 * @param string month in format MM
1393 * @param string day in format DD
1394 * @param string format for returned date
1396 * @access public
1398 * @return string date in given format
1401 static function dateFormat($day, $month, $year, $format)
1403 if (!Date_Calc::isValidDate($day, $month, $year)) {
1404 $year = Date_Calc::dateNow("%Y");
1405 $month = Date_Calc::dateNow("%m");
1406 $day = Date_Calc::dateNow("%d");
1409 $output = "";
1411 for ($strpos = 0; $strpos < strlen($format); $strpos++) {
1412 $char = substr($format, $strpos, 1);
1413 if ($char == "%") {
1414 $nextchar = substr($format, $strpos + 1, 1);
1415 switch ($nextchar) {
1416 case "a":
1417 $output .= Date_Calc::getWeekdayAbbrname($day, $month, $year);
1418 break;
1419 case "A":
1420 $output .= Date_Calc::getWeekdayFullname($day, $month, $year);
1421 break;
1422 case "b":
1423 $output .= Date_Calc::getMonthAbbrname($month);
1424 break;
1425 case "B":
1426 $output .= Date_Calc::getMonthFullname($month);
1427 break;
1428 case "d":
1429 $output .= sprintf("%02d", $day);
1430 break;
1431 case "e":
1432 $output .= $day;
1433 break;
1434 case "E":
1435 $output .= Date_Calc::dateToDays($day, $month, $year);
1436 break;
1437 case "j":
1438 $output .= Date_Calc::julianDate($day, $month, $year);
1439 break;
1440 case "m":
1441 $output .= sprintf("%02d", $month);
1442 break;
1443 case "n":
1444 $output .= "\n";
1445 break;
1446 case "t":
1447 $output .= "\t";
1448 break;
1449 case "w":
1450 $output .= Date_Calc::dayOfWeek($day, $month, $year);
1451 break;
1452 case "U":
1453 $output .= Date_Calc::weekOfYear($day, $month, $year);
1454 break;
1455 case "y":
1456 $output .= substr($year, 2, 2);
1457 break;
1458 case "Y":
1459 $output .= $year;
1460 break;
1461 case "%":
1462 $output .= "%";
1463 break;
1464 default:
1465 $output .= $char.$nextchar;
1468 $strpos++;
1469 } else {
1470 $output .= $char;
1474 return $output;
1475 } // end func dateFormat
1478 * Returns the current local year in format CCYY
1480 * @access public
1482 * @return string year in format CCYY
1485 static function getYear()
1487 return Date_Calc::dateNow("%Y");
1488 } // end func getYear
1491 * Returns the current local month in format MM
1493 * @access public
1495 * @return string month in format MM
1498 static function getMonth()
1500 return Date_Calc::dateNow("%m");
1501 } // end func getMonth
1504 * Returns the current local day in format DD
1506 * @access public
1508 * @return string day in format DD
1511 static function getDay()
1513 return Date_Calc::dateNow("%d");
1514 } // end func getDay
1517 * Returns the full month name for the given month
1519 * @param string month in format MM
1521 * @access public
1523 * @return string full month name
1526 static function getMonthFullname($month)
1528 $month = (int)$month;
1530 if (empty($month)) {
1531 $month = Date_Calc::dateNow("%m");
1534 $month_names = Date_Calc::getMonthNames();
1535 return $month_names[$month];
1536 // getMonthNames returns months with correct indexes
1537 //return $month_names[($month - 1)];
1538 } // end func getMonthFullname
1541 * Returns the abbreviated month name for the given month
1543 * @param string month in format MM
1544 * @param int optional length of abbreviation, default is 3
1546 * @access public
1548 * @return string abbreviated month name
1549 * @see Date_Calc::getMonthFullname
1552 static function getMonthAbbrname($month, $length = 3)
1554 $month = (int)$month;
1556 if (empty($month)) {
1557 $month = Date_Calc::dateNow("%m");
1560 return substr(Date_Calc::getMonthFullname($month), 0, $length);
1561 } // end func getMonthAbbrname
1564 * Returns the full weekday name for the given date
1566 * @param string year in format CCYY, default current local year
1567 * @param string month in format MM, default current local month
1568 * @param string day in format DD, default current local day
1570 * @access public
1572 * @return string full month name
1575 static function getWeekdayFullname($day = "", $month = "", $year = "")
1577 if (empty($year)) {
1578 $year = Date_Calc::dateNow("%Y");
1581 if (empty($month)) {
1582 $month = Date_Calc::dateNow("%m");
1585 if (empty($day)) {
1586 $day = Date_Calc::dateNow("%d");
1589 $weekday_names = Date_Calc::getWeekDays();
1590 $weekday = Date_Calc::dayOfWeek($day, $month, $year);
1592 return $weekday_names[$weekday];
1593 } // end func getWeekdayFullname
1596 * Returns the abbreviated weekday name for the given date
1598 * @param string year in format CCYY, default current local year
1599 * @param string month in format MM, default current local month
1600 * @param string day in format DD, default current local day
1601 * @param int optional length of abbreviation, default is 3
1603 * @access public
1605 * @return string full month name
1606 * @see Date_Calc::getWeekdayFullname
1609 static function getWeekdayAbbrname($day = "", $month = "", $year = "", $length = 3)
1611 if (empty($year)) {
1612 $year = Date_Calc::dateNow("%Y");
1615 if (empty($month)) {
1616 $month = Date_Calc::dateNow("%m");
1619 if (empty($day)) {
1620 $day = Date_Calc::dateNow("%d");
1623 return substr(Date_Calc::getWeekdayFullname($day, $month, $year), 0, $length);
1624 } // end func getWeekdayFullname
1627 * Returns the numeric month from the month name or an abreviation
1629 * Both August and Aug would return 8.
1630 * Month name is case insensitive.
1632 * @param string month name
1633 * @return integer month number
1635 static function getMonthFromFullName($month)
1637 $month = strtolower($month);
1638 $months = Date_Calc::getMonthNames();
1639 while (list($id, $name) = each($months)) {
1640 if (preg_match("/" . addcslashes($month, '/') . "/", strtolower($name))) {
1641 return($id);
1645 return(0);
1649 * Retunrs an array of month names
1651 * Used to take advantage of the setlocale function to return
1652 * language specific month names.
1653 * XXX cache values to some global array to avoid preformace hits when called more than once.
1655 * @returns array An array of month names
1657 static function getMonthNames()
1659 for ($i=1; $i<13; $i++) {
1660 $months[$i] = strftime('%B', mktime(0, 0, 0, $i, 1, 2001));
1663 return($months);
1667 * Returns an array of week days
1669 * Used to take advantage of the setlocale function to
1670 * return language specific week days
1671 * XXX cache values to some global array to avoid preformace hits when called more than once.
1673 * @returns array An array of week day names
1675 static function getWeekDays()
1677 for ($i=0; $i<7; $i++) {
1678 $weekdays[$i] = strftime('%A', mktime(0, 0, 0, 1, $i, 2001));
1681 return($weekdays);
1683 } // end class Date_calendar