1 month ago on January 22

Displaying dates for a user can be a bit tricky. First, you have to take into consideration what time zone they are in and what date format they prefer. Also, some people consider it easier to calculate a relative date in their mind. An easy workaround to this mess is to display dates in a relative format, "2 hours ago", "5 months ago." The way this is done, is to take the difference of two Unix timestamps--virtually, seconds since January 1, 1970 00:00 UTC.

PHP

<?php
//////////
function relative_time($to=NULL, $from=NULL) {
	$now = time(); // Get current UNIX timestamp
	$past = '';
	$future = '';
	
	$to = (!is_numeric($to)) ? $now : round($to); // Default to UNIX if not number
	$from = (!is_numeric($from)) ? $now : round($from); // Default to UNIX if not number
	if($from > $to) { $past = ' ago'; } else { $future = 'in '; }
	$seconds = abs($to-$from); // Get absolute difference
	$units = array(
		'values'=>array(31556926, 2629743.83, 604800, 86400, 3600, 60),
		'labels'=>array('year', 'month', 'week', 'day', 'hour', 'minute')
	);
	
	foreach($units['values'] as $i=>$value) {
		$value = $seconds/$value;
		if($value >= 1) {
			// Test all units until division is more than 1
			$value = ($i===0) ? round($value, 1) : round($value);
			
			$label = $units['labels'][$i];
			$value = ($label=='year') ? number_format($value, 1) : round($value);
			$label = ($value == 1) ? $label : "{$label}s";
			
			$string = "$future$value $label$past";
			break; // No need to test rest if found
		}
	}
	
	if(empty($string)) {
		$string = "{$future}less than a minute{$past}";
	}
	
	return $string;
}
//////////
$to_date = strtotime('Oct 12, 2011 15:20'); // Get to timestamp
$from_date = strtotime('Oct 12, 2011 11:07'); // Get from timestamp
echo relative_time($to_date, $from_date); // In 4 hours
?>

JavaScript

//////////
function relative_time(to, from) {
	var now = Math.round(new Date().getTime()/1000); // Get now UNIX timestamp
	var past = '';
	var future = '';
	var string = '';
	
	if(isNaN(to = parseInt(to))) { to = now; } // If to is not integer, use now
	if(isNaN(from = parseInt(from))) { from = now; } // If from is not integer, use now
	if(from > to) { past = ' ago'; } else { future = 'in '; } // Set if in future or past
	var seconds = Math.abs(to-from); // Get absolute seconds difference
	
	var values = new Array(31556926, 2629743.83, 604800, 86400, 3600, 60); // Unit values
	var labels = new Array('year', 'month', 'week', 'day', 'hour', 'minute'); // Unit labels
	for(var i=0; i<values.length; i++) {
		// Test against all units, till is more than one
		var value = values[i];
		value = seconds/value;
		if(value >= 1) {
			value = (i===0) ? Math.round(value*10)/10 : Math.round(value);
			var label = labels[i];
			label = (value == 1) ? label : label+'s';
			string = future+value+' '+label+past;
			break; // Found, no need to search rest
		}
	}
	
	if(string=='') {
		// Default to less than a minute
		string = future+'less than a minute'+past;
	}
	
	return string;
}
//////////
var to_date = Date.parse("Dec 1, 2012")/1000; // Get UNIX timestamp
var relative = relative_time(to_date); // Calculate from now
document.write(relative.toString()); // 7 months ago
Short URL: http://mayavps.com/a19
If you enjoyed this post, please subscribe via e-mail, RSS, or Twitter.

No comments yet

What's on your mind?

Gravatar

HTML not converted. Links begin with http://. Code blocks should be wrapped with [code][/code]. Unicode characters accepted.


E-Mail RSS