human age

Format dates into human-friendly ages.

example:

$test is 1111111111

It is currently 1135168699

{$test|human_age}

9 months, 3 days, 10 hours, 39 minutes, 51 seconds

{$test|human_age:false:false}

0 years, 9 months, 0 weeks, 3 days, 10 hours, 39 minutes, 51 seconds

{$test|human_age:false:false:2}

0 years, 9 months

{$test|human_age:false:true:2}

9 months, 3 days

<?php

/**
 * Smarty plugin
 * -----------------------------------------
 * File:    modifier.human_age.php
 * Type:    modifier
 * Name:    human_age
 * Params:  from_time    unix timestamp (required)
 *          to_time      unix timestamp (default=false (means now))
 *          strip_zeroes remove units with zero values ("0 days") (default=true)
 *          limit        limit the number of units returned (default=no limit)
 * Author:  Michael Barton (http://www.weirdlooking.com/email)
 * Purpose: Returns a human-readable difference between two times
 *          e.g. "1 day, 8 hours, 48 minutes, 57 seconds"
 * Remarks: Correct for leap years and different-sized months.
 *          Well, my idea of correct.  Turns out it's slightly subjective.
 *
 * @link http://www.weirdlooking.com/blog/45
 * -----------------------------------------
 */
  require_once $smarty->_get_plugin_filepath('shared','make_timestamp');

  function smarty_modifier_human_age($from_time, $to_time = false, $strip_zeroes = true, $limit = false)
  {
    if ($to_time === false)
      $to_time = time();
    $order = array('year', 'mon', 'mday', 'hours', 'minutes', 'seconds');
    $names = array('year', 'month', 'week', 'day', 'hour', 'minute', 'second');
    $sizes = array(12, 2=>24, 60, 60);
    $month_lengths = array(31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30);
    $from = getdate($from_time);
    $to = getdate($to_time);
    $delta = array();
    foreach ($order as $unit)
      $delta[] = $to[$unit] - $from[$unit];
    for ($i = 5; $i >= 0; $i--)
      if ($delta[$i] < 0)
      {
        $delta[$i-1]--;
        if ($i == 2 && ($to['mon'] == 3 && !($to['year'] % 4)))
          $delta[$i] += 29; // fix this before the year 2100!!!
        else if ($i == 2)
          $delta[$i] +=  $month_lengths[$to['mon']-1];
        else
          $delta[$i] += $sizes[$i-1];
      }
    $delta[2] -= ($week = floor($delta[2]/7)) * 7;
    $delta = array($delta[0], $delta[1], $week, $delta[2], $delta[3], $delta[4], $delta[5]);
    $ret = array();
    foreach ($delta as $i => $val)
      if (($delta[$i] || !$strip_zeroes) && ($limit === false || sizeof($ret) < $limit))
        $ret[] = $delta[$i].' '.$names[$i].($delta[$i] == 1 ? '' : 's');
    return join(', ', $ret);
  }
?>