Zend Framework Source Code Snippets

Time Measurement With Zend_Measure_Time

Bookmark and Share
1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
4041
42
43
44
4546
47
48
49
5051
52
53
54
5556
57
58
59
6061
62
63
64
6566
67
68
<?php
/**
 * Time measurement.
 *
 * @author Sasa Stamenkovic <umpirsky@gmail.com> * @package Measure
 */
 
/**
 * Time measurement class. *
 * @author Sasa Stamenkovic <umpirsky@gmail.com>
 * @package Measure
 */
class Lib_Measure_Time extends Zend_Measure_Time {        /**
     * Call parent and sort units.
     *
     * @param  $value  mixed  - Value as string, integer, real or float
     * @param  $type   type   - OPTIONAL a Zend_Measure_Area Type     * @param  $locale locale - OPTIONAL a Zend_Locale Type
     * @throws Zend_Measure_Exception
     */
    public function __construct($value, $type = null, $locale = null) {
        parent::__construct($value, $type, $locale);            array_multisort(&$this->_units);
    }
 
        /**
         * Get time interval from now.         *
         * @author Sasa Stamenkovic <umpirsky@gmail.com>
         *
         * @return Zend_Measure_Time
         */        public function getInterval() {
                // Get current time
                $now = new Zend_Measure_Time(time());
                $now->sub($this);
                $this->setValue($now->getValue()); 
                // Find appropriate unit to convert to
                $convertTo = Zend_Measure_Time::STANDARD;
                foreach ($this->_units as $unitId => $unit) {
                        if ($unit[0]/$this->_value > 1) {                                break;
                        }
                        $convertTo = $unitId;
                }
                 // Convert
                return $this->convertTo($convertTo, 0);
        }
        
        /**     * Returns a string representation.
     *
     * @author Sasa Stamenkovic <umpirsky@gmail.com>
     * 
     * @param  integer  $round  OPTIONAL rounds the value to an given exception     * @return string
     */
    public function toString($round = -1) {
        $s = parent::toString($round);
        $s .= ($this->getValue($round) > 1) ? 's' : '';        return $s;
    }
}
1
2
3
4
56
7
8
// Some examples
$measureTime = new Lib_Measure_Time(time() - 6666666);
                echo $measureTime->getInterval();
// Outputs 3 months 
 $measureTime = new Lib_Measure_Time(time() - 66666666);
                echo $measureTime->getInterval();
// Outputs 2 years

Comments

bachya bachya
2 years ago

Great idea, but I don't understand where all the 6s are coming from... Perhaps you could explain a little more?

umpirsky umpirsky
2 years ago

@bachya Thanks! time() - 666 and all this dummy arguments in examples can be read from database, or any storage your app use. So, you give it a timestamp, and Lib_Measure_Time will compare it with current timestamp and tell you: "The moment in time you provided was x hours or years or whatever ago" :)

raspi raspi
2 years ago

Why array_multisort() is eval'ed?

umpirsky umpirsky
2 years ago

@raspi Good call! Long story, but this should be fixed, there were some older versions...and I forgot to check the constructor.

Thanks, fixing...

Wilfried Loche Wilfried Loche
2 years ago

Hi Saša. I post me class I wrote based on yours:

<?php
/**
* Time interval management
*
* @package Core
* @package Measure
*/

/**
* Time interval management
*
* Original 'Lib_Measure_Time' class here: {@link http://www.zfsnippets.com/snippets/view/id/39}
* coded by {@link mailto:umpirsky@gmail.com Sasa Stamenkovic}.
*
* Exemple:
* <code>
* $n = 3600*24*4 + 3600*5 + 2585;
*
* $measureTime = new Cto_Core_Time_Interval(
* $n,
* Zend_Measure_Time::SECOND,
* Zend_Registry::get('Zend_Locale')
* );
* echo "$n s => " . $measureTime; // 366185 s => 4 day 5 h 43 min 5 s
*
* $measureTime = new Cto_Core_Time_Interval(
* $n,
* Zend_Measure_Time::SECOND,
* Zend_Registry::get('Zend_Locale')
* );
* $measureTime->setVisibleUnits(array(Zend_Measure_Time::MINUTE, Zend_Measure_Time::SECOND));
* echo "$n s => " . $measureTime; // 366185 s => 6103 min 5 s
*
* $measureTime = new Cto_Core_Time_Interval(
* $n,
* Zend_Measure_Time::SECOND,
* Zend_Registry::get('Zend_Locale')
* );
* $measureTime->setVisibleUnits(array(Zend_Measure_Time::DAY));
* echo "$n s => " . $measureTime; // 366185 s => 4 day
* </code>
*
* @since ZF 1.9.1
*
* @package Core
* @package Measure
*/
class Cto_Core_Time_Interval extends Zend_Measure_Time
{

/** @var array Visible units */
private $_visibleUnits = array(
parent::YEAR => array('31536000', 'year'),
parent::MONTH => array('2628600', 'month'),
parent::DAY => array('86400', 'day'),
parent::HOUR => array('3600', 'h'),
parent::MINUTE => array('60', 'min'),
parent::SECOND => array('1', 's')
);

/**
* Call parent and sort units.
*
* @param mixed $value Value as string, integer, real or float
* @param string $type A Zend_Measure_Area Type
* @param string|Zend_Locale $locale A Zend_Locale Type
*
* @throws Zend_Measure_Exception
*/
public function __construct($value, $type = null, $locale = null)
{
parent::__construct($value, $type, $locale);
$this->setType(parent::SECOND);
}

/**
* Set new visible units
*
* @param array $units
*/
public function setVisibleUnits(array $units)
{
if (!count($units)) {
throw new Cto_Core_Exception("At least one unit must be visible");
}

$visibleUnits = array();
foreach ($units as $unit) {
if (!isset($this->_units[$unit])
|| !is_array($this->_units[$unit])
|| !is_string($this->_units[$unit][0])) {

trigger_error(__METHOD__ . "(): $unit is not a valid unit", E_USER_WARNING);
continue;
}

$visibleUnits[$unit] = $this->_units[$unit];
}

if (!count($visibleUnits)) {
throw new Cto_Core_Exception('No valid units left');
}

array_multisort($visibleUnits, SORT_DESC);
$this->_visibleUnits = $visibleUnits;
}

/**
* Returns a string representation of this interval
*
* @return string
*
* @todo Will : Apply translation on units (f.e. 'day') first and do not forget plural form (f.e. 'days')
*/
public function toString()
{
if (!$this->_value) {
return '';
}

$s = array();

foreach ($this->_visibleUnits as $unit) {
if (!is_array($unit) || !is_string($unit[0])) {
continue;
}

if ($this->_value / $unit[0] > 1) {
$t = floor($this->_value / $unit[0]);
$s[] = $t . ' ' . $unit[1];
$this->_value -= $unit[0] * $t;
}
}

return implode(' ', $s);
}

}

You must login before commenting on a snippet. If you do not have an account, please register.

Snippet description

Simple class to help measure time intervals. Useful for blogs or email clients: e.g. "Posted 2h ago".

Snippet details

Created:
umpirsky umpirsky
2 years ago
Edited:
umpirsky umpirsky
2 years ago
Revision Id:
56
Edit Message:
Added plural support
Tags:
time Zend_Measure_Time interval measure
Comments:
5
Views:
2423
Points:
0 (0 votes)

History

r56

Added plural support

umpirsky umpirsky
2 years ago
diff
r53

Initial Release

umpirsky umpirsky
2 years ago
diff
r48

Initial Release

umpirsky umpirsky
2 years ago