Salagir's Blog

Old name was: "Why do witches burn?"

Ceci est la version anglaise. Aller à la version Française

Be careful, this is the translation of two French articles and it’s long.

Today we will be writing time in a way that is comfortable for a human reader.
Who want to read, « Only 0h 00mn 18s left » at the end of a count that began an hour ago?

Before, strftime() was enough. Now, time to do better.
When the time is more than one hour, I write the number of hours. But otherwise, I don’t write « 0 hour ». That’s the same for each unity.

Here are three function that display remaining time.
They all have their advantage and complexity. The third is a fusion of the first two.

Write time in several languages

You already have php functions for that. date() and strftime(), with the installed locals, will adapts.
In PHP5, there is even a more powerful international date writer.

But making locales work can be a hassle. This function will work everywhere, is standalone, BUT it’s limited in number of languages.

//! Write a time, multilanguage ($lg = 'fr|en|es|it')
function write_temps_internationnal($secondes, $lg='fr') {
    static $trads = array(
            's' => array('fr'=>'secondes',  'en'=>'seconds', 'it'=>'secunde', 'es'=>'segundos'),
            'ms'=> array('fr'=>'%Mmn, %Ss', 'en'=>'%Mmn, %Ss', 'it'=>'%Mmn, %Ss', 'es'=>'%Mm., %Ss.'),
            'h' => array('fr'=>'%kh, ', 'en'=>'%kh, ', 'it'=>'%kh', 'es'=>'%kh.'),
            'j' => array('fr'=>'%e jours, ', 'en'=>'%e days, ', 'it'=>'%e giorni', 'es'=>'%e dias'),
            );
    if ($secondes<60) {
        return $secondes.' '.$trads['s'][$lg];
    }
    if ($secondes<3600) {
        return gmstrftime($trads['ms'][$lg], $secondes);
    }
    if ($secondes<86400) {
        return gmstrftime($trads['h'][$lg].$trads['ms'][$lg], $secondes);
    }
    //  %e/%d give 1 day more because it's the *1* January 1970
    // so one day less
    $secondes -= 86400;
    return gmstrftime($trads['j'][$lg].$trads['h'][$lg].$trads['ms'][$lg], $secondes);
}

Simple to use.

Write rounded time

This version permit to display a loose information of remaining time. If there are 5 days, 3h, 8min and 9 seconds, it writes « 5 days ». We only keep the important number.
Also useful when you simply don’t want the guy to know the exact time.

/** Write rounded time
 
  \param $secondes (int) number of seconds.
 
  \param $detail ca be a boolean or one of the following strings: 'h', 'mn',
that tell you want the detail to the hour, to the minute. false being sometime to unclear
 
  \return (string)
  */
function write_temps($secondes, $detail=true) {
    if ($secondes<60) {
        if ($detail==='h') return "less than one hour";
        if ($detail==='mn') return "less than a minute";
        return write_temps_sub($secondes, 'second');
    }
    if ($secondes<3600) {
        if ($detail==='h') return "less than one hour";
        if (!$detail or $detail==='mn') return write_temps_sub($secondes/60, 'minute');
        return gmstrftime('%Mmn, %Ss', $secondes);
    }
    if ($secondes<86400) {
        if (!$detail or $detail==='h') return write_temps_sub($secondes/3600, 'hour');
        if ($detail==='mn') return gmstrftime('%kh, %Mmn', $secondes);
        return gmstrftime('%kh, %Mmn, %Ss', $secondes);
    }
    if (!$detail) return round($secondes/86400).' days';
    //  %e/%d give 1 day more because it's the *1* January 1970
    // so one day less
    $secondes -= 86400;
    if ($detail==='mn') return gmstrftime('%e jours, %kh, %Mmn', $secondes);
    if ($detail==='h') return gmstrftime('%e jours et %kh', $secondes);
    return gmstrftime('%e jours, %kh, %Mmn, %Ss', $secondes);
}
function write_temps_sub($nbre, $quoi) {
    $nbre = round($nbre);
    if ($nbre>1) return $nbre.' '.$quoi.'s';
    return $nbre.' '.$quoi;
}

But it’s only in one language.

Write rounded time, international

Here it is, the powerful function that is a fusion of both previous functions.
It’s given with a lot of languages, thanks to the translators of Multiverse. Here is a usage example. (Look for « Next page in: … »)

First, we’ll use my translation system. It’s very simple, all informations are here.

Then, use this function and fill the translation table with the following SQL.

/** Write rounded time, international
 
  \param $secondes (int) number of seconds.
 
  \param $detail can be:
        - a boolean (yes we display all details, or no)
        - one of these strings: 'h' (detail at the hour), 'mn' (detail at the minute)
        - or an int: the number of informations. 1 is the same as false
 
  \return (string)
 */
function super_write_delay($secondes, $detail=true) {
     // hum....
}

In fact, the function is quite long so get directly the file (zip), or look at it online.
Comments in it are in French. You may want to add the url of this article for future reference in the comment of the function after you’ve used it.

Here are the several SQL line to add to your table (the file is encoded in UTF8).
Do NOT copy-paste its content. Save it on your hard drive, and import in in the database, with phpMyAdmin for example.

Examples of usage:

// dragon ball multiverse
// $S is the number of second until the next page is out
// note: 48 is of course the translation number for "Next page in :"
echo __(48).' '.super_write_delay($S, 2);
// result : "Next page in: 3 days, 10h"   or  "Next page in: 9h, 23mn"
 
// Others :
echo super_write_delay(3661, 'h');
// 1 hour
echo super_write_delay(3661, 'mn');
// 1h, 01mn
echo super_write_delay(3661, 's');
// 1h, 01mn, 01s

One Response to “Time Functions: Displaying rounded and international”

  1. […] This function use write_temps(), the second function given on this link. […]

    Why do witches burn? » Blog Archive » Displaying a progress bar

Leave a Reply