2 /* vim: set expandtab tabstop=4 shiftwidth=4: */
5 * Contains the Calendar_Engine_PearDate class
9 * LICENSE: Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * @category Date and Time
32 * @author Lorenzo Alberton <l.alberton@quipo.it>
33 * @copyright 2003-2007 Lorenzo Alberton
34 * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
35 * @version CVS: $Id: PearDate.php 4940 2012-06-06 02:20:28Z fishbone $
36 * @link http://pear.php.net/package/Calendar
40 * Load PEAR::Date class
42 require_once 'Date.php';
45 * Performs calendar calculations based on the PEAR::Date class
46 * Timestamps are in the ISO-8601 format (YYYY-MM-DD HH:MM:SS)
48 * @category Date and Time
50 * @author Lorenzo Alberton <l.alberton@quipo.it>
51 * @copyright 2003-2007 Lorenzo Alberton
52 * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause)
53 * @link http://pear.php.net/package/Calendar
56 class Calendar_Engine_PearDate /* implements Calendar_Engine_Interface */
59 * Makes sure a given timestamp is only ever parsed once
60 * Uses a static variable to prevent date() being used twice
61 * for a date which is already known
63 * @param mixed $stamp Any timestamp format recognized by Pear::Date
65 * @return object Pear::Date object
68 function stampCollection($stamp)
70 static $stamps = array();
71 if (!isset($stamps[$stamp])) {
72 $stamps[$stamp] = new Date($stamp);
74 return $stamps[$stamp];
78 * Returns a numeric year given a iso-8601 datetime
80 * @param string $stamp iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
82 * @return int year (e.g. 2003)
85 function stampToYear($stamp)
87 $date = Calendar_Engine_PearDate::stampCollection($stamp);
88 return (int)$date->year;
92 * Returns a numeric month given a iso-8601 datetime
94 * @param string $stamp iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
96 * @return int month (e.g. 9)
99 function stampToMonth($stamp)
101 $date = Calendar_Engine_PearDate::stampCollection($stamp);
102 return (int)$date->month;
106 * Returns a numeric day given a iso-8601 datetime
108 * @param string $stamp iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
110 * @return int day (e.g. 15)
113 function stampToDay($stamp)
115 $date = Calendar_Engine_PearDate::stampCollection($stamp);
116 return (int)$date->day;
120 * Returns a numeric hour given a iso-8601 datetime
122 * @param string $stamp iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
124 * @return int hour (e.g. 13)
127 function stampToHour($stamp)
129 $date = Calendar_Engine_PearDate::stampCollection($stamp);
130 return (int)$date->hour;
134 * Returns a numeric minute given a iso-8601 datetime
136 * @param string $stamp iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
138 * @return int minute (e.g. 34)
141 function stampToMinute($stamp)
143 $date = Calendar_Engine_PearDate::stampCollection($stamp);
144 return (int)$date->minute;
148 * Returns a numeric second given a iso-8601 datetime
150 * @param string $stamp iso-8601 datetime (YYYY-MM-DD HH:MM:SS)
152 * @return int second (e.g. 51)
155 function stampToSecond($stamp)
157 $date = Calendar_Engine_PearDate::stampCollection($stamp);
158 return (int)$date->second;
162 * Returns a iso-8601 datetime
164 * @param int $y year (2003)
165 * @param int $m month (9)
166 * @param int $d day (13)
167 * @param int $h hour (13)
168 * @param int $i minute (34)
169 * @param int $s second (53)
171 * @return string iso-8601 datetime
174 function dateToStamp($y, $m, $d, $h=0, $i=0, $s=0)
177 Calendar_Engine_PearDate::adjustDate($y, $m, $d, $h, $i, $s);
178 $key = $y.$m.$d.$h.$i.$s;
179 if (!isset($r[$key])) {
180 $r[$key] = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
181 $y, $m, $d, $h, $i, $s);
187 * Set the correct date values (useful for math operations on dates)
189 * @param int &$y year (2003)
190 * @param int &$m month (9)
191 * @param int &$d day (13)
192 * @param int &$h hour (13)
193 * @param int &$i minute (34)
194 * @param int &$s second (53)
199 function adjustDate(&$y, &$m, &$d, &$h, &$i, &$s)
202 $m -= floor($s / 60);
206 $m += floor($s / 60);
210 $h -= floor($i / 60);
214 $h += floor($i / 60);
218 $d -= floor($h / 24);
222 $d += floor($h / 24);
225 for(; $m < 1; $y--, $m+=12);
226 for(; $m > 12; $y++, $m-=12);
235 $d += Date_Calc::daysInMonth($m, $y);
237 for ($max_days = Date_Calc::daysInMonth($m, $y); $d > $max_days; ) {
249 * The upper limit on years that the Calendar Engine can work with
254 function getMaxYears()
260 * The lower limit on years that the Calendar Engine can work with
265 function getMinYears()
271 * Returns the number of months in a year
278 function getMonthsInYear($y=null)
284 * Returns the number of days in a month, given year and month
286 * @param int $y year (2003)
287 * @param int $m month (9)
289 * @return int days in month
292 function getDaysInMonth($y, $m)
294 return (int)Date_Calc::daysInMonth($m, $y);
298 * Returns numeric representation of the day of the week in a month,
299 * given year and month
301 * @param int $y year (2003)
302 * @param int $m month (9)
304 * @return int from 0 to 7
307 function getFirstDayInMonth($y, $m)
309 return (int)Date_Calc::dayOfWeek(1, $m, $y);
313 * Returns the number of days in a week
315 * @param int $y year (2003)
316 * @param int $m month (9)
317 * @param int $d day (4)
322 function getDaysInWeek($y=null, $m=null, $d=null)
328 * Returns the number of the week in the year (ISO-8601), given a date
330 * @param int $y year (2003)
331 * @param int $m month (9)
332 * @param int $d day (4)
334 * @return int week number
337 function getWeekNInYear($y, $m, $d)
339 //return Date_Calc::weekOfYear($d, $m, $y); //beware, Date_Calc doesn't follow ISO-8601 standard!
340 list($nYear, $nWeek) = Date_Calc::weekOfYear4th($d, $m, $y);
345 * Returns the number of the week in the month, given a date
347 * @param int $y year (2003)
348 * @param int $m month (9)
349 * @param int $d day (4)
350 * @param int $firstDay first day of the week (default: monday)
352 * @return int week number
355 function getWeekNInMonth($y, $m, $d, $firstDay=1)
357 $weekEnd = ($firstDay == 0) ? $this->getDaysInWeek()-1 : $firstDay-1;
358 $end_of_week = (int)Date_Calc::nextDayOfWeek($weekEnd, 1, $m, $y, '%e', true);
360 while ($d > $end_of_week) {
362 $end_of_week += $this->getDaysInWeek();
368 * Returns the number of weeks in the month
370 * @param int $y year (2003)
371 * @param int $m month (9)
372 * @param int $firstDay first day of the week (default: monday)
374 * @return int weeks number
377 function getWeeksInMonth($y, $m, $firstDay=1)
379 $FDOM = Date_Calc::firstOfMonthWeekday($m, $y);
381 $FDOM = $this->getDaysInWeek();
383 if ($FDOM > $firstDay) {
384 $daysInTheFirstWeek = $this->getDaysInWeek() - $FDOM + $firstDay;
387 $daysInTheFirstWeek = $firstDay - $FDOM;
390 $daysInTheFirstWeek %= $this->getDaysInWeek();
391 return (int)(ceil(($this->getDaysInMonth($y, $m) - $daysInTheFirstWeek) /
392 $this->getDaysInWeek()) + $weeks);
396 * Returns the number of the day of the week (0=sunday, 1=monday...)
398 * @param int $y year (2003)
399 * @param int $m month (9)
400 * @param int $d day (4)
402 * @return int weekday number
405 function getDayOfWeek($y, $m, $d)
407 return Date_Calc::dayOfWeek($d, $m, $y);
411 * Returns a list of integer days of the week beginning 0
413 * @param int $y year (2003)
414 * @param int $m month (9)
415 * @param int $d day (4)
417 * @return array (0, 1, 2, 3, 4, 5, 6) 1 = Monday
420 function getWeekDays($y=null, $m=null, $d=null)
422 return array(0, 1, 2, 3, 4, 5, 6);
426 * Returns the default first day of the week
428 * @param int $y year (2003)
429 * @param int $m month (9)
430 * @param int $d day (4)
432 * @return int (default 1 = Monday)
435 function getFirstDayOfWeek($y=null, $m=null, $d=null)
441 * Returns the number of hours in a day
443 * @param int $y year (2003)
444 * @param int $m month (9)
445 * @param int $d day (4)
450 function getHoursInDay($y=null,$m=null,$d=null)
456 * Returns the number of minutes in an hour
458 * @param int $y year (2003)
459 * @param int $m month (9)
460 * @param int $d day (4)
466 function getMinutesInHour($y=null,$m=null,$d=null,$h=null)
472 * Returns the number of seconds in a minutes
474 * @param int $y year (2003)
475 * @param int $m month (9)
476 * @param int $d day (4)
478 * @param int $i minute
483 function getSecondsInMinute($y=null,$m=null,$d=null,$h=null,$i=null)
489 * Checks if the given day is the current day
491 * @param mixed $stamp Any timestamp format recognized by Pear::Date
496 function isToday($stamp)
498 static $today = null;
499 if (is_null($today)) {
502 $date = Calendar_Engine_PearDate::stampCollection($stamp);
503 return ( $date->day == $today->getDay()
504 && $date->month == $today->getMonth()
505 && $date->year == $today->getYear()