Search code examples
timephprelative-date

PHP Function to Calculate Relative Time (Human Readable / Facebook Style)


function RelativeTime($timestamp) {
    $difference = time() - $timestamp;
    $periods    = array(
        "sec", "min", "hour", "day", "week", "month", "years", "decade"
    );
    $lengths    = array("60", "60", "24", "7", "4.35", "12", "10");

    if ($difference > 0) { // this was in the past
        $ending = "ago";
    } else { // this was in the future
        $difference = -$difference;
        $ending     = "to go";
    }
    for ($j = 0; $difference >= $lengths[$j]; $j++)
        $difference /= $lengths[$j];
    $difference = round($difference);
    if ($difference != 1) $periods[$j] .= "s";
    $text = "$difference $periods[$j] $ending";
    return $text;
}

I found the above PHP function on the interwebs. It seems to be working pretty well, except it has issues with dates far in the future.

For example, I get looping PHP error

division by zero

for $difference /= $lengths[$j]; when the date is in 2033.

Any ideas how to fix that? The array already accounts for decades, so I am hoping 2033 would result in something like "2 decades to go".


Solution

  • The problem is that the second array $lengths contains 7 elements so when executing the last iteration of the loop (after deviding by 10 - for the decades) $j = 7, $lengths[7] is undefined, so converted to 0 and therefore the test $difference >= $lengths[$j] returns true. Then the code enters an infinite loop. To overcome this problem, just add one more element to the $lengths array, say "100", so the for loop to terminate after processing the decades. Note that dates can be represented in UNIX timestamp if they are before January 19, 2038. Therefore you cannot calculate dates in more than 4 decates so 100 is sufficiant to break from the loop.