Aidan's PHP Repository

A repository for PHP functions and classes ...

Duration.php

A class for making time periods readable.

This class allows for the conversion of an integer number of seconds into a readable string. For example, '121' into '2 minutes, 1 second'.

If an array is passed to the class, the associative keys are used for the names of the time segments. For example, array('seconds' => 12, 'minutes' => 1) into '1 minute, 12 seconds'.

This class is plural aware. Time segments with values other than 1 will have an 's' appended. For example, '1 second' not '1 seconds'.

  • Author: Aidan Lister <aidan@php.net>
  • Version: 1.2.1
  • Link: http://aidanlister.com/repos/v/Duration.php
  • Views: 35829
  • Downloads: 2907

Source

Download this script <?php
/**
 * A class for making time periods readable.
 *
 * This class allows for the conversion of an integer
 * number of seconds into a readable string.
 * For example, '121' into '2 minutes, 1 second'.
 * 
 * If an array is passed to the class, the associative
 * keys are used for the names of the time segments.
 * For example, array('seconds' => 12, 'minutes' => 1)
 * into '1 minute, 12 seconds'.
 *
 * This class is plural aware. Time segments with values
 * other than 1 will have an 's' appended.
 * For example, '1 second' not '1 seconds'.
 *
 * @author      Aidan Lister <aidan@php.net>
 * @version     1.2.1
 * @link        http://aidanlister.com/repos/v/Duration.php
 */
class Duration
{
    /**
     * All in one method
     *
     * @param   int|array  $duration  Array of time segments or a number of seconds
     * @return  string
     */
    function toString ($duration, $periods = null)
    {
        if (!is_array($duration)) {
            $duration = Duration::int2array($duration, $periods);
        }
 
        return Duration::array2string($duration);
    }
 
 
    /**
     * Return an array of date segments.
     *
     * @param        int $seconds Number of seconds to be parsed
     * @return       mixed An array containing named segments
     */
    function int2array ($seconds, $periods = null)
    {        
        // Define time periods
        if (!is_array($periods)) {
            $periods = array (
                    'years'     => 31556926,
                    'months'    => 2629743,
                    'weeks'     => 604800,
                    'days'      => 86400,
                    'hours'     => 3600,
                    'minutes'   => 60,
                    'seconds'   => 1
                    );
        }
 
        // Loop
        $seconds = (float) $seconds;
        foreach ($periods as $period => $value) {
            $count = floor($seconds / $value);
 
            if ($count == 0) {
                continue;
            }
 
            $values[$period] = $count;
            $seconds = $seconds % $value;
        }
 
        // Return
        if (empty($values)) {
            $values = null;
        }
 
        return $values;
    }
 
 
    /**
     * Return a string of time periods.
     *
     * @package      Duration
     * @param        mixed $duration An array of named segments
     * @return       string
     */
    function array2string ($duration)
    {
        if (!is_array($duration)) {
            return false;
        }
 
        foreach ($duration as $key => $value) {
            $segment_name = substr($key, 0, -1);
            $segment = $value . ' ' . $segment_name; 
 
            // Plural
            if ($value != 1) {
                $segment .= 's';
            }
 
            $array[] = $segment;
        }
 
        $str = implode(', ', $array);
        return $str;
    }
 
}
 
?>

Example

<pre>
<?php
require_once 'Duration.php';
 
// 2 hours, 20 minutes, 5 seconds
$time = 60*60*2 + 20*60 + 5;
 
// Convert to a string
echo Duration::toString($time);
echo "\n";
 
// Convert to an array
print_r(Duration::int2array($time));
 
// Convert an array to a string
$time = array (
            'years' => 10,
            'days' => 6,
            'hours' => 1
        );
echo Duration::array2string($time);
echo "\n";
 
// Days until new years eve
$date = mktime(0, 0, 0, 1, 1, date('Y') + 1) - time();
$periods = array('days' => 86400);
echo Duration::toString($date, $periods);
?>
</pre>

Output

2 hours, 20 minutes, 5 seconds
Array
(
    [hours] => 2
    [minutes] => 20
    [seconds] => 5
)
10 years, 6 days, 1 hour
159 days

Comments

June 26th, 2006
Thanks! We're using this in our advertising platform SDK.
June 7th, 2006
As with everyone I added my own alterations, (I set a "standard" period that is only months, weeks, and days, as well as setting it to only add to the array (in array2string) if $value > 0. (I also added the static keyword for PHP5 OOP compatibility.) Thanks so much for this. I would've spent a couple hours re-doing this script had I not seen yours. Keep up the good work!
May 16th, 2006
how do i get the period difference to show in hours, minutes and seconds only? so i count 1 day as 24 hours, 2 days as 48 hours so my time for 1 day and 2 hours 24 minutes 6 seconds would be: 26 hours 24 minutes and 6 seconds Editor's Note: 3600, 'minutes' => 60, 'seconds' => 1); $string = Duration::toString($seconds, $periods); ?>
April 26th, 2006
Very nice class function for date manipulation. Keep up the good work and hope to see more!!!!!!
March 26th, 2006
Dear Sir, Excellent class to deal with dates. Something that is used most and is always tiring to code as lot of thinking is involved. Your code plus add ons are excellent. PHP rocks ! Thanks ! Chantu of ChantuDotCom
February 22nd, 2006
(from germany) WOW!! this reallyreallyreally should be a php-function! thank you for this wonderfull piece of code!
February 18th, 2006
Very useful stuff. I happen to get directed here from the PHP manual a lot. Keep up the good work!
February 13th, 2006
Holy crap, this is useful! I used this in the "manage my files" section of hostfile.org. Eventually I'll get around to creating a "credits" page and I'll definately credit you at this site. Great work! This should really be a function in PHP, for sure... :P
January 13th, 2006
Can you define months as a specific number of seconds -- since months are different lengths? What about?
January 1st, 2006
Great hack. Thx for sharing. Solved my problem. ( From Brazil )
December 29th, 2005
Cool. Thx for da script yo!
December 25th, 2005
Very good. Thanks! :)
October 15th, 2005
I added these functions to the class to count the period between to datetime's Usage:
October 12th, 2005
Thanks for sharing
May 13th, 2005
Wow, it's awsome !
March 25th, 2005
Nice work! Big thanks!
January 17th, 2005
Thanks much! This is exactly what I was looking for.
January 15th, 2005
Nice script!
December 18th, 2004
big tx !
December 5th, 2004
=) Nice work
November 18th, 2004
oh!!! its greats! you are a genius!