Data e hora no formato do Twitter

Olá.

Um dos meus clientes sugeriu modificar a forma de exibição das datas. Um formato mais fácil para entender. No nosso caso, precisavamos visualizar a idade dos pacientes sem precisar analisar a data de nascimento e calcular “nos dedos”. Ok, mas pacientes podem ter 10 dias de vida, 2 meses, 12 anos, 40 anos…

Lembrei do Twitter que exibe a data e hora em formato “humano” logo a baixo dos tweets. Exemplo: xhelton escreveu isso a 1 hora atrás… 10 dias atrás… 1 mês atrás.

A solução encontrada foi esta:

Para Javascript:

/**
* HORA NO FORMATO HUMANO
* 
* @example
* var data = new Date(2013, 2, 2);
* alert(humanTiming(data) +" atrás");
* 
* @param dateTime Data e hora no formato interno do javascript.
*/
humanTiming : function(dateTime){
    var currentDateTime = new Date();
    var tokens = [
        [31536000, ["ano", "anos"]],
        [2592000, ["mês", "meses"]],
        [604800, ["semana", "semanas"]],
        [86400, ["dia", "dias"]],
        [3600, ["hora", "horas"]],
        [60, ["minuto", "minutos"]],
        [1, ["segundo", "segundos"]]
    ];
    
    dateTime = Math.floor((currentDateTime.getTime() - dateTime.getTime()) / 1000);
    
    for(a in tokens){
        if(dateTime < tokens[a][0])
            continue;
        
        numberOfUnits = Math.floor(dateTime / tokens[a][0]);
        return numberOfUnits +" "+ (numberOfUnits > 1 ? tokens[a][1][1] : tokens[a][1][0]); 
    }
}

Para PHP:

/**
 * RETORNA A DATA/HORA EM FORMATO HUMANO
 * @example echo humanTiming("2013-02-02 10:00:00");
 * @param $dateTime Data e hora (ou somente data)
 * @return string
 */
public static function humanTiming($dateTime){
    if($dateTime == "")
        return "";
    
    $dateTime = time() - strtotime($dateTime);
    
    $tokens = array(
        31536000 => array("ano", "anos"),
        2592000 => array("mês", "meses"),
        604800 => array("semana", "semanas"),
        86400 => array("dia", "dias"),
        3600 => array("hora", "horas"),
        60 => array("minuto", "minutos"),
        1 => array("segundo", "segundos")
    );
    
    foreach ($tokens as $unit => $text) {
        if ($dateTime < $unit) continue;
        $numberOfUnits = floor($dateTime / $unit);
        return $numberOfUnits . ' ' . (($numberOfUnits > 1) ? $text[1] : $text[0]);
    }
}

Fica a dica!