[PHP] Relative date time : afficher une date comme Facebook ou Gmail

Voici un petit bout de code pour afficher une date à la manière "sociale" :

  • 3 seconds ago
  • 1 minute and 38 seconds ago
  • Today at 8:33 am
  • Yesterday at 0:23 pm
  • Last friday at 16:58 pm
  • 4 days ago
  • The 23 april
  • December 17, 2011

Cette fonction permet de spécifier le temps de référence (par défaut l'heure actuelle), et supporte les dates passée ou futures.

function rdatetime_en($timestamp, $ref = 0) {

	if ($ref < 1) $ref = time();

	$ts = $ref - $timestamp;
	$past = $ts > 0;
	$ts = abs($ts);

	if ($past) {
		$left = '';
		$right = ' ago';
	}
	else {
		$left = 'In ';
		$right = '';
	}

	if ($ts === 0) return 'Now';

	if ($ts === 1) return $left.'1 second'.$right;

	// Less than 1 minute
	if ($ts < 60) return $left.$ts.' seconds'.$right;

	$tm = floor($ts / 60);
	$ts = $ts - $tm * 60;

	// Less than 3 hours
	if ($tm < 3 && $ts > 0) {
		return $left.$tm.' minute'.($tm > 1 ? 's' : '').' and '
			.$ts.' second'.($ts > 1 ? 's' : '').$right;
	}

	// Less than 1 hour
	if ($tm < 60) {
		if ($ts > 0) {
			$left = 'About ';
		}
		return $left.$tm.' minutes'.$right;
	}

	$th = floor($tm / 60);
	$tm = $tm - $th * 60;

	// Less than 3 hours
	if ($th < 3) {
		if ($tm > 0) {
			return $left.$th.' hour'.($th > 1 ? 's' : '').' and '
				.$tm.' minute'.($tm > 1 ? 's' : '').$right;
		}
		else {
			return $left.$th.' hour'.($th > 1 ? 's' : '').$right;
		}
	}

	$refday = strtotime(date('Y-m-d', $ref));
	$refyday = strtotime(date('Y-m-d', $ref - 86400));

	// Same day, or yesterday
	if ($timestamp >= $refyday) {
		if ($timestamp < $refday) {
			$left = 'Yesterday ';
			$right = '';
		}
		else {
			$left = 'Today ';
			$right = '';
		}
		return $left.' at '.date('H:i a', $timestamp).' '.$right;
	}

	$td = floor($th / 24);
	$th = $th - $td * 24;

	// Less than 3 days
	if ($td < 3) {
		$left = 'Last ';
		$right = '';
		return $left.strtolower(date('l', $timestamp)).' at '
			.date('H:i', $timestamp).$right;
	}

	// Less than 5 days
	if ($td < 5) {
		return $left.$td.' days'.$right;
	}

	$refday = strtotime(date('Y-m-01', $ref));

	$right = '';

	// Same month
	if ($timestamp >= $refyday) {
		$left = 'The ';
		return $left.date('j F', $timestamp).$right;
	}

	return $left.date('F j, Y', $timestamp).$right;

}

Si vous constatez des réultats étranges, vérifiez bien que votre serveur est réglé sur le même fuseau horaire que vous. Si ce n'est pas le cas, vous pouvez changer facilement grace à la fonction :

bool date_default_timezone_set ( string $timezone_identifier )


Commentaires

1. Commentaire de freddysimo le samedi 19 novembre 2011

J'ai rajouté :
if ($timestamp == 0) echo "Never";

Comme ça si un timestamp est à 0 dans une base de donnée ça n'affiche pas "January 1, 1970"


About the Author

Ted Marklor est un web designer, un web developer et un génie de la nature. Transcendant le web depuis bientôt 15 ans, Ted est une source d’inspiration et de conseil pour toute une génération de jeunes programmeurs. Le Web 2.0, c’est lui. Dans la vie, il aime aussi faire des avions en papier, s’inventer des pseudonymes et une vie de winner, et surtout parler de lui à la troisième personne. Ça se fait en ce moment sur les blogs…


Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.