PHP funkce pro vyjádření časových intervalů slovně … „včera“, „před 5 dny“, „za rok“ …

Jste-li vývojáři, může se vám hodit funkce pro získání slovního vyjádření uplynulého času (nebo zbývajícího času). Informace o uplynulém času, případně o času, který zbývá do nějaké události, se snáze uživatelům zpracovává, je-li vyjádřena slovně jako časový interval.

Představte si, že máte uživatelům zobrazit u jednotlivých akcí i kdy k těmto akcím došlo či dojde. Můžete samozřejmě zobrazit číselně datum a více se tím nezabývat:
14. dubna 2012 ve 13:30:15

Uživatelé by však jistě ocenili, kdyby nemuseli nad datumy přemýšlet a hned dokázali získat představu, kdy daná akce proběhla či proběhne. Zvláště kritické je informovat uživatele srozumitelnějším způsobem například v přehledech o objednávkách v e-shopech.
Ideální je proto zobrazit nejen datum, ale i slovní vyjádření:
včera
před 10 minutami
před týdnem
před měsícem
před 3 měsíci
za rok
za týden
za 10 minut
apod.

<?php
/** -----------------------------------------------------------------------
*     class CasovyInterval
*     Vrací slovní vyjádření uplynulého času nebo zbývajícího času
*     např.: před 5 minutami, před hodinou, před pěti hodinami, včera, před 3 dny, před týdnem, před měsícem, za minutu, za hodinu, ...
*
*     @author   Petr Franěk <franek.petr@seznam.cz>
*     @access   public
*     @todo     kontrola platnosti parametru $datum (např. pomocí preg_match)
*
*     Příklad použití:
*     $datum = '2013-03-05 12:00:12';
*     $t = new CasovyInterval;
*     echo $interval = $t->intervalSlovne($datum);       // zobrazí uplynulý nebo zbývající čas slovně v češtině
*     echo $uplynulychDni = $t->pocetDni('2011-01-01')   // zobrazí počet dní (číselně) od daného datumu
*
*     Třída CasovyInterval nemá konstruktor. Nejde o objekt v pravém slova smyslu. Slouží pouze k zapouzdření funkcí.
*/
class CasovyInterval
{
   /**  ------------------------------------------------------------------------
   *
   *     Konvertuje DATE (YYYY-MM-DD) nebo DATETIME (YYYY-MM-DD hh:mm:ss) na slovní vyjádření uplynulého nebo zbývajícího času
   *
   *     Vrací slovní vyjádření uplynulého nebo zbývajícího času
   *     @param      string datetime
   *     @access     public
   *     @return     string
   */
   public function intervalSlovne($datum)
   {
       if( empty($datum) ) {
           return "Nebyl předán datum.";
       }

       $perioda       = array("sekundy", "minuty", "hodiny", "dny", "týdny", "měsíce", "roky");
       $delka         = array("60","60","24","7","4.35","12");

       $nyni          = time();
       $unixovy_datum = strtotime($datum);

       if( empty($unixovy_datum) ) {
           return "Chybný formát datumu.";
       }

       // minulý čas nebo budoucí čas?
       //
       if( $nyni > $unixovy_datum ) {
           $rozdil      = $nyni - $unixovy_datum;
           $slovesnyCas = "před";

       } else {
           $rozdil      = $unixovy_datum - $nyni;
           $slovesnyCas = "za";
       }

       for($j = 0; $rozdil >= $delka[$j] && $j < count($delka)-1; $j++) {
           $rozdil /= $delka[$j];
       }

       $rozdil = round($rozdil);

       if( $slovesnyCas == "před" ) {
       	 switch ($perioda[$j]) {
          case "sekundy":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "sekundou";
            	$rozdil = "jednou";
            }else{
            	$perioda[$j] = "sekundami";
            }
            break;

          case "minuty":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "minutou";
            	$rozdil = "";
            }else{
            	$perioda[$j] = "minutami";
            }
            break;  

          case "hodiny":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "hodinou";
            	$rozdil = "";
            }else{
            	$perioda[$j] = "hodinami";
            }
            break;  

          case "dny":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "včera";
            	$rozdil = "";
            	$slovesnyCas = "";
            }else{
            	$perioda[$j] = "dny";
            }
            break;  

          case "týdny":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "týdnem";
            	$rozdil = "";
            }else{
            	$perioda[$j] = "týdny";
            }
            break; 

          case "měsíce":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "měsícem";
            	$rozdil = "";
            }elseif( $rozdil == 12 ){
              	$perioda[$j] = "rokem";
            	$rozdil = "";
            }else{
               $perioda[$j] = "měsíci";
            }
            break; 

          case "roky":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "rokem";
            	$rozdil = "";
            }else{
            	$perioda[$j] = "roky";
            }
            break;
          default:
          	break;
          }
       }else{    // "za ..."
       	 switch ($perioda[$j]) {
       	 case "sekundy":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "sekundu";
            	$rozdil = "jednu";
            }else{
            	$perioda[$j] = "sekund";
            }
            break;

          case "minuty":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "minutu";
            	$rozdil = "";
            }else{
            	$perioda[$j] = "minut";
            }
            break;   

          case "hodiny":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "hodinu";
            	$rozdil = "";
            }elseif( $rozdil >= 2 && $rozdil < 5){
               $perioda[$j] = "hodiny";
            }elseif( $rozdil >= 5 ){
               $perioda[$j] = "hodin";
            }
            break;   

          case "dny":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "zítra";
            	$rozdil = "";
            	$slovesnyCas = "";
            }else{
               if( $rozdil > 1 && $rozdil < 5 ) {
               	$perioda[$j] = "dny";
               }else{
                  $perioda[$j] = "dní";
               }
            }
            break;   

          case "týdny":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "týden";
            	$rozdil = "";
            }elseif( $rozdil == 2 ){
               $perioda[$j] = "týden";
            	$rozdil = "příští";
            }elseif( $rozdil > 2 && $rozdil < 5 ){
               $perioda[$j] = "týdny";
            }elseif( $rozdil >= 5 ){
               $perioda[$j] = "týdnů";
            }
            break;   

          case "měsíce":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "měsíc";
            	$rozdil = "";
            }elseif( $rozdil >= 2 && $rozdil < 5 ){
               $perioda[$j] = "měsíce";
            }elseif( $rozdil == 12 ){
            	$perioda[$j] = "rok";
            	$rozdil = "";
            }elseif( $rozdil >= 5 ){
               $perioda[$j] = "měsíců";
            }
            break;  

          case "roky":
            if( $rozdil == 1 ) {
            	$perioda[$j] = "rok";
            	$rozdil = "";
            }elseif( $rozdil == 2 ){
               $perioda[$j] = "roky";
            }
            break;  

          default:

          	break;
          }
       }

       return "{$slovesnyCas} $rozdil $perioda[$j]";
   }

   /**  ------------------------------------------------------------------------
   *
   *     Vrací počet dní od parametrem předaného datumu v mysql formátu ... YYYY-mm-dd nebo YYYY-mm-dd HH:ii:ss
   *
   *     @param      string datetime
   *     @access     public
   *     @return     integer
   */
   public function pocetDni($datum = "")
   {
      $sekund = $this->datum_na_timestamp($datum);

      $rozdil = time() - $sekund;
      $dni = floor($rozdil / (60 * 60 * 24));

   	return $dni;
   }

   /**  ------------------------------------------------------------------------
   *
   *     Konvertuje DATE (YYYY-MM-DD) nebo DATETIME (YYYY-MM-DD hh:mm:ss) na timestamp
   *
   *     Vrací timestamp
   *     @param      string
   *     @access     private
   *     @return     integer
   */
   private function datum_na_timestamp($datetime = "")
   {
      // použitelné pouze pro 10 nebo 19 znakové vyjádření ( 0000-00-00  nebo 0000-00-00 00:00:00 )
      $delka = strlen($datetime);

      if(!($delka == 10 || $delka == 19)) {
         return false;
      }

      $datum = $datetime;
      $hours = 0;
      $minutes = 0;
      $seconds = 0;

      // DATETIME
      if($delka == 19)
      {
         list($datum, $time) = explode(" ", $datetime);
         list($hodin, $minut, $sekund) = explode(":", $time);
      }

      list($rok, $mesic, $den) = explode("-", $datum);

      return mktime($hodin, $minut, $sekund, $mesic, $den, $rok);
   }

} // end class

?>

class.casovy_interval.zip – zdrojový soubor

Funkce zapouzdřeny do třídy CasovyInterval. Třídu můžete používat ve svých projektech.

Inteligentní čtenáři chtějí lepší internet

Chcete, aby byl jednou internet kvalitním zdrojem informací? Potom vězte, že to záleží především na vás, čtenářích!
Co pro to udělat?
  • Byl tento článek něčím přínosný? Odkažte na něj ze svého webu, sociálních sítí nebo z diskusí.
  • Narazili jste na informace, které jsou velmi nepřesné nebo chybné? Napište zde do komentářů co je špatně a hlavně uveďte zdroj přesnějších informací.

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *