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

Viewed 307080

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?

32 Answers

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";
    }
}

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

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

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.

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;

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();
}

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 :)

Related