Convert Past Date to Time Ago in PHP

What?
Just a quick note to refine a function that will take a date in the past and return the number of years, months, weeks, days, hours, minutes and seconds.

Why?
Here are some examples of what we want to achieve:
1 year 2 months 3 weeks 4 days 5 hours 6 minutes 7 seconds  // full string
1 year 3 weeks 5 hours 7 seconds                            // where shown values are not zero
Actually we just want the first two words of those strings:
3 days ago          // where event is 3 days ago or just over but less than 4 days ago
1 week ago          // where event is just over 1 week ago but less than 2 weeks ago

How?
I know there are so many examples out there that do this perhaps better but this one I understand and can customize to fit my needs.

This PHP function accepts as parameter a SQL date (or date format that strtotime() can convert) and outputs the largest unit (for example "1 year" not "1 year 2 months 3 days, etc...").
function getTimeAgo($p_Date) {

    // get seconds ago
    $v_Seconds = strtotime('now') - strtotime($p_Date);

    // set unit labels
    $a_UnitLabels = array('year','month','week','day','hour','minute','second');

    // set unit values
    $a_UnitValues = array(
        floor($v_Seconds / 31536000),
        floor(($v_Seconds % 31536000) / 2592000),
        floor(($v_Seconds % 2592000) / 604800),
        floor(($v_Seconds % 604800) / 86400),
        floor(($v_Seconds % 86400) / 3600),
        floor(($v_Seconds % 3600) / 60),
        floor($v_Seconds % 60),
    ); 

    // initiate array (for array_slice)
    $a_UnitPairs = array();

    // loop concatenating unit value to its label
    for($i=0;$i<count($a_UnitLabels);$i++){

        // pair up if greater than zero
        $v_Str  = $a_UnitValues[$i]>0 ? $a_UnitValues[$i].' '.$a_UnitLabels[$i] : '';

        // grammar for plural/singular (should always be a positive number)
        $v_Str .= $a_UnitValues[$i]>1 ? 's' : '';

        // only add to array if not empty/zero
        if($v_Str!='') $a_UnitPairs[] = $v_Str;
    }

    // take first item of array (round up to largest unit)
    $v_ReturnStr = $a_UnitPairs[0].' ago';

    // return
    return $v_ReturnStr;

}

Usage
$v_Str = getTimeAgo('2019-05-16 19:30:00');
// If (at time of print) this date is 17 minutes and 5 seconds ago
// then $v_Str = "17 minutes ago"

Or how about
$v_Str = getTimeAgo('-1 week 2 days 4 hours 2 seconds');
// yields "1 week ago"

$v_Str = getTimeAgo('last Monday');
// yields "3 days ago" (it's Thursday)

$v_Str = getTimeAgo('first day of this month');
// yields "15 days ago" (it's the 16th)

The same PHP function as above but somewhat minimized
function getTimeAgo($p){
    $s = strtotime('now') - strtotime($p);
    $a1 = array('year','month','week','day','hour','minute','second');
    $a2 = array(
        floor($s/31536000),
        floor(($s%31536000)/2592000),
        floor(($s%2592000)/604800),
        floor(($s%604800)/86400),
        floor(($s%86400)/3600),
        floor(($s%3600)/60),
        floor($s%60),
    ); 
    for($i=0;$i<count($a1);$i++){
        $str  = $a2[$i]>0 ? $a2[$i].' '.$a1[$i] : '';
        $str .= $a2[$i]>1 ? 's' : '';
        if($str!='') break;
    }
    return $str.' ago';
}

If you want the first 4 words but minified (eg. "1 week and 2 days ago"):
function getTimeAgo($p) {
    $s = strtotime('now') - strtotime($p);
    $a1 = array('year','month','week','day','hour','minute','second');
    $a2 = array(
        floor($s / 31536000),
        floor(($s % 31536000) / 2592000),
        floor(($s % 2592000) / 604800),
        floor(($s % 604800) / 86400),
        floor(($s % 86400) / 3600),
        floor(($s % 3600) / 60),
        floor($s % 60),
    ); 
    for($i=0;$i<count($a1);$i++){
        $v  = $a2[$i]>0 ? $a2[$i].' '.$a1[$i] : '';
        $v .= $a2[$i]>1 ? 's' : '';
        if($v!='') $a3[] = $v;
    }
    return implode(' and ', array_slice($a3,0,2)).' ago';
}

When could I possibly want to do this? Well I've previously used this for password change reminders but on this occasion for a listing of reviews laid out as per the following screenshot:
Screenshot of narrow column reviews

Related Articles

Joes Revolver Map

Joes Word Cloud

Accreditation

Badge - Certified Zoho Creator Associate
Badge - Certified Zoho Creator Associate

Donate & Support

If you like my content, and would like to support this sharing site, feel free to donate using a method below:

Paypal:
Donate to Joel Lipman via PayPal

Bitcoin:
Donate to Joel Lipman with Bitcoin - Valid till 8 May 2022 3QnhmaBX7LQSRsC9hh6Je9rGQKEGNQNfPb
© 2021 Joel Lipman .com. All Rights Reserved.