Converting timestamp to time ago in PHP e.g 1 day ago, 2 days ago...

PhpTimestamp

Php Problem Overview


I am trying to convert a timestamp of the format 2009-09-12 20:57:19 and turn it into something like 3 minutes ago with PHP.

I found a useful script to do this, but I think it's looking for a different format to be used as the time variable. The script I'm wanting to modify to work with this format is:

function _ago($tm,$rcs = 0) {
    $cur_tm = time(); 
    $dif = $cur_tm-$tm;
    $pds = array('second','minute','hour','day','week','month','year','decade');
    $lngh = array(1,60,3600,86400,604800,2630880,31570560,315705600);

    for($v = sizeof($lngh)-1; ($v >= 0)&&(($no = $dif/$lngh[$v])<=1); $v--); if($v < 0) $v = 0; $_tm = $cur_tm-($dif%$lngh[$v]);
        $no = floor($no);
        if($no <> 1)
            $pds[$v] .='s';
        $x = sprintf("%d %s ",$no,$pds[$v]);
        if(($rcs == 1)&&($v >= 1)&&(($cur_tm-$_tm) > 0))
            $x .= time_ago($_tm);
        return $x;
    }

I think on those first few lines the script is trying to do something that looks like this (different date format math):

$dif = 1252809479 - 2009-09-12 20:57:19;

How would I go about converting my timestamp into that (unix?) format?

Php Solutions


Solution 1 - Php

###Use example :

echo time_elapsed_string('2013-05-01 00:22:35');
echo time_elapsed_string('@1367367755'); # timestamp input
echo time_elapsed_string('2013-05-01 00:22:35', true);

Input can be any supported date and time format.

###Output :

4 months ago
4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago

###Function :

function time_elapsed_string($datetime, $full = false) {
	$now = new DateTime;
	$ago = new DateTime($datetime);
	$diff = $now->diff($ago);
	
	$diff->w = floor($diff->d / 7);
	$diff->d -= $diff->w * 7;
	
	$string = array(
		'y' => 'year',
		'm' => 'month',
		'w' => 'week',
		'd' => 'day',
		'h' => 'hour',
		'i' => 'minute',
		's' => 'second',
	);
	foreach ($string as $k => &$v) {
		if ($diff->$k) {
			$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
		} else {
			unset($string[$k]);
		}
	}

	if (!$full) $string = array_slice($string, 0, 1);
	return $string ? implode(', ', $string) . ' ago' : 'just now';
}

Solution 2 - Php

function time_elapsed_string($ptime)
{
    $etime = time() - $ptime;

    if ($etime < 1)
    {
        return '0 seconds';
    }

    $a = array( 365 * 24 * 60 * 60  =>  'year',
                 30 * 24 * 60 * 60  =>  'month',
                      24 * 60 * 60  =>  'day',
                           60 * 60  =>  'hour',
                                60  =>  'minute',
                                 1  =>  'second'
                );
    $a_plural = array( 'year'   => 'years',
                       'month'  => 'months',
                       'day'    => 'days',
                       'hour'   => 'hours',
                       'minute' => 'minutes',
                       'second' => 'seconds'
                );

    foreach ($a as $secs => $str)
    {
        $d = $etime / $secs;
        if ($d >= 1)
        {
            $r = round($d);
            return $r . ' ' . ($r > 1 ? $a_plural[$str] : $str) . ' ago';
        }
    }
}

Solution 3 - Php

$time_elapsed = timeAgo($time_ago); //The argument $time_ago is in timestamp (Y-m-d H:i:s)format.

//Function definition

function timeAgo($time_ago)
{
    $time_ago = strtotime($time_ago);
    $cur_time   = time();
    $time_elapsed   = $cur_time - $time_ago;
    $seconds    = $time_elapsed ;
    $minutes    = round($time_elapsed / 60 );
    $hours      = round($time_elapsed / 3600);
    $days       = round($time_elapsed / 86400 );
    $weeks      = round($time_elapsed / 604800);
    $months     = round($time_elapsed / 2600640 );
    $years      = round($time_elapsed / 31207680 );
    // Seconds
    if($seconds <= 60){
        return "just now";
    }
    //Minutes
    else if($minutes <=60){
        if($minutes==1){
            return "one minute ago";
        }
        else{
            return "$minutes minutes ago";
        }
    }
    //Hours
    else if($hours <=24){
        if($hours==1){
            return "an hour ago";
        }else{
            return "$hours hrs ago";
        }
    }
    //Days
    else if($days <= 7){
        if($days==1){
            return "yesterday";
        }else{
            return "$days days ago";
        }
    }
    //Weeks
    else if($weeks <= 4.3){
        if($weeks==1){
            return "a week ago";
        }else{
            return "$weeks weeks ago";
        }
    }
    //Months
    else if($months <=12){
        if($months==1){
            return "a month ago";
        }else{
            return "$months months ago";
        }
    }
    //Years
    else{
        if($years==1){
            return "one year ago";
        }else{
            return "$years years ago";
        }
    }
}

Solution 4 - Php

I don't know why nobody mention Carbon yet.

https://github.com/briannesbitt/Carbon

This is actually an extension to php dateTime (which was already used here) and it has: diffForHumans method. So all you need to do is:

$dt = Carbon::parse('2012-9-5 23:26:11.123789');
echo $dt->diffForHumans();

more examples: http://carbon.nesbot.com/docs/#api-humandiff

Pros of this solution:

  • it works for future dates and will return something like in 2 months etc.
  • you can use localization to get other languages and the pluralization works fine
  • if you will start using Carbon for other things working with dates will be as easy as never.

Solution 5 - Php

This is actually a better solution I've found. Uses jQuery however it works perfectly. Also it refreshes automatically similar to the way SO and Facebook does so you don't have to refresh the page to see the updates.

This plugin will read your datetime attr in the <time> tag and fill it in for you.

e.g. "4 minutes ago" or "about 1 day ago

http://timeago.yarp.com/

Solution 6 - Php

I found results like the following ugly:

> 1 years, 2 months, 0 days, 0 hours, 53 minutes and 1 seconds

Because of that I realized a function that respects plurals, removes empty values and optionally it is possible to shorten the output:

function since($timestamp, $level=6) {
	global $lang;
	$date = new DateTime();
	$date->setTimestamp($timestamp);
	$date = $date->diff(new DateTime());
	// build array
	$since = array_combine(array('year', 'month', 'day', 'hour', 'minute', 'second'), explode(',', $date->format('%y,%m,%d,%h,%i,%s')));
	// remove empty date values
	$since = array_filter($since);
	// output only the first x date values
	$since = array_slice($since, 0, $level);
	// build string
	$last_key = key(array_slice($since, -1, 1, true));
	$string = '';
	foreach ($since as $key => $val) {
		// separator
		if ($string) {
			$string .= $key != $last_key ? ', ' : ' ' . $lang['and'] . ' ';
		}
		// set plural
		$key .= $val > 1 ? 's' : '';
		// add date value
		$string .= $val . ' ' . $lang[ $key ];
	}
	return $string;
}

Looks much better:

> 1 year, 2 months, 53 minutes and 1 second

Optionally use $level = 2 to shorten it as follows:

> 1 year and 2 months

Remove the $lang part if you need it only in English or edit this translation to fit your needs:

$lang = array(
	'second' => 'Sekunde',
	'seconds' => 'Sekunden',
	'minute' => 'Minute',
	'minutes' => 'Minuten',
	'hour' => 'Stunde',
	'hours' => 'Stunden',
	'day' => 'Tag',
	'days' => 'Tage',
	'month' => 'Monat',
	'months' => 'Monate',
	'year' => 'Jahr',
	'years' => 'Jahre',
	'and' => 'und',
);

Solution 7 - Php

function humanTiming ($time)
		{
		
		    $time = time() - $time; // to get the time since that moment
		    $time = ($time<1)? 1 : $time;
		    $tokens = array (
		        31536000 => 'year',
		        2592000 => 'month',
		        604800 => 'week',
		        86400 => 'day',
		        3600 => 'hour',
		        60 => 'minute',
		        1 => 'second'
		    );
		
		    foreach ($tokens as $unit => $text) {
		        if ($time < $unit) continue;
		        $numberOfUnits = floor($time / $unit);
		        return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
		    }
		
		}

echo humanTiming( strtotime($mytimestring) );

Solution 8 - Php

I modified the original function a bit to be (in my opinion more useful, or logical).

// display "X time" ago, $rcs is precision depth
function time_ago ($tm, $rcs = 0) {
  $cur_tm = time(); 
  $dif = $cur_tm - $tm;
  $pds = array('second','minute','hour','day','week','month','year','decade');
  $lngh = array(1,60,3600,86400,604800,2630880,31570560,315705600);
  
  for ($v = count($lngh) - 1; ($v >= 0) && (($no = $dif / $lngh[$v]) <= 1); $v--);
    if ($v < 0)
      $v = 0;
  $_tm = $cur_tm - ($dif % $lngh[$v]);

  $no = ($rcs ? floor($no) : round($no)); // if last denomination, round

  if ($no != 1)
    $pds[$v] .= 's';
  $x = $no . ' ' . $pds[$v];

  if (($rcs > 0) && ($v >= 1))
    $x .= ' ' . $this->time_ago($_tm, $rcs - 1);

  return $x;
}

Solution 9 - Php

i made this and it's working just fine it's working for both unix timestamp like 1470919932 or formatted time like 16-08-11 14:53:30

function timeAgo($time_ago) {
    $time_ago =  strtotime($time_ago) ? strtotime($time_ago) : $time_ago;
    $time  = time() - $time_ago;

switch($time):
// seconds
case $time <= 60;
return 'lessthan a minute ago';
// minutes
case $time >= 60 && $time < 3600;
return (round($time/60) == 1) ? 'a minute' : round($time/60).' minutes ago';
// hours
case $time >= 3600 && $time < 86400;
return (round($time/3600) == 1) ? 'a hour ago' : round($time/3600).' hours ago';
// days
case $time >= 86400 && $time < 604800;
return (round($time/86400) == 1) ? 'a day ago' : round($time/86400).' days ago';
// weeks
case $time >= 604800 && $time < 2600640;
return (round($time/604800) == 1) ? 'a week ago' : round($time/604800).' weeks ago';
// months
case $time >= 2600640 && $time < 31207680;
return (round($time/2600640) == 1) ? 'a month ago' : round($time/2600640).' months ago';
// years
case $time >= 31207680;
return (round($time/31207680) == 1) ? 'a year ago' : round($time/31207680).' years ago' ;

endswitch;
}
	
?>

Solution 10 - Php

Just to throw in another option...

Whilst I prefer the DateTime method posting here, I didn't like the fact it displayed 0 years etc.

/* 
 * Returns a string stating how long ago this happened
 */
 
private function timeElapsedString($ptime){
    $diff = time() - $ptime;
    $calc_times = array();
    $timeleft   = array();

    // Prepare array, depending on the output we want to get.
    $calc_times[] = array('Year',   'Years',   31557600);
    $calc_times[] = array('Month',  'Months',  2592000);
    $calc_times[] = array('Day',    'Days',    86400);
    $calc_times[] = array('Hour',   'Hours',   3600);
    $calc_times[] = array('Minute', 'Minutes', 60);
    $calc_times[] = array('Second', 'Seconds', 1);

    foreach ($calc_times AS $timedata){
        list($time_sing, $time_plur, $offset) = $timedata;

        if ($diff >= $offset){
            $left = floor($diff / $offset);
            $diff -= ($left * $offset);
            $timeleft[] = "{$left} " . ($left == 1 ? $time_sing : $time_plur);
        }
    }
	
    return $timeleft ? (time() > $ptime ? null : '-') . implode(' ', $timeleft) : 0;
}

Solution 11 - Php

I usually use this to find out difference between current and passed datetime stamp

OUTPUT

//If difference is greater than 7 days
7 June 2019

// if difference is greater than 24 hours and less than 7 days
1 days ago
6 days ago

1 hour ago
23 hours ago

1 minute ago
58 minutes ago

1 second ago
20 seconds ago

CODE

//return current date time
function getCurrentDateTime(){
    //date_default_timezone_set("Asia/Calcutta");
    return date("Y-m-d H:i:s");
}
function getDateString($date){
    $dateArray = date_parse_from_format('Y/m/d', $date);
    $monthName = DateTime::createFromFormat('!m', $dateArray['month'])->format('F');
    return $dateArray['day'] . " " . $monthName  . " " . $dateArray['year'];
}

function getDateTimeDifferenceString($datetime){
    $currentDateTime = new DateTime(getCurrentDateTime());
    $passedDateTime = new DateTime($datetime);
    $interval = $currentDateTime->diff($passedDateTime);
    //$elapsed = $interval->format('%y years %m months %a days %h hours %i minutes %s seconds');
    $day = $interval->format('%a');
    $hour = $interval->format('%h');
    $min = $interval->format('%i');
    $seconds = $interval->format('%s');
    
    if($day > 7)
        return getDateString($datetime);
    else if($day >= 1 && $day <= 7 ){
        if($day == 1) return $day . " day ago";
        return $day . " days ago";
    }else if($hour >= 1 && $hour <= 24){
        if($hour == 1) return $hour . " hour ago";
        return $hour . " hours ago";
    }else if($min >= 1 && $min <= 60){
        if($min == 1) return $min . " minute ago";
        return $min . " minutes ago";
    }else if($seconds >= 1 && $seconds <= 60){
        if($seconds == 1) return $seconds . " second ago";
        return $seconds . " seconds ago";
    }
}

Solution 12 - Php

it help you check it

   function calculate_time_span($seconds)
{  
 $year = floor($seconds /31556926);
$months = floor($seconds /2629743);
$week=floor($seconds /604800);
$day = floor($seconds /86400); 
$hours = floor($seconds / 3600);
 $mins = floor(($seconds - ($hours*3600)) / 60); 
$secs = floor($seconds % 60);
 if($seconds < 60) $time = $secs." seconds ago";
 else if($seconds < 3600 ) $time =($mins==1)?$mins."now":$mins." mins ago";
 else if($seconds < 86400) $time = ($hours==1)?$hours." hour ago":$hours." hours ago";
 else if($seconds < 604800) $time = ($day==1)?$day." day ago":$day." days ago";
 else if($seconds < 2629743) $time = ($week==1)?$week." week ago":$week." weeks ago";
 else if($seconds < 31556926) $time =($months==1)? $months." month ago":$months." months ago";
 else $time = ($year==1)? $year." year ago":$year." years ago";
return $time; 
}  
  $seconds = time() - strtotime($post->post_date); 
echo calculate_time_span($seconds); 

Solution 13 - Php

Try this, I found it from my old codes, which shows the correct Result

function ago($datefrom, $dateto = -1) {
    // Defaults and assume if 0 is passed in that
    // its an error rather than the epoch

    if ($datefrom == 0) {
        return "A long time ago";
    }
    if ($dateto == -1) {
        $dateto = time();
    }

    // Make the entered date into Unix timestamp from MySQL datetime field

    $datefrom = strtotime($datefrom);

    // Calculate the difference in seconds betweeen
    // the two timestamps

    $difference = $dateto - $datefrom;

    // Based on the interval, determine the
    // number of units between the two dates
    // From this point on, you would be hard
    // pushed telling the difference between
    // this function and DateDiff. If the $datediff
    // returned is 1, be sure to return the singular
    // of the unit, e.g. 'day' rather 'days'

    switch (true) {
        // If difference is less than 60 seconds,
        // seconds is a good interval of choice
        case(strtotime('-1 min', $dateto) < $datefrom):
            $datediff = $difference;
            $res = ($datediff == 1) ? $datediff . ' second' : $datediff . ' seconds';
            break;
        // If difference is between 60 seconds and
        // 60 minutes, minutes is a good interval
        case(strtotime('-1 hour', $dateto) < $datefrom):
            $datediff = floor($difference / 60);
            $res = ($datediff == 1) ? $datediff . ' minute' : $datediff . ' minutes';
            break;
        // If difference is between 1 hour and 24 hours
        // hours is a good interval
        case(strtotime('-1 day', $dateto) < $datefrom):
            $datediff = floor($difference / 60 / 60);
            $res = ($datediff == 1) ? $datediff . ' hour' : $datediff . ' hours';
            break;
        // If difference is between 1 day and 7 days
        // days is a good interval                
        case(strtotime('-1 week', $dateto) < $datefrom):
            $day_difference = 1;
            while (strtotime('-' . $day_difference . ' day', $dateto) >= $datefrom) {
                $day_difference++;
            }

            $datediff = $day_difference;
            $res = ($datediff == 1) ? 'yesterday' : $datediff . ' days';
            break;
        // If difference is between 1 week and 30 days
        // weeks is a good interval            
        case(strtotime('-1 month', $dateto) < $datefrom):
            $week_difference = 1;
            while (strtotime('-' . $week_difference . ' week', $dateto) >= $datefrom) {
                $week_difference++;
            }

            $datediff = $week_difference;
            $res = ($datediff == 1) ? 'last week' : $datediff . ' weeks';
            break;
        // If difference is between 30 days and 365 days
        // months is a good interval, again, the same thing
        // applies, if the 29th February happens to exist
        // between your 2 dates, the function will return
        // the 'incorrect' value for a day
        case(strtotime('-1 year', $dateto) < $datefrom):
            $months_difference = 1;
            while (strtotime('-' . $months_difference . ' month', $dateto) >= $datefrom) {
                $months_difference++;
            }

            $datediff = $months_difference;
            $res = ($datediff == 1) ? $datediff . ' month' : $datediff . ' months';

            break;
        // If difference is greater than or equal to 365
        // days, return year. This will be incorrect if
        // for example, you call the function on the 28th April
        // 2008 passing in 29th April 2007. It will return
        // 1 year ago when in actual fact (yawn!) not quite
        // a year has gone by
        case(strtotime('-1 year', $dateto) >= $datefrom):
            $year_difference = 1;
            while (strtotime('-' . $year_difference . ' year', $dateto) >= $datefrom) {
                $year_difference++;
            }

            $datediff = $year_difference;
            $res = ($datediff == 1) ? $datediff . ' year' : $datediff . ' years';
            break;
    }
    return $res;
}

Example: echo ago('2020-06-03 00:14:21 AM');

Output: 6 days

Solution 14 - Php

To directly answer the question... you can use...

strtotime()

https://www.php.net/manual/en/function.strtotime.php

$dif = time() - strtotime("2009-09-12 20:57:19");

E.G:

echo round(((( time() - strtotime("2021-08-01 21:57:50") )/60)/60)/24).' day(s) ago';

Result: 1 day(s) ago

Solution 15 - Php

I'm aware that there are several answers here, but this is what I came up with. This only handles MySQL DATETIME values as per the original question I was responding to. The array $a needs some work. I welcome comments on how to improve. Call as:

echo time_elapsed_string('2014-11-14 09:42:28');

function time_elapsed_string($ptime)
{
    // Past time as MySQL DATETIME value
	$ptime = strtotime($ptime);

    // Current time as MySQL DATETIME value
    $csqltime = date('Y-m-d H:i:s');

    // Current time as Unix timestamp
    $ctime = strtotime($csqltime); 

    // Elapsed time
    $etime = $ctime - $ptime;

    // If no elapsed time, return 0
    if ($etime < 1){
	    return '0 seconds';
    }

    $a = array( 365 * 24 * 60 * 60  =>  'year',
                 30 * 24 * 60 * 60  =>  'month',
                      24 * 60 * 60  =>  'day',
                           60 * 60  =>  'hour',
                                60  =>  'minute',
                                 1  =>  'second'
    );

    $a_plural = array( 'year'   => 'years',
                       'month'  => 'months',
                       'day'    => 'days',
                       'hour'   => 'hours',
                       'minute' => 'minutes',
                       'second' => 'seconds'
    );

    foreach ($a as $secs => $str){
	    // Divide elapsed time by seconds
	    $d = $etime / $secs;
	    if ($d >= 1){
		    // Round to the next lowest integer 
		    $r = floor($d);
		    // Calculate time to remove from elapsed time
		    $rtime = $r * $secs;
		    // Recalculate and store elapsed time for next loop
		    if(($etime - $rtime)  < 0){
			    $etime -= ($r - 1) * $secs;
		    }
		    else{
			    $etime -= $rtime;
		    }
		    // Create string to return
	        $estring = $estring . $r . ' ' . ($r > 1 ? $a_plural[$str] : $str) . ' ';
        }
    }
    return $estring . ' ago';
}

Solution 16 - Php

I tried this and works fine for me

$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-10');
$difference = $datetime1->diff($datetime2);
echo formatOutput($difference);

function formatOutput($diff){
	/* function to return the highrst defference fount */
	if(!is_object($diff)){
		return;
	}

	if($diff->y > 0){
		return $diff->y .(" year".($diff->y > 1?"s":"")." ago");
	}

	if($diff->m > 0){
		return $diff->m .(" month".($diff->m > 1?"s":"")." ago");
	}

	if($diff->d > 0){
		return $diff->d .(" day".($diff->d > 1?"s":"")." ago");
	}

	if($diff->h > 0){
		return $diff->h .(" hour".($diff->h > 1?"s":"")." ago");
	}

	if($diff->i > 0){
		return $diff->i .(" minute".($diff->i > 1?"s":"")." ago");
	}

	if($diff->s > 0){
		return $diff->s .(" second".($diff->s > 1?"s":"")." ago");
	}
}

Check this link for reference here

Thanks! and have fun.

Solution 17 - Php

This is what I went with. Its a modified version of Abbbas khan's post:

<?php

  function calculate_time_span($post_time)
  {  
  $seconds = time() - strtotime($post);
  $year = floor($seconds /31556926);
  $months = floor($seconds /2629743);
  $week=floor($seconds /604800);
  $day = floor($seconds /86400); 
  $hours = floor($seconds / 3600);
  $mins = floor(($seconds - ($hours*3600)) / 60); 
  $secs = floor($seconds % 60);
  if($seconds < 60) $time = $secs." seconds ago";
  else if($seconds < 3600 ) $time =($mins==1)?$mins."now":$mins." mins ago";
  else if($seconds < 86400) $time = ($hours==1)?$hours." hour ago":$hours." hours ago";
  else if($seconds < 604800) $time = ($day==1)?$day." day ago":$day." days ago";
  else if($seconds < 2629743) $time = ($week==1)?$week." week ago":$week." weeks ago";
  else if($seconds < 31556926) $time =($months==1)? $months." month ago":$months." months ago";
  else $time = ($year==1)? $year." year ago":$year." years ago";
  return $time; 
  }  



 // uses
 // $post_time="2017-12-05 02:05:12";
 // echo calculate_time_span($post_time); 

Solution 18 - Php

Many solutions here did not account for rounding. For example:

Event happened at 3pm two days ago. If you are checking at 2pm, it will show one day ago. If you are checking at 4pm it will show two days ago.

If you are working with unix time, this helps:

// how long since event has passed in seconds
$secs = time() - $time_ago;

// how many seconds in a day
$sec_per_day = 60*60*24;

// days elapsed
$days_elapsed = floor($secs / $sec_per_day);

// how many seconds passed today
$today_seconds = date('G')*3600 + date('i') * 60 + date('s');

// how many seconds passed in the final day calculation
$remain_seconds = $secs % $sec_per_day;

if($today_seconds < $remain_seconds)
{
    $days_elapsed++;
}

echo 'The event was '.$days_ago.' days ago.';

It is not perfect if you are worried about leap seconds and daylight savings time.

Solution 19 - Php

You'll have to take each individual piece of your timestamp, and convert it into Unix time. For example for the timestamp, 2009-09-12 20:57:19.

(((2008-1970)365)+(830)+12)*24+20 would give you a ROUGH estimate of the hours since January 1st, 1970.

Take that number, multiply by 60 and add 57 to get the minutes.

Take that, multiply by 60 and add 19.

That would convert it very roughly and inaccurately however.

Is there any reason you can't just take the normal Unix time to begin with?

Solution 20 - Php

There is some issue with some language display time ago for example in Arabic there 3 needed formats to display date. I use this functions in my projects hopefully they can help someone (any suggestion or improvement I'll be apperciate :) )

/**
 *
 * @param	string $date1 
 * @param	string $date2 the date that you want to compare with $date1
 * @param	int $level  
 * @param	bool $absolute  
 */

function app_date_diff( $date1, $date2, $level = 3, $absolute = false ) {
	
	$date1 = date_create($date1);	
	$date2 = date_create($date2);
	$diff = date_diff( $date1, $date2, $absolute );
	
	$d = [
		'invert' => $diff->invert
	];	
	
	$diffs = [
		'y' => $diff->y, 
		'm' => $diff->m, 
		'd' => $diff->d
	];
	
	$level_reached = 0;
	
	foreach($diffs as $k=>$v) {
		
		if($level_reached >= $level) {
			break;
		}
		
		if($v > 0) {
			$d[$k] = $v;
			$level_reached++;
		}
		
	}
	
	return  $d;
	
}

/**
 * 
 */

function date_timestring( $periods, $format = 'latin', $separator = ',' ) {
	
	$formats = [
		'latin' => [
			'y' => ['year','years'],
			'm' => ['month','months'],
			'd' => ['day','days']
		],
		'arabic' => [
			'y' => ['سنة','سنتين','سنوات'],
			'm' => ['شهر','شهرين','شهور'],
			'd' => ['يوم','يومين','أيام']
		]
	];
	
	$formats = $formats[$format];
	
	$string = [];
	
	foreach($periods as $period=>$value) {
		
		if(!isset($formats[$period])) {
			continue;
		}
		
		$string[$period] = $value.' ';
		if($format == 'arabic') {
			if($value == 2) {
				$string[$period] = $formats[$period][1];
			}elseif($value > 2 && $value <= 10) {
				$string[$period] .= $formats[$period][2];
			}else{
				$string[$period] .= $formats[$period][0];
			}
			
		}elseif($format == 'latin') {
			$string[$period] .= ($value > 1) ? $formats[$period][1] : $formats[$period][0];
		}
		
	}
	
	return implode($separator, $string);
	
	
}

function timeago( $date ) {
	
	$today = date('Y-m-d h:i:s');
	
	$diff = app_date_diff($date,$today,2);
	
	if($diff['invert'] == 1) {
		return '';
	}
	
	unset($diff[0]);
	
	$date_timestring = date_timestring($diff,'latin');
	
	return 'About '.$date_timestring;
	
}

$date1 = date('Y-m-d');
$date2 = '2018-05-14';

$diff = timeago($date2);
echo $diff;

Solution 21 - Php

If you are using PostgreSQL then it will do the job for you:

const DT_SQL = <<<SQL
WITH lapse AS (SELECT (?::timestamp(0) - now()::timestamp(0))::text t)
SELECT CASE
  WHEN (select t from lapse) ~ '^\s*-' THEN replace((select t from lapse), '-', '') ||' ago' 
  ELSE (select t from lapse) END;
SQL;

function timeSpanText($ts, $conn)
// $ts: date-time string, $conn: PostgreSQL PDO connection
{
 return $conn -> prepare(DT_SQL) -> execute([ts]) -> fetchColumn();
}

Solution 22 - Php

I wanted to have dutch version that supported singles and plurals. Just adding an 's' at the end would not suffice, we use completely different words so I rewrote the top answer of this post.

This will result in:

2 jaren 1 maand 2 weken 1 dag 1 minuten 2 seconden

or

1 jaar 2 maanden 1 week 2 dagen 1 minuut 1 seconde

	public function getTimeAgo($full = false){

    $now = new \DateTime;
    $ago = new \DateTime($this->datetime());
    $diff = $now->diff($ago);

    $diff->w = floor($diff->d / 7);
    $diff->d -= $diff->w * 7;

    $string = array(
        'y' => 'jaren',
        'm' => 'maanden',
        'w' => 'weken',
        'd' => 'dagen',
        'h' => 'uren',
        'i' => 'minuten',
        's' => 'seconden',
    );
	$singleString = array(
		'y' => 'jaar',
        'm' => 'maand',
        'w' => 'week',
        'd' => 'dag',
        'h' => 'uur',
        'i' => 'minuut',
        's' => 'seconde',
	);
	// M.O. 2022-02-11 I rewrote this function to support dutch singles and plurals. Added some docs for next programmer to break his brain :)
	// For each possible notation, if corresponding value of current key is true (>1) otherwise remove its key/value from array
	// If the value from current key is 1, use value from $singleString array. Otherwise use value from $string array
    foreach ($string as $k => &$v) {
        if ($diff->$k) {
			if($diff->$k == 1){
				$v = $diff->$k . ' ' . $singleString[$k];
			} else {
				$v = $diff->$k . ' ' . $v;
			}
        } else {
			if($diff->$k == 1){
				unset($singleString[$k]);
			} else {
				unset($string[$k]);
			}
        }
    }

	// If $full = true, print all values.
	// Values have already been filtered with foreach removing keys that contain a 0 as value
    if (!$full) $string = array_slice($string, 0, 1);
    return $string ? implode(', ', $string) . '' : 'zojuist';
}

You should probably test it first because I am not that good of a programmer :)

Solution 23 - Php

$time_ago = ' ';
$time = time() - $time; // to get the time since that moment
$tokens = array (
31536000 => 'year',2592000 => 'month',604800 => 'week',86400 => 'day',3600 => 'hour',
60  => 'minute',1 => 'second');
foreach ($tokens as $unit => $text) {
if ($time < $unit)continue;
$numberOfUnits = floor($time / $unit);
$time_ago = ' '.$time_ago. $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'').'  ';
$time = $time % $unit;}echo $time_ago;

Solution 24 - Php

Here is my solution please check and modify according your requirements

function getHowLongAgo($date, $display = array('Year', 'Month', 'Day', 'Hour', 'Minute', 'Second'), $ago = '') {
        date_default_timezone_set('Australia/Sydney');
        $timestamp = strtotime($date);
        $timestamp = (int) $timestamp;
        $current_time = time();
        $diff = $current_time - $timestamp;

        //intervals in seconds
        $intervals = array(
            'year' => 31556926, 'month' => 2629744, 'week' => 604800, 'day' => 86400, 'hour' => 3600, 'minute' => 60
        );

        //now we just find the difference
        if ($diff == 0) {
            return ' Just now ';
        }

        if ($diff < 60) {
            return $diff == 1 ? $diff . ' second ago ' : $diff . ' seconds ago ';
        }

        if ($diff >= 60 && $diff < $intervals['hour']) {
            $diff = floor($diff / $intervals['minute']);
            return $diff == 1 ? $diff . ' minute ago ' : $diff . ' minutes ago ';
        }

        if ($diff >= $intervals['hour'] && $diff < $intervals['day']) {
            $diff = floor($diff / $intervals['hour']);
            return $diff == 1 ? $diff . ' hour ago ' : $diff . ' hours ago ';
        }

        if ($diff >= $intervals['day'] && $diff < $intervals['week']) {
            $diff = floor($diff / $intervals['day']);
            return $diff == 1 ? $diff . ' day ago ' : $diff . ' days ago ';
        }

        if ($diff >= $intervals['week'] && $diff < $intervals['month']) {
            $diff = floor($diff / $intervals['week']);
            return $diff == 1 ? $diff . ' week ago ' : $diff . ' weeks ago ';
        }

        if ($diff >= $intervals['month'] && $diff < $intervals['year']) {
            $diff = floor($diff / $intervals['month']);
            return $diff == 1 ? $diff . ' month ago ' : $diff . ' months ago ';
        }

        if ($diff >= $intervals['year']) {
            $diff = floor($diff / $intervals['year']);
            return $diff == 1 ? $diff . ' year ago ' : $diff . ' years ago ';
        }
    }

Thanks

Solution 25 - Php

# This function prints the difference between two php datetime objects
# in a more human readable form
# inputs should be like strtotime($date)
function humanizeDateDiffference($now,$otherDate=null,$offset=null){
	if($otherDate != null){
		$offset = $now - $otherDate;
	}
	if($offset != null){
		$deltaS = $offset%60;
		$offset /= 60;
		$deltaM = $offset%60;
		$offset /= 60;
		$deltaH = $offset%24;
		$offset /= 24;
		$deltaD = ($offset > 1)?ceil($offset):$offset;		
	} else{
		throw new Exception("Must supply otherdate or offset (from now)");
	}
	if($deltaD > 1){
		if($deltaD > 365){
			$years = ceil($deltaD/365);
			if($years ==1){
				return "last year"; 
			} else{
				return "<br>$years years ago";
			}	
		}
		if($deltaD > 6){
			return date('d-M',strtotime("$deltaD days ago"));
		}		
		return "$deltaD days ago";
	}
	if($deltaD == 1){
		return "Yesterday";
	}
	if($deltaH == 1){
		return "last hour";
	}
	if($deltaM == 1){
		return "last minute";
	}
	if($deltaH > 0){
		return $deltaH." hours ago";
	}
	if($deltaM > 0){
		return $deltaM." minutes ago";
	}
	else{
		return "few seconds ago";
	}
}

Solution 26 - Php

This function is not made to be used for the English language. I translated the words in English. This needs more fixing before using for English.

function ago($d) {
$ts = time() - strtotime(str_replace("-","/",$d));
       
        if($ts>315360000) $val = round($ts/31536000,0).' year';
		else if($ts>94608000) $val = round($ts/31536000,0).' years';
		else if($ts>63072000) $val = ' two years';
		else if($ts>31536000) $val = ' a year';
		
        else if($ts>24192000) $val = round($ts/2419200,0).' month';
		else if($ts>7257600) $val = round($ts/2419200,0).' months';
		else if($ts>4838400) $val = ' two months';
		else if($ts>2419200) $val = ' a month';
		
		
        else if($ts>6048000) $val = round($ts/604800,0).' week';
		else if($ts>1814400) $val = round($ts/604800,0).' weeks';
		else if($ts>1209600) $val = ' two weeks';
		else if($ts>604800) $val = ' a week';
		
        else if($ts>864000) $val = round($ts/86400,0).' day';
		else if($ts>259200) $val = round($ts/86400,0).' days';
		else if($ts>172800) $val = ' two days';
		else if($ts>86400) $val = ' a day';
		
		else if($ts>36000) $val = round($ts/3600,0).' year';
		else if($ts>10800) $val = round($ts/3600,0).' years';
		else if($ts>7200) $val = ' two years';
        else if($ts>3600) $val = ' a year';
		
		else if($ts>600) $val = round($ts/60,0).' minute';
		else if($ts>180) $val = round($ts/60,0).' minutes';
		else if($ts>120) $val = ' two minutes';
        else if($ts>60) $val = ' a minute';
		
		else if($ts>10) $val = round($ts,0).' second';
		else if($ts>2) $val = round($ts,0).' seconds';
        else if($ts>1) $val = ' two seconds';
		else $val = $ts.' a second';
       
        
        return $val;
    }

Solution 27 - Php

Use of:

echo elapsed_time('2016-05-09 17:00:00'); // 18 saat 8 dakika önce yazıldı.

Function:

function elapsed_time($time){// Nekadar zaman geçmiş
	
		$diff = time() - strtotime($time); 
		
		$sec = $diff;
		$min = floor($diff/60);
		$hour = floor($diff/(60*60));
		$hour_min = floor($min - ($hour*60));
		$day = floor($diff/(60*60*24));
		$day_hour = floor($hour - ($day*24));
		$week = floor($diff/(60*60*24*7));
		$mon = floor($diff/(60*60*24*7*4));
		$year = floor($diff/(60*60*24*7*4*12));

		//difference calculate to string
		if($sec < (60*5)){
			return 'şimdi yazıldı.';
		}elseif($min < 60){
			return 'biraz önce yazıldı.';
		}elseif($hour < 24){
			return $hour.' saat '.$hour_min.' dakika önce yazıldı.';
		}elseif($day < 7){
			if($day_hour!=0){$day_hour=$day_hour.' saat ';}else{$day_hour='';}
			return $day.' gün '.$day_hour.'önce yazıldı.';
		}elseif($week < 4){
			return $week.' hafta önce yazıldı.';
		}elseif($mon < 12){
			return $mon.' ay önce yazıldı.';
		}else{
			return $year.' yıl önce yazıldı.';
		}
	}

Solution 28 - Php

Slightly modified answer from above:

  $commentTime = strtotime($whatever)
  $today       = strtotime('today');
  $yesterday   = strtotime('yesterday');
  $todaysHours = strtotime('now') - strtotime('today');

private function timeElapsedString(
    $commentTime,
    $todaysHours,
    $today,
    $yesterday
) {
    $tokens = array(
        31536000 => 'year',
        2592000 => 'month',
        604800 => 'week',
        86400 => 'day',
        3600 => 'hour',
        60 => 'minute',
        1 => 'second'
    );
    $time = time() - $commentTime;
    $time = ($time < 1) ? 1 : $time;
    if ($commentTime >= $today || $commentTime < $yesterday) {
        foreach ($tokens as $unit => $text) {
            if ($time < $unit) {
                continue;
            }
            if ($text == 'day') {
                $numberOfUnits = floor(($time - $todaysHours) / $unit) + 1;
            } else {
                $numberOfUnits = floor(($time)/ $unit);
            }
            return $numberOfUnits . ' ' . $text . (($numberOfUnits > 1) ? 's' : '') . ' ago';
        }
    } else {
        return 'Yesterday';
    }
}

Solution 29 - Php

just pass the date time to this func. it would print out in time ago format for you

date_default_timezone_set('your-time-zone');
function convert($datetime){
  $time=strtotime($datetime);
  $diff=time()-$time;
  $diff/=60;
  $var1=floor($diff);
  $var=$var1<=1 ? 'min' : 'mins';
  if($diff>=60){
    $diff/=60;
    $var1=floor($diff);
    $var=$var1<=1 ? 'hr' : 'hrs';
    if($diff>=24){$diff/=24;$var1=floor($diff);$var=$var1<=1 ? 'day' : 'days';
    if($diff>=30.4375){$diff/=30.4375;$var1=floor($diff);$var=$var1<=1 ? 'month' : 'months';
    if($diff>=12){$diff/=12;$var1=floor($diff);$var=$var1<=1 ? 'year' : 'years';}}}}
    echo $var1,' ',$var,' ago';
  }

Solution 30 - Php

The following is a very simple and extremely efficient solution.

function timeElapsed($originalTime){
        
        $timeElapsed=time()-$originalTime;
        
        /*
          You can change the values of the following 2 variables 
          based on your opinion. For 100% accuracy, you can call
          php's cal_days_in_month() and do some additional coding
          using the values you get for each month. After all the
          coding, your final answer will be approximately equal to
          mine. That is why it is okay to simply use the average
          values below.
        */
        $averageNumbDaysPerMonth=(365.242/12);
        $averageNumbWeeksPerMonth=($averageNumbDaysPerMonth/7);
        
        $time1=(((($timeElapsed/60)/60)/24)/365.242);
        $time2=floor($time1);//Years
        $time3=($time1-$time2)*(365.242);
        $time4=($time3/$averageNumbDaysPerMonth);
        $time5=floor($time4);//Months
        $time6=($time4-$time5)*$averageNumbWeeksPerMonth;
        $time7=floor($time6);//Weeks
        $time8=($time6-$time7)*7;
        $time9=floor($time8);//Days
        $time10=($time8-$time9)*24;
        $time11=floor($time10);//Hours
        $time12=($time10-$time11)*60;
        $time13=floor($time12);//Minutes
        $time14=($time12-$time13)*60;
        $time15=round($time14);//Seconds
        
        $timeElapsed=$time2 . 'yrs ' . $time5 . 'months ' . $time7 . 
                     'weeks ' . $time9 .  'days ' . $time11 . 'hrs '
                     . $time13 . 'mins and ' . $time15 . 'secs.';
        
        return $timeElapsed;
        
}
    

echo timeElapsed(1201570814);

Sample output:

6yrs 4months 3weeks 4days 12hrs 40mins and 36secs.

Solution 31 - Php

Here's my solution for a notification module I built some time ago. It returns output similar to Facebook's notifications dropdown (eg. 1 day ago, Just now, etc).

public function getTimeDifference($time) {
    //Let's set the current time
    $currentTime = date('Y-m-d H:i:s');
    $toTime = strtotime($currentTime);

    //And the time the notification was set
    $fromTime = strtotime($time);

    //Now calc the difference between the two
    $timeDiff = floor(abs($toTime - $fromTime) / 60);

    //Now we need find out whether or not the time difference needs to be in
    //minutes, hours, or days
    if ($timeDiff < 2) {
        $timeDiff = "Just now";
    } elseif ($timeDiff > 2 && $timeDiff < 60) {
        $timeDiff = floor(abs($timeDiff)) . " minutes ago";
    } elseif ($timeDiff > 60 && $timeDiff < 120) {
        $timeDiff = floor(abs($timeDiff / 60)) . " hour ago";
    } elseif ($timeDiff < 1440) {
        $timeDiff = floor(abs($timeDiff / 60)) . " hours ago";
    } elseif ($timeDiff > 1440 && $timeDiff < 2880) {
        $timeDiff = floor(abs($timeDiff / 1440)) . " day ago";
    } elseif ($timeDiff > 2880) {
        $timeDiff = floor(abs($timeDiff / 1440)) . " days ago";
    }

    return $timeDiff;
}

Solution 32 - Php

I am using following function for several years. And it is working fine:

function timeDifference($timestamp)
{
	$otherDate=$timestamp;
	$now=@date("Y-m-d H:i:s");
	
	$secondDifference=@strtotime($now)-@strtotime($otherDate);
	$extra="";
	if ($secondDifference == 2592000) { 
    // months 
    $difference = $secondDifference/2592000; 
    $difference = round($difference,0); 
    if ($difference>1) { $extra="s"; } 
    $difference = $difference." month".$extra." ago"; 
}else if($secondDifference > 2592000)
	{$difference=timestamp($timestamp);} 
elseif ($secondDifference >= 604800) { 
    // weeks 
    $difference = $secondDifference/604800; 
    $difference = round($difference,0); 
    if ($difference>1) { $extra="s"; } 
    $difference = $difference." week".$extra." ago"; 
} 
elseif ($secondDifference >= 86400) { 
    // days 
    $difference = $secondDifference/86400; 
    $difference = round($difference,0); 
    if ($difference>1) { $extra="s"; } 
    $difference = $difference." day".$extra." ago"; 
} 
elseif ($secondDifference >= 3600) { 
    // hours 
	
    $difference = $secondDifference/3600; 
    $difference = round($difference,0); 
    if ($difference>1) { $extra="s"; } 
    $difference = $difference." hour".$extra." ago"; 
} 
elseif ($secondDifference < 3600) { 
    // hours 
	// for seconds (less than minute)
	if($secondDifference<=60)
	{		
		if($secondDifference==0)
		{
			$secondDifference=1;
		}
		if ($secondDifference>1) { $extra="s"; }
   	 	$difference = $secondDifference." second".$extra." ago"; 
		
	}
	else
	{
		 		
$difference = $secondDifference/60; 
    	if ($difference>1) { $extra="s"; }else{$extra="";}
    	$difference = round($difference,0); 
   	 	$difference = $difference." minute".$extra." ago"; 
	}
} 

$FinalDifference = $difference; 
return $FinalDifference;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwilldanceforfunView Question on Stackoverflow
Solution 1 - PhpGlavićView Answer on Stackoverflow
Solution 2 - PhpAyman HusseinView Answer on Stackoverflow
Solution 3 - PhpCaptain RedView Answer on Stackoverflow
Solution 4 - PhpKrzysztof DuszczykView Answer on Stackoverflow
Solution 5 - PhpPanama JackView Answer on Stackoverflow
Solution 6 - PhpmguttView Answer on Stackoverflow
Solution 7 - PhpbrycejlView Answer on Stackoverflow
Solution 8 - PhpBobb FwedView Answer on Stackoverflow
Solution 9 - PhpAhmad ghoneimView Answer on Stackoverflow
Solution 10 - PhpTMHView Answer on Stackoverflow
Solution 11 - PhpVicky SalunkheView Answer on Stackoverflow
Solution 12 - PhpAbbbas khanView Answer on Stackoverflow
Solution 13 - PhpMonzurView Answer on Stackoverflow
Solution 14 - PhpDazzaView Answer on Stackoverflow
Solution 15 - PhprdpcoderView Answer on Stackoverflow
Solution 16 - PhpRuberandinda PatienceView Answer on Stackoverflow
Solution 17 - PhpdrtechnoView Answer on Stackoverflow
Solution 18 - PhpFrank ForteView Answer on Stackoverflow
Solution 19 - PhpLukeWarm74View Answer on Stackoverflow
Solution 20 - PhpMourad KaroudiView Answer on Stackoverflow
Solution 21 - PhpStefanov.smView Answer on Stackoverflow
Solution 22 - PhpMaartenView Answer on Stackoverflow
Solution 23 - PhpMehreen JamilView Answer on Stackoverflow
Solution 24 - PhpDineshawsView Answer on Stackoverflow
Solution 25 - PhpRameshView Answer on Stackoverflow
Solution 26 - PhpsyrkullView Answer on Stackoverflow
Solution 27 - PhpLimitless isaView Answer on Stackoverflow
Solution 28 - PhpMr SorboseView Answer on Stackoverflow
Solution 29 - PhphrishiView Answer on Stackoverflow
Solution 30 - Phpuser3008679View Answer on Stackoverflow
Solution 31 - PhpCiaranView Answer on Stackoverflow
Solution 32 - PhpAyyaz ZafarView Answer on Stackoverflow