Source for file date.php
Documentation is available at date.php
* Simple date and time classes to perform basic date calculations
* @author Stuart Prescott
* @copyright Copyright Stuart Prescott
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
/** Load ancillary functions */
require_once 'inc/typeinfo.php';
require_once 'inc/bb/configreader.php';
* Simple date class to perform basic date calculations
* WARNING USING TICKS DIRECTLY IS DANGEROUS
* The ticks variable here is a little problematic... daylight saving transitions tend
* to make it rather frought. For example, for the purposes of this system,
* if you want to know what 4 days after 9am 20th March
* is, you expect to get 9am 23rd March regardless of a timezone change from daylight saving.
* For example, this might not give you what you want:<code>
* $date = new SimpleDate('2005-03-20');
* $date->addSecs(4*24*60*60); // add 4 days
* $date = new SimpleDate('2005-03-20');
* $date->addDays(4); // add 4 days
* cache of date in string format
* date in seconds since epoch
* construct a Date-Time object
* constructor will work with $time in the following formats:
* - YYYY-MM-DD (assumes 00:00:00 for time part)
* - YYYY-MM-DD HH:MM (assumes :00 for seconds part)
* @param mixed $time initial time to use
($time ==
NULL) &&
$time =
0;
} elseif (type_is_a($time, 'SimpleDate')) {
* set the date and time from a string
* - YYYY-MM-DD (assumes 00:00:00)
* - YYYY-MM-DD HH:MM (assumes :00)
* @param mixed $s date time string
if (! isset
($this->_cache['datetime'])) {
return $this->_cache['datetime'];
if (! isset
($this->_cache['time'])) {
if (! isset
($this->_cache['date'])) {
* get a short string representation for the current locale
* @return string time value in short time format
if (! isset
($this->_cache['lshortDate'])) {
$format =
$conf->value('language', 'date_shortdate', 'Y-m-d');
return $this->_cache['lshortDate'];
* get a short string representation for the current locale
* @return string time value in short time format
if (! isset
($this->_cache['lshortTime'])) {
$format =
$conf->value('language', 'date_shorttime', 'H:i');
return $this->_cache['lshortTime'];
* get a short string representation for the current locale
* @return string time value in short time format
if (! isset
($this->_cache['lshortDateTime'])) {
$format =
$conf->value('language', 'date_shortdatetime', 'Y-m-d H:i');
return $this->_cache['lshortDateTime'];
* get a long string representation for the current locale
* @return string time value in long time format
if (! isset
($this->_cache['llongDate'])) {
$format =
$conf->value('language', 'date_longdate', 'D F j, Y');
return $this->_cache['llongDate'];
* get a long string representation for the current locale
* @return string time value in long time format
if (! isset
($this->_cache['llongTime'])) {
$format =
$conf->value('language', 'date_longtime', 'H:i:s');
return $this->_cache['llongTime'];
* get a long string representation for the current locale
* @return string time value in long time format
if (! isset
($this->_cache['llongDateTime'])) {
$format =
$conf->value('language', 'date_longdatetime', 'H:i:s, D F j, Y');
return $this->_cache['llongDateTime'];
* Get a string representation of this time in the specified format
* Recognised format characters are as follows:
* d Day of the month, 2 digits with leading zeros 01 to 31
* D A textual representation of a day, three letters Mon through Sun
* j Day of the month without leading zeros 1 to 31
* l (lowercase 'L') A full textual representation of the day of the week Sunday through Saturday
* F A full textual representation of a month, such as January or March January through December
* m Numeric representation of a month, with leading zeros 01 through 12
* M A short textual representation of a month, three letters Jan through Dec
* n Numeric representation of a month, without leading zeros 1 through 12
* Y A full numeric representation of a year, 4 digits Examples: 1999 or 2003
* y A two digit representation of a year Examples: 99 or 03
* a Lowercase Ante meridiem and Post meridiem am or pm
* A Uppercase Ante meridiem and Post meridiem AM or PM
* g 12-hour format of an hour without leading zeros 1 through 12
* G 24-hour format of an hour without leading zeros 0 through 23
* h 12-hour format of an hour with leading zeros 01 through 12
* H 24-hour format of an hour with leading zeros 00 through 23
* i Minutes with leading zeros 00 to 59
* s Seconds, with leading zeros 00 through 59
* @return string time value in short time format
$i18n =
date_make_translation_array();
$s =
''; // return string
$c =
''; // current character
$p =
''; // previous character
#print "Analysing $format";
$formatLen =
strlen($format);
for ($i=
0; $i<
$formatLen; $i++
) {
if ($i >
0 &&
$format[$i-
1] ==
'\\') {
#print " $i: $c ($s)...";
#$s .= date($c, $this->ticks);
* set the date and time from seconds since epoch
#echo "SimpleDate::Ticks $s<br />";
#preDump(debug_backtrace());
* add a whole number of days to the current date-time
* @param integer $d days to add
* add a time (i.e. a number of seconds) to the current date-time
* @param mixed $d days to add
if (type_is_a($t, 'SimpleTime')) {
$this->ticks +=
$t->seconds();
* add a whole number of seconds to the current date-time
* @param integer $s seconds to add
* round (down) the date-time to the current day
* sets the current YYY-MM-DD HH:MM:SS to YYYY-MM-DD 00:00:00
// this might look as though it would be faster by avoiding the expensive strtotime() call,
// (10000 reps took average 0.490s with PHP 4.4.2, libc6-2.3.6)
// $this->setTimeParts(0,0,0,date('d', $this->ticks),date('m', $this->ticks),date('Y', $this->ticks));
// but this is actually faster.
// (10000 reps took average 0.385s with PHP 4.4.2, libc6-2.3.6; that's 21% faster)
* round (down) the date-time to the start of the current week (Sunday)
* round (down) the date-time to the start of the current month (the 1st)
* round (down) the date-time to the start of the current quarter (1st Jan, 1st Apr, 1st Jul, 1st Oct)
$quarter =
floor(($month-
1)/
3)*
3+
1;
* round (down) the date-time to the start of the current year (1st Jan)
* returns the number of days between two dates ($this - $date)
* note that it will return fractional days across daylight saving boundaries
* @param SimpleDate $date date to subtract from this date
return $this->subtract($date) /
(24 *
60 *
60);
* returns the number of days between two dates ($this - $date) accounting for daylight saving
* @param SimpleDate $date date to subtract from this date
//Calculate the number of days as a fraction, removing fractions due to daylight saving
//We don't want to count an extra day (or part thereof) just because the day range
//includes going from summertime to wintertime so the date range includes an extra hour!
$tz2 =
date('Z', $date->ticks);
// same timezone, so return the computed amount
#echo "Using numdays $tz1 $tz2 ";
// subtract the difference in the timezones to fix this
#echo "Using tzinfo: $tz1 $tz2 ";
return $numdays -
($tz2-
$tz1) /
(24*
60*
60);
* returns the number of days (or part thereof) between two dates ($this - $d)
* @param SimpleDate $date date to subtract from this date
//we want this to be an integer and since we want "part thereof" we'd normally round up
//but daylight saving might cause problems.... We also have to include the part day at
//the beginning and the end
$stopwhole->ticks +=
24*
60*
60-
1;
// $stopwhole->_setStr();
return $stopwhole->dsDaysBetween($startwhole);
* returns the number of seconds between two times
* NB this does not specially account for daylight saving changes, so will not always give
* the 24*60*60 for two datetimes that are 1 day apart on the calendar...!
* @param SimpleDate $date date to subtract from this date
#echo "$this->ticks - $date->ticks ";
return $this->ticks -
$date->ticks;
* returns a SimpleTime object for just the time component of this date time
* @return SimpleTime object of just the HH:MM:SS component of this date
* Sets the time component of this date-time to the specified time but with the same date as currently set
* The specified time can be HH:MM HH:MM:SS, seconds since midnight or a SimpleTime object
* @param mixed time to use
//echo $this->dump().$s.'<br/>';
// Benchmarks of 10000 calls to setTime($time)
// Original algorithm, dayRound() and then addTimeParts(); avg over 10 benchmark runs = 1.28s
// $time = new SimpleTime($s);
// $this->addTimeParts($time->part('s'), $time->part('i'), $time->part('H'), 0,0,0);
// setTimeParts() directly; avg over 10 benchmark runs = 0.80s
//$this->setTimeParts(date('s', $time->ticks),date('i', $time->ticks),date('H', $time->ticks),
// date('d', $this->ticks),date('m', $this->ticks),date('Y', $this->ticks));
$this->setTimeParts($time->part('s'), $time->part('i'), $time->part('H'),
* Sets this SimpleDate to the earlier of $this and $t
* Sets this SimpleDate to the later of $this and $t
* round time down to the nearest $g time-granularity measure
* Example: if this date time is set to 2005-11-21 17:48 and
* $g represents 00:15:00 (i.e. 15 minutes) then this date-time would
* be set to 2005-11-21 17:45 by rounding to the nearest 15 minutes.
* Add components to the current date-time
* Note that this function will take account of daylight saving in unusual (but quite sensible)
* ways... for example, if $today is a SimpleDate object representing midday the day before
* daylight saving ends, then $today->addTimeParts(24*60*60) will give a different result
* to $today->addTimeParts(0,0,0,1). The former will be exactly 24 hours later than the original
* value of $today (11:00), but the latter will 1 calendar day later (12:00).
* @param integer $sec (optional) number of seconds to add to this date-time
* @param integer $min (optional) number of minutes to add to this date-time
* @param integer $hour (optional) number of hours to add to this date-time
* @param integer $day (optional) number of days to add to this date-time
* @param integer $month (optional) number of months to add to this date-time
* @param integer $year (optional) number of years to add to this date-time
function addTimeParts($sec=
0, $min=
0, $hour=
0, $day=
0, $month=
0, $year=
0) {
* Set current date-time by components
* @param integer $sec (optional) seconds to set
* @param integer $min (optional) minutes to set
* @param integer $hour (optional) hours to add set
* @param integer $day (optional) days to add set
* @param integer $month (optional) months to set
* @param integer $year (optional) years to set
function setTimeParts($sec=
0, $min=
0, $hour=
0, $day=
0, $month=
0, $year=
0) {
* return the day of week of the current date.
* @return integer day of week (0 == Sunday, 6 == Saturday)
* return the day of week of the current date as a string (in current language)
* @return string day of week (Sunday, Monday, etc)
* return the (short) day of week of the current date as a string (in current language)
* @return string day of week (Sun, Mon, etc)
* return the day of month
* @return integer day of month (1..31)
return intval(date('d', $this->ticks)); // use intval to remove the leading zero
* return integer month of year (1..12)
* @return integer month of year (1..12)
* return the month of year of the current date as a string (in current language)
* @return string month of the year (January, February etc)
* return the (short) month of the year of the current date as a string (in current language)
* @return string month of the year (Jan, Feb etc)
* returns 365 only in leap years
* @return integer day of year (0..365)
* @return integer year (e.g. 2005)
* dump the datetimestring and ticks in a readable format
* @param boolean $html (optional) use html line endings
* @return string datetimestring and ticks
$s .=
($html ?
'<br />' :
'') .
"\n";
* translate an individual date-related word (day of week, month of year)
* @param string $word word to translate
* @returns string translated word
* Simple time class to perform basic time calculations
* cache of string formatted data
* current time in integer seconds since midnight
* is set to a valid value
* Accepts the following for the initial time:
* - HH:MM (assumes :00 for seconds part)
#echo "New SimpleTime: $time, $type<br />";
} elseif (type_is_a($time, 'SimpleTime')) {
if (! isset
($this->_cache['time'])) {
* Set time by seconds since midnight
if (preg_match('/^(\d\d):(\d\d):(\d\d)$/', $s, $t)) {
$this->ticks =
$t[1]*
3600+
$t[2]*
60+
$t[3];
$this->ticks =
$t[1]*
3600+
$t[2]*
60;
* subtract seconds $this - $other
* @param SimpleTime $other
* @return integer seconds difference
return $this->ticks -
$other->ticks;
* add seconds to this time
* @return integer current seconds since midnight
* set this value to the earlier of $this and $other
* @param SimpleTime $other
* set this value to the later of $this and $other
* @param SimpleTime $other
* get a string representation that includes the number of seconds
* @return string time value in HH:MM:SS format
* get a short string representation for the current locale
* @return string time value in short time format
if (! isset
($this->_cache['short'])) {
$format =
$conf->value('language', 'date_shorttime', 'H:i');
return $this->_cache['short'];
* get a long string representation for the current locale
* @return string time value in long time format
if (! isset
($this->_cache['long'])) {
$format =
$conf->value('language', 'date_longtime', 'H:i:s');
* Get a string representation of this time in the specified format
* Recognised format characters are as follows:
* a Lowercase Ante meridiem and Post meridiem am or pm
* A Uppercase Ante meridiem and Post meridiem AM or PM
* g 12-hour format of an hour without leading zeros 1 through 12
* G 24-hour format of an hour without leading zeros 0 through 23
* h 12-hour format of an hour with leading zeros 01 through 12
* H 24-hour format of an hour with leading zeros 00 through 23
* i Minutes with leading zeros 00 to 59
* s Seconds, with leading zeros 00 through 59
* @return string time value in short time format
// cache the AM/PM data to reduce time spent in i18n function
$s =
''; // return string
$c =
''; // current character
$p =
''; // previous character
#print "Analysing $format";
$formatLen =
strlen($format);
for ($i=
0; $i<
$formatLen; $i++
) {
if ($i >
0 &&
$format[$i-
1] ==
'\\') {
#print " $i: $c ($s)...";
$s .=
$i18n[$this->part('a')];
$s .=
$i18n[$this->part('A')];
$s .=
($this->part('h')-
1) %
12 +
1;
* round time down to the nearest $g time-granularity measure
* @see SimpleDate::floorTime()
// $this->_setStr(); * @param SimpleTime $g time granularity
* round time up to the nearest $g time-granularity measure
* @see SimpleTime::floorTime()
* @param SimpleTime $g time granularity
* Obtain hour, minute or seconds parts of the time
* return hour, minute or seconds parts of the time, emulating the date('H', $ticks) etc
* functions, but not using them as they get too badly confused with timezones to be useful
* @param char $s time part to obtain (valid parts: h, i, s for hours, mins, secs)
* @return integer part of the time
//we don't actually care about zero padding in this case.
//let's just allow 'm' to give minutes as well, as it's easier
return ($this->ticks %
86400 <
43200) ?
'am' :
'pm';
return ($this->ticks %
86400 <
43200) ?
'AM' :
'PM';
//we can't use this as we're not actually using the underlying date-time types here.
//return date($s, $this->ticks);
* Add another time to this time
* @param SimpleTime $t time to add to this one
$this->ticks +=
$t->ticks;
* dump the timestring and ticks in a readable format
* @param boolean $html (optional) use html line endings
* @return string timestring and ticks
$s .=
($html ?
'<br />' :
'') .
"\n";
// We need to define these just so that the date formatting routines can always
// return English names for the days and dates and the translation layer will
// provide the correct translation. We can't just use setlocale() and strftime()
// to do this because they only work if the locale is installed on the server and
// this is frequently not the case (which is why we are using gettext emulation
if ($i18n !==
null) return $i18n;
$i18n['Monday'] =
T_('Monday');
$i18n['Mon'] =
T_('Mon');
$i18n['Tuesday'] =
T_('Tuesday');
$i18n['Tue'] =
T_('Tue');
$i18n['Tues'] =
T_('Tue');
$i18n['Wednesday'] =
T_('Wednesday');
$i18n['Wed'] =
T_('Wed');
$i18n['Thursday'] =
T_('Thursday');
$i18n['Thu'] =
T_('Thu');
$i18n['Thurs'] =
T_('Thu');
$i18n['Friday'] =
T_('Friday');
$i18n['Fri'] =
T_('Fri');
$i18n['Saturday'] =
T_('Saturday');
$i18n['Sat'] =
T_('Sat');
$i18n['Sunday'] =
T_('Sunday');
$i18n['Sun'] =
T_('Sun');
$i18n['January'] =
T_('January');
$i18n['Jan'] =
T_('Jan');
$i18n['February'] =
T_('February');
$i18n['Feb'] =
T_('Feb');
$i18n['March'] =
T_('March');
$i18n['Mar'] =
T_('Mar');
$i18n['April'] =
T_('April');
$i18n['Apr'] =
T_('Apr');
$i18n['May'] =
T_('May');
$i18n['June'] =
T_('June');
$i18n['Jun'] =
T_('Jun');
$i18n['July'] =
T_('July');
$i18n['Jul'] =
T_('Jul');
$i18n['August'] =
T_('August');
$i18n['Aug'] =
T_('Aug');
$i18n['September'] =
T_('September');
$i18n['Sep'] =
T_('Sep');
$i18n['October'] =
T_('October');
$i18n['Oct'] =
T_('Oct');
$i18n['November'] =
T_('November');
$i18n['Nov'] =
T_('Nov');
$i18n['December'] =
T_('December');
$i18n['Dec'] =
T_('Dec');
Documentation generated on Tue, 06 Mar 2007 10:01:12 +0000 by phpDocumentor 1.3.0