Source for file Span.php
Documentation is available at Span.php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
* Generic time span handling class for PEAR
* Copyright (c) 1997-2005 Leandro Lucarella, Pierre-Alain Joye
* Redistribution and use in source and binary forms, with or without
* modification, are permitted under the terms of the BSD License.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* @category Date and Time
* @author Leandro Lucarella <llucax@php.net>
* @author Pierre-Alain Joye <pajoye@php.net>
* @copyright 1997-2006 Leandro Lucarella, Pierre-Alain Joye
* @license http://www.opensource.org/licenses/bsd-license.php
* @version CVS: $Id: Span.php,v 1.15 2007/11/29 19:26:08 c01234 Exp $
* @link http://pear.php.net/package/Date
* @since File available since Release 1.4
* Get the Date_Calc class
require_once 'Date/Calc.php';
* Non Numeric Separated Values (NNSV) Input Format
* Input format guessed from something like this:
* days<sep>hours<sep>minutes<sep>seconds
* Where <sep> is any quantity of non numeric chars. If no values are
* given, time span is set to zero, if one value is given, it's used for
* hours, if two values are given it's used for hours and minutes and if
* three values are given, it's used for hours, minutes and seconds.<br>
* '' -> 0, 0, 0, 0 (days, hours, minutes, seconds)<br>
* '12.30' -> 0, 12, 30, 0<br>
* '12:30:18' -> 0, 12, 30, 18<br>
* '3-12-30-18' -> 3, 12, 30, 18<br>
* '3 days, 12-30-18' -> 3, 12, 30, 18<br>
* '12:30 with 18 secs' -> 0, 12, 30, 18<br>
define('DATE_SPAN_INPUT_FORMAT_NNSV', 1 );
* Default time format when converting to a string
$GLOBALS['_DATE_SPAN_FORMAT'] = '%C';
* Default time format when converting from a string
* Generic time span handling class for PEAR
* @category Date and Time
* @author Leandro Lucarella <llucax@php.net>
* @author Pierre-Alain Joye <pajoye@php.net>
* @copyright 1997-2006 Leandro Lucarella, Pierre-Alain Joye
* @license http://www.opensource.org/licenses/bsd-license.php
* @version Release: 1.5.0a1
* @link http://pear.php.net/package/Date
* @since Class available since Release 1.4
* @since Property available since Release 1.0
* The no of hours (0 to 23)
* @since Property available since Release 1.0
* The no of minutes (0 to 59)
* @since Property available since Release 1.0
* The no of seconds (0 to 59)
* @since Property available since Release 1.0
* Creates the time span object calling the set() method.
* @param mixed $time time span expression
* @param mixed $format format string to set it from a string or the
* second date set it from a date diff
function Date_Span($time = 0 , $format = null )
$this->set($time, $format);
* Set the time span to a new value in a 'smart' way
* Sets the time span depending on the argument types, calling
* to the appropriate setFromXxx() method.
* @param mixed $time time span expression
* @param mixed $format format string to set it from a string or the
* second date set it from a date diff
* @return bool true on success
* @see setFromObject(), setFromArray(), setFromString(),
* setFromSeconds(), setFromDateDiff()
function set($time = 0 , $format = null )
if (is_a($time, 'date_span')) {
return $this->copy($time);
} elseif (is_a($time, 'date') and is_a($format, 'date')) {
* Set the time span from an array
* Any value can be a float (but it has no sense in seconds), for example:
* <code>array(23.5, 20, 0)</code>
* is interpreted as 23 hours, .5*60 + 20 = 50 minutes and 0 seconds.
* @param array $time items are counted from right to left. First
* item is for seconds, second for minutes, third
* for hours and fourth for days. If there are
* less items than 4, zero (0) is assumed for the
* @return bool true on success
if (!$tmp1->setFromSeconds (@array_pop($time))) {
if (!$tmp2->setFromMinutes (@array_pop($time))) {
if (!$tmp2->setFromHours (@array_pop($time))) {
if (!$tmp2->setFromDays (@array_pop($time))) {
return $this->copy($tmp1);
* Set the time span from a string based on an input format
* This is some like a mix of format() method and sscanf() PHP function.
* The error checking and validation of this function is very primitive,
* so you should be carefull when using it with unknown $time strings.
* With this method you are assigning day, hour, minute and second
* values, and the last values are used. This means that if you use
* something like setFromString('10, 20', '%H, %h') your time span
* would be 20 hours long. Allways remember that this method sets
* <b>all</b> the values, so if you had a $time span 30 minutes long
* and you make $time->setFromString('20 hours', '%H hours'), $time
* span would be 20 hours long (and not 20 hours and 30 minutes).
* Input format options:<br>
* <code>%C</code> Days with time, same as "%D, %H:%M:%S"<br>
* <code>%d</code> Total days as a float number
* (2 days, 12 hours = 2.5 days)<br>
* <code>%D</code> Days as a decimal number<br>
* <code>%e</code> Total hours as a float number
* (1 day, 2 hours, 30 minutes = 26.5 hours)<br>
* <code>%f</code> Total minutes as a float number
* (2 minutes, 30 seconds = 2.5 minutes)<br>
* <code>%g</code> Total seconds as a decimal number
* (2 minutes, 30 seconds = 90 seconds)<br>
* <code>%h</code> Hours as decimal number<br>
* <code>%H</code> Hours as decimal number limited to 2 digits<br>
* <code>%m</code> Minutes as a decimal number<br>
* <code>%M</code> Minutes as a decimal number limited to 2 digits<br>
* <code>%n</code> Newline character (\n)<br>
* <code>%p</code> Either 'am' or 'pm' depending on the time. If 'pm'
* is detected it adds 12 hours to the resulting time
* span (without any checks). This is case
* <code>%r</code> Time in am/pm notation, same as "%H:%M:%S %p"<br>
* <code>%R</code> Time in 24-hour notation, same as "%H:%M"<br>
* <code>%s</code> Seconds as a decimal number<br>
* <code>%S</code> Seconds as a decimal number limited to 2 digits<br>
* <code>%t</code> Tab character (\t)<br>
* <code>%T</code> Current time equivalent, same as "%H:%M:%S"<br>
* <code>%%</code> Literal '%'<br>
* @param string $time string from where to get the time span
* @param string $format format string
* @return bool true on success
$format = $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
// If format is a string, it parses the string format.
$day = $hour = $minute = $second = 0;
for ($i = 0; $i < strlen($format); $i++ ) {
$nextchar = $format{++ $i};
$str .= '%d, %2d:%2d:%2d';
$str .= '%2d:%2d:%2d %2s';
$str .= $char . $nextchar;
foreach ($vals as $i => $val) {
// If format is a integer, it uses a predefined format
* Set the time span from a total number of seconds
* @param int $seconds total number of seconds
* @return bool true on success
$hour = floor($min / 60 );
$this->second = $sec % 60;
$this->minute = $min % 60;
$this->hour = $hour % 24;
* Set the time span from a total number of minutes
* @param float $minutes total number of minutes
* @return bool true on success
* Set the time span from a total number of hours
* @param float $hours total number of hours
* @return bool true on success
* Set the time span from a total number of days
* @param float $days total number of days
* @return bool true on success
* Set the span from the elapsed time between two dates
* The time span is unsigned, so the date's order is not important.
* @param object $date1 first Date
* @param object $date2 second Date
* @return bool true on success
if (!is_a($date1, 'date') or !is_a($date2, 'date')) {
if ($date1->after ($date2)) {
list ($date1, $date2) = array ($date2, $date1);
$hours = $date2->getHour () - $date1->getHour ();
$mins = $date2->getMinute () - $date1->getMinute ();
$secs = $date2->getSecond () - $date1->getSecond ();
* Set the time span from another time object
* @param object $time source time span object
* @return bool true on success
if (is_a($time, 'date_span')) {
$this->second = $time->second;
$this->minute = $time->minute;
$this->hour = $time->hour;
* Time span pretty printing (similar to Date::format())
* Formats the time span in the given format, similar to
* strftime() and Date::format().<br>
* Formatting options:<br>
* <code>%C</code> Days with time, same as "%D, %H:%M:%S"<br>
* <code>%d</code> Total days as a float number
* (2 days, 12 hours = 2.5 days)<br>
* <code>%D</code> Days as a decimal number<br>
* <code>%e</code> Total hours as a float number
* (1 day, 2 hours, 30 minutes = 26.5 hours)<br>
* <code>%E</code> Total hours as a decimal number
* (1 day, 2 hours, 40 minutes = 26 hours)<br>
* <code>%f</code> Total minutes as a float number
* (2 minutes, 30 seconds = 2.5 minutes)<br>
* <code>%F</code> Total minutes as a decimal number
* (1 hour, 2 minutes, 40 seconds = 62 minutes)<br>
* <code>%g</code> Total seconds as a decimal number
* (2 minutes, 30 seconds = 90 seconds)<br>
* <code>%h</code> Hours as decimal number (0 to 23)<br>
* <code>%H</code> Hours as decimal number (00 to 23)<br>
* <code>%i</code> Hours as decimal number on 12-hour clock
* <code>%I</code> Hours as decimal number on 12-hour clock
* <code>%m</code> Minutes as a decimal number (0 to 59)<br>
* <code>%M</code> Minutes as a decimal number (00 to 59)<br>
* <code>%n</code> Newline character (\n)<br>
* <code>%p</code> Either 'am' or 'pm' depending on the time<br>
* <code>%P</code> Either 'AM' or 'PM' depending on the time<br>
* <code>%r</code> Time in am/pm notation, same as "%I:%M:%S %p"<br>
* <code>%R</code> Time in 24-hour notation, same as "%H:%M"<br>
* <code>%s</code> Seconds as a decimal number (0 to 59)<br>
* <code>%S</code> Seconds as a decimal number (00 to 59)<br>
* <code>%t</code> Tab character (\t)<br>
* <code>%T</code> Current time equivalent, same as "%H:%M:%S"<br>
* <code>%%</code> Literal '%'<br>
* @param string $format the format string for returned time span
* @return string the time span in specified format
function format($format = null )
$format = $GLOBALS['_DATE_SPAN_FORMAT'];
for ($i = 0; $i < strlen($format); $i++ ) {
$nextchar = $format{++ $i};
$output .= sprintf('%d, %02d:%02d:%02d',
$output .= sprintf('%02d', $this->hour);
$hour = $this->hour + 1 > 12 ?
$output .= $this->minute;
$output .= sprintf('%02d', $this->minute);
$output .= $this->hour >= 12 ? 'pm' : 'am';
$output .= $this->hour >= 12 ? 'PM' : 'AM';
$hour = $this->hour + 1 > 12 ?
$output .= sprintf('%02d:%02d:%02d %s',
$this->hour >= 12 ? 'pm' : 'am');
$output .= $this->second;
$output .= sprintf('%02d', $this->second);
$output .= sprintf('%02d:%02d:%02d',
$output .= $char . $nextchar;
* Convert time span to seconds
* @return int time span as an integer number of seconds
return $this->day * 86400 + $this->hour * 3600 +
$this->minute * 60 + $this->second;
* Convert time span to minutes
* @return float time span as a decimal number of minutes
return $this->day * 1440 + $this->hour * 60 + $this->minute +
* Convert time span to hours
* @return float time span as a decimal number of hours
return $this->day * 24 + $this->hour + $this->minute / 60 +
* Convert time span to days
* @return float time span as a decimal number of days
return $this->day + $this->hour / 24 + $this->minute / 1440 +
* @param object $time time span to add
* If the time span to subtract is larger than the original, the result
* is zero (there's no sense in negative time spans).
* @param object $time time span to subtract
$sub = $this->toSeconds() - $time->toSeconds ();
* Tells if time span is equal to $time
* @param object $time time span to compare to
* @return bool true if the time spans are equal
return $this->toSeconds() == $time->toSeconds ();
* Tells if this time span is greater or equal than $time
* @param object $time time span to compare to
* @return bool true if this time span is greater or equal than $time
return $this->toSeconds() >= $time->toSeconds ();
* Tells if this time span is lower or equal than $time
* @param object $time time span to compare to
* @return bool true if this time span is lower or equal than $time
return $this->toSeconds() <= $time->toSeconds ();
* Tells if this time span is greater than $time
* @param object $time time span to compare to
* @return bool true if this time span is greater than $time
return $this->toSeconds() > $time->toSeconds ();
* Tells if this time span is lower than $time
* @param object $time time span to compare to
* @return bool true if this time span is lower than $time
return $this->toSeconds() < $time->toSeconds ();
* Compares two time spans
* Suitable for use in sorting functions.
* @param object $time1 the first time span
* @param object $time2 the second time span
* @return int 0 if the time spans are equal, -1 if time1 is lower
* than time2, 1 if time1 is greater than time2
if ($time1->equal ($time2)) {
} elseif ($time1->lower ($time2)) {
* Tells if the time span is empty (zero length)
* @return bool true if empty
return !$this->day && !$this->hour && !$this->minute && !$this->second;
// {{{ setDefaultInputFormat()
* Set the default input format
* @param mixed $format new default input format
* @return mixed previous default input format
$old = $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
$GLOBALS['_DATE_SPAN_INPUT_FORMAT'] = $format;
// {{{ getDefaultInputFormat()
* Get the default input format
* @return mixed default input format
return $GLOBALS['_DATE_SPAN_INPUT_FORMAT'];
// {{{ setDefaultFormat()
* @param mixed $format new default format
* @return mixed previous default format
$old = $GLOBALS['_DATE_SPAN_FORMAT'];
$GLOBALS['_DATE_SPAN_FORMAT'] = $format;
// {{{ getDefaultFormat()
* @return mixed default format
return $GLOBALS['_DATE_SPAN_FORMAT'];
* c-hanging-comment-ender-p: nil
Documentation generated on Sun, 23 Mar 2008 20:00:33 -0400 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.
|