0

I have a timestamp like this: 1362466800

I want to output it to something like this:

Time left: 1 Year 2 Months 5 Days 17 hours 6 Minutes Left

Also if there is less than 1 year or less than 1 month etc.. That part of the string needs to be hidden.

I know there is some built in PHP functions for this in 5.3+ but they don't seem to be able to hide values that are 0.

Thanks for any help.

John Conde
  • 217,595
  • 99
  • 455
  • 496
Talon
  • 4,937
  • 10
  • 43
  • 57
  • you can use the DateTime class in PHP, then use diff to get the difference. as far as the hiding goes, just check each one if it's 0, and if it is don't show it. – kennypu Mar 05 '13 at 01:50

4 Answers4

4
$datetime1 = new DateTime();
$datetime2 = new DateTime('@1362466800');
$interval = $datetime1->diff($datetime2);
$elapsed = $interval->format('%y years %m months %a days %h hours %i minutes %S seconds');
echo $elapsed;

See it in action

edit

If you want to elimate any periods that have zero values you can use the snippet below to remove them.

$empties = array('0 years', '0 months', '0 days', '0 hours', '0 minutes', '0 seconds');
echo str_replace($empties, '', $elapsed);

Reference

John Conde
  • 217,595
  • 99
  • 455
  • 496
  • How do you get it to hide the items that are at 0? In your example there is 0 years, 0 months, and 0 days but they are all still showing. – Talon Mar 05 '13 at 01:56
  • That's good, thought this also doesn't get the singular and plural correct (ex. It says `1 days` instead of `1 day`) and it would also be best to show only the outermost time, so if there is 2 Days 3 hours 45 Seconds Left I want the string to only say 2 Days and if there was 3 hours 25 seconds left, i'd want the string to only say 3 hours. Is that possible with this type of format? – Talon Mar 05 '13 at 02:06
  • I don't think expanding this code to do that would be difficult. The code I have provided is the hardest part. – John Conde Mar 05 '13 at 02:08
2

You can do it like this :

   echo secondsToTime(1362466800);

   function secondsToTime($seconds) {
    $dtF = new \DateTime('@0');
    $dtT = new \DateTime("@$seconds");
    return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
}
Syed Saqlain
  • 544
  • 4
  • 21
1

Based on @John Condes answer I was able to come up with a function that outputs a really easy to read time from now display:

function daysLeft($timestamp) {
    $datetime1 = new DateTime('@'.time() );
    $datetime2 = new DateTime('@' . $timestamp );
    $interval = $datetime1->diff($datetime2);

    $years = $interval->format('%y');
    $months = $interval->format('%m');
    $days = $interval->format('%a');
    $hours = $interval->format('%h');
    $minutes = $interval->format('%i');
    $seconds = $interval->format('%S');

    if($seconds):
        $elapsed = $seconds == 1 ? $seconds . ' Second ' : $seconds . ' Seconds ';
    endif;
    if($minutes):
        $elapsed = $minutes == 1 ? $minutes . ' Minute ' : $minutes . ' Minutes ';
    endif;
    if($hours):
        $elapsed = $hours == 1 ? $hours . ' Hour ' : $hours . ' Hours ';
    endif;
    if($days):
        $elapsed = $days == 1 ? $days . ' Day ' : $days . ' Days ';
    endif;
    if($months):
        $elapsed = $months == 1 ? $months . ' Month ' : $months . ' Months ';
    endif;
    if($years):
        $elapsed = $years == 1 ? $years . ' Year ' : $years . ' Years ';
    endif;

    return $elapsed;
}

In case anyone is trying to do something similar.

Nathan J.B.
  • 10,215
  • 3
  • 33
  • 41
Talon
  • 4,937
  • 10
  • 43
  • 57
0

Based on @Talon i decided to go a little further and write a small class:

/**
 * Calculates the time between two UNIX timestamps
 * Like 3 hours or 180 minutes.
 * 
 * @package Add Package Name Here
 * @version 1
 * @since Jul 12, 2013
 * @author Andrew Starlike <andrewstarlike@gmail.com>
 */
class NiceDate
{

private $translation;

/**
 * @param array $translation
 */
public function __construct($translation = null)
{
$this->setTranslation($translation);
}

/**
 * Sets the translation of the time string
 * 
 * @param array $translation (the array must have this keys 'second', 'minute', 'hour', 'day', 'month', 'year')
 */
private function setTranslation($translation = null)
{
if ($translation === null) {
    $translation = array();
    $plural = 's';
    $formats = array('second', 'minute', 'hour', 'day', 'month', 'year');
    foreach ($formats as $format) {
    $translation[$format] = ucfirst($format);
    $translation[$format . $plural] = ucfirst($format . $plural);
    }
}

$this->translation = $translation;
}

/**
 * 
 * @param int $old (UNIX timestamp)
 * @param int $newer (UNIX timestamp)
 * @return string
 */
public function timeLeft($old, $newer)
{
$datetime1 = new DateTime('@' . $newer);
$datetime2 = new DateTime('@' . $old);
$interval = $datetime1->diff($datetime2);

$years = $interval->format('%y');
$months = $interval->format('%m');
$days = $interval->format('%a');
$hours = $interval->format('%h');
$minutes = $interval->format('%i');
$seconds = $interval->format('%S');

$translation = $this->translation;

if ($seconds):
    $elapsed = $seconds . ' ';
    $elapsed .= $seconds == 1 ? $translation['second'] : $translation['seconds'];
endif;
if ($minutes):
    $elapsed = $minutes . ' ';
    $elapsed .= $minutes == 1 ? $translation['minute'] : $translation['minutes'];
endif;
if ($hours):
    $elapsed = $hours . ' ';
    $elapsed .= $hours == 1 ? $translation['hour'] : $translation['hours'];
endif;
if ($days):
    $elapsed = $days . ' ';
    $elapsed .= $days == 1 ? $translation['day'] : $translation['days'];
endif;
if ($months):
    $elapsed = $months . ' ';
    $elapsed .= $months == 1 ? $translation['month'] : $translation['months'];
endif;
if ($years):
    $elapsed = $years . ' ';
    $elapsed .= $years == 1 ? $translation['year'] : $translation['years'];
endif;

return $elapsed;
}

}
Andrew Starlike
  • 379
  • 4
  • 14