18Nov 2011 6 Comments */?>

Clase para mostrar fechas al estilo “hace 1 dia 6 min” con PHP

Categorías: PHP, Recursos, Tips de PHP, Tutoriales - Tags: ,

La mayoría de redes sociales como Twitter o Facebook en lugar de mostrar las fechas como 2011-11-18 utilizan un formato de “Hace 2 dias 4 horas 3 minutos“. Pasa usar ese formato en sus programas se pueden ayudar de la siguiente clase de PHP llamada haceTanto.
Esta clase la encontre por internet en formato ingles y la modifique para nuestro idioma y le agregue la opción de elegir una profundidad a la hora de mostrar fechas.

Importante

Esta clase solo funciona con PHP >= 5.3 ya que la función DateTime::diff() no se encuentra en versiones previas

Para utilizar la clase la llamamos de la siguiente forma:

1
2
3
date_default_timezone_set('Europe/Madrid');
$hace = new haceTanto('2010-02-22 18:42:00','s');
echo 'Hace'.$hace;
  • 1. Definimos el Timezone que nos encontramos
  • 2. Creamos la instancia de haceTanto pasando dos valores.
    • Una fecha por ejemplo: “2011-10-26”
    • La profundidad hasta la que queremos mostrar siendo los posibles valores: ‘y’ => años ,’m’ => meses, ‘d’ => dias, ‘i’ => horas, ‘m’ => minutos, ‘s’ => segundos
  • 3. Imprimimos la fecha

El ejemplo anterior imprime:

1
2
3
4
date_default_timezone_set('Europe/Madrid');
$hace = new haceTanto('2010-02-22 18:42:00','s');
echo 'Hace'.$hace;
//Hace 1 año 8 meses 27 dias 28 minutos 5 segundos

Y ahora la clase de PHP encargada de esto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php
class haceTanto extends DateTime {
 
    protected $strings = array(
        'y' => array('1 a&ntilde;o', '%d a&ntilde;os'),
        'm' => array('1 mes', '%d meses'),
        'd' => array('1 d&iacute;a', '%d dias'),
        'h' => array('1 hora', '%d horas'),
        'i' => array('1 min', '%d minutos'),
        's' => array('segundos', '%d segundos'),
    );
 
    public $profundidad;
 
    public function __construct( $fecha,$profundidad='i')
    {
        parent::__construct( $fecha );
        $this->profundidad = $profundidad;
 
    }
 
 
    public function __toString() {
	     try 
	    {  
	     	$now = new DateTime('now');
	        $diff = $this->diff($now);
 
	        foreach($this->strings as $key => $value){
 
	            if( ($text .= ' '.$this->getDiffText($key, $diff)) ){
 
	            }
	            if($this->profundidad == $key) break;
	        }
	        return $text;   
	    } 
	    catch(Exception $e) 
	    {  
	        trigger_error($e->getMessage(), E_USER_ERROR);  
	        return '';  
	    }  
 
 
    }
 
     protected function getDiffText($intervalKey, $diff){
        $pluralKey = 1;
        $value = $diff->$intervalKey;
        if($value > 0){
            if($value < 2){
                $pluralKey = 0;
            }
            return sprintf($this->strings[$intervalKey][$pluralKey], $value);
        }
        return null;
    }
}
?>

Espero que les sirva de ayuda en sus proyectos. Saludos!!

Damián Logghe

Programador freelancer y emprendedor en sueños. Contento de ser mi jefe y poder hacer lo que me gusta. WordPress es mi principal fuente de ingreso y me escribo tanto para ayudar como para tener una guia de memoria. Quieres contratarme? Déjame un mensaje.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle Plus

  • Roky

    buen post

  • Excelente clase, la he modificado para en vez de ser el tiempo transcurrido entre fechas, me diga el número de días, meses, etc a partir de un número concreto de minutos.

    Gracias por el aporte

  • Claudio Caldareri

    Muy buena tu clase.

    Me tomo el atrevimiento de modificar tu clase para que lo muestre al estilo twitter, espero no te moleste:foreach($this->strings as $key => $value){
    $dato=$this->getDiffText($key, $diff);
    if($dato!=null ){
    $text .= ‘ ‘.$dato;
    break;
    }Así solo mostraría un solo dato y no la fecha competa.

  • Josh

    porque me aparece Undefined variable: text en la linea 31?

  • Alberto

    Funciona bien la funcion, no se le podria dar estilo facebook

  • Juan Pendino

    Estimado Damián:

    He tenido que agregar la siguiente línea para inicializar la variable:
    $text =””; (en la función __toString() ).

    Gracias por el código.