0

I use this php function to convert a numeric timestamp to something like "7 days ago", but a certain timestamp returns division by zero error, I don't know how to fix the function.

function timestamp_to_ago($timestamp){
    if(isset($timestamp) and $timestamp !=''){  
        $difference = time() - $timestamp;
        $periods = array("second", "minute", "hour", "day", "week", "month", "year", "decade");
        $lengths = array("60","60","24","7","4.35","12","10");
        for($j = 0; $difference >= $lengths[$j]; $j++){
            $difference /= $lengths[$j]; // <<< line with problem
        }
        $difference = round($difference);
        if($difference != 1) $periods[$j].= "s";
        $text = "$difference $periods[$j] ago";
        return $text;
    }
}

// returns division by zero error
echo timestamp_to_ago(1135288800);

// doesn't return division by zero
echo timestamp_to_ago(1235288800);

The division by zero is triggered at this line $difference /= $lengths[$j]; but I don't know how to fix the function to avoid this error.

adrianTNT
  • 3,671
  • 5
  • 29
  • 35

3 Answers3

3

What happens, if it is more than a decade old?

    for($j = 0; isset($lengths[$j]) && $difference >= $lengths[$j]; $j++){
        $difference /= $lengths[$j]; // <<< line with problem
    }
Gennadiy Litvinyuk
  • 1,536
  • 12
  • 21
1

The problem is that your loop doesn't stop when it reaches the end of $lengths. When $i reaches the length of the array, $lengths[$i] is undefined, and that gets converted to 0 when dividing.

You can use foreach instead of for.

foreach ($lengths as $j => $length) {
    if ($difference < $length) {
        break;
    }
    $difference /= $length;
}
$period = $periods[$j];
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

It seems as though these arrays are static and establish a baseline for your result. If so you are missing a value for "second". You either need to add a value in lengths or remove "seconds" from periods to fix this divide by zero error. I believe (after reading your question that below is what you are trying to achieve though because it seems the logic is flawed.

function timestamp_to_ago($timestamp){
    if(isset($timestamp) and $timestamp !=''){  
        $difference = time() - $timestamp;
        $periods = array("second", "minute", "hour", "day", "week", "month", "year", "decade");
        $lengths = array("60","60","24","7","4.35","12","10");
        for($j = 1; $difference >= $lengths[$j-1]; $j++){
            $difference /= $lengths[$j];
        }
        $difference = round($difference);
        if($difference != 1) $periods[$j].= "s";
        $text = "$difference $periods[$j-1] ago";
        return $text;
    }
}

If you look, I am leaving the arrays alone so you can still have seconds be put into your return value but it seems this should fix the logic error.

Jab
  • 26,853
  • 21
  • 75
  • 114