Code Snippets: PHP Function secs2human_time

On one project I was working on, it was driving someone crazy that the amount of time that had passed since an action occurred was being displayed in seconds (which was fine if the event had occurred 15 seconds ago, but not so much when 16,540 had).

I couldn’t find a builtin function (no wonder) that would do what I needed, which was to basically take the seconds and display the time in a human readable format. I set out to do that and came up with what I think works fairly well.

Here’s the code:

//////////////////////////////////////////////////////////
// FUNCTION: secs2human_time
// ///////////////////////////////////////////////////////
// Description:
// 
// This function takes seconds and converts them into a
// human readable format.
//
// If a string is passed it will be converted into an int
//
// ///////////////////////////////////////////////////////
// Parameters:
//     $total      - Amount of time in seconds
// ///////////////////////////////////////////////////////
// Example:
//     write_time_exact(604927);
//     returns: '1 week 2 minutes 7 seconds'
// ///////////////////////////////////////////////////////
// Returns: string - Human readable length of time from seconds
//////////////////////////////////////////////////////////
function secs2human_time($total)
{
    $secsMinute = 60;
    $secsHour   = 3600;
    $secsDay    = 86400;
    $secsWeek   = 604800;
    $secsMonth  = 2592000;
    $secsYear   = 31104000;

    $result = '';

    $seconds = 0;
    $minutes = 0;
    $hours   = 0;
    $days    = 0;
    $weeks   = 0;
    $months  = 0;
    $years   = 0;

    $total = intval($total);

    if (!$total || $total < 0)
        return FALSE;

    if ($total >= $secsYear)
    {
        $years = floor($total / $secsYear);
        $total -= $secsYear * $years;
    }
    if ($total >= $secsMonth)
    {
        $months = floor($total / $secsMonth);
        $total -= $secsMonth * $months;
    }
    if ($total >= $secsWeek)
    {
        $weeks = floor($total / $secsWeek);
        $total -= $secsWeek * $weeks;
    }
    if ($total >= $secsDay)
    {
        $days = floor($total / $secsDay);
        $total -= $secsDay * $days;
    }
    if ($total >= $secsHour)
    {
        $hours = floor($total / $secsHour);
        $total -= $secsHour * $hours;
    }
    if ($total >= $secsMinute)
    {
        $minutes = floor($total / $secsMinute);
        $total -= $secsMinute * $minutes;
    }
    $seconds = $total;

    if ($years)  { $result = $years.' years '; }
    if ($months) { $result = $result.$months.' months '; }
    if ($weeks) { $result = $result.$weeks.' weeks '; }
    if ($days) { $result = $result.$days.' days '; }
    if ($hours) { $result = $result.$hours.' hours '; }
    if ($minutes) { $result = $result.$minutes.' minutes '; }
    if ($seconds) { $result = $result.$seconds.' seconds '; }

    return $result;
}

Now I toyed with the idea of adding in decades, centuries, millenniums, ages, and eons… but I doubt my code will survive long enough to warrant that.

Belisarius Smith consults as a software engineer, cloud engineer, and security adviser. He has a BSBA in Security Management and is currently completing graduate studies in the Engineering Department at Penn State University with a Masters of Software Engineering. When he isn't traveling, mountain climbing, or reading, he spends his spare time on personal side projects and studies.

Leave a Reply