Date semantics, the incomplete way
When dating a blog post, a comment, an article, there is usually a semantic problem. A visitor looks at the date, let’s say 07/01/09, 5:04, and wonders…
- Ok, that’s the date. But is it PM or AM?
- How should I read the date, american (month/day/year), european (day/month/year) or japanese (year/month/day)?
- And what’s the timezone in which was written, and what’s my timezone?
The worst blogger way
The default template in blogger separates time (at the end of every post, to maintain the permanent link) and date (at the beginning of every post):
Date semantics, the complete and too crowded way
It is not a very nice way of presenting it. But this post is about the date semantics: even if the date is perfectly stated, like 7 January 2009, 5:04 PM CET, there is a usability problem. Back to our visitor:
- Ok, that’s the well-defined date. What is my timezone?
- And how much time has it passed since it was published?
That is the point: how much time ago? This does not happen with future dates, like bidding or the time a concert/movie starts. But with already past dates, and most of the times, the visitor only needs to know how much time it has passed. For example, 3 months, 17 days, 4 hours, 23 minutes, 22 seconds, 333 milisecons ago.
That is more meaningful, but still has too much information, and anyway it will be outdated the moment it renders on a webpage.
The twitter way
The right way!
But it stops in hours, and for days it renders the whole date. Too much non-related information. I would rather prefer it to say:
- seconds ago (during the first minute), or
- N minutes ago (during the first hour), or
- N hours ago (during the first day), or
- N days ago (during the first week),
and so on with weeks, months and years. If it has been 3 weeks ago, is it really needed to know at what exact time it was? For some applications, maybe it is, but not most of the times.
Date semantics in PHP
$time_now = date( "YmdHis" );
$seconds = $time_now - $date_old;
if( $seconds < 60 ) { $iQuant = $seconds; $sUnit = "second"; }
elseif( $seconds < ( 60 * 60 ) ) { $iQuant = (int) ( $seconds / 60 ); $sUnit = "minute"; }
elseif( $seconds < ( 24 * 60 * 60 ) ) { $iQuant = (int) ( $seconds / ( 60 * 60 ) ); $sUnit = "hour"; }
elseif( $seconds < ( 31 * 24 * 60 * 60 ) ) { $iQuant = (int) ( $seconds / ( 24 * 60 * 60 ) ); $sUnit = "day"; }
elseif( $seconds < ( 12 * 31 * 24 * 60 * 60 ) ) { $iQuant = (int) ( $seconds / ( 31 * 24 * 60 * 60 ) ); $sUnit = "month"; }
else { $iQuant = (int) ( $seconds / ( 12 * 31 * 24 * 60 * 60 ) ); $sUnit = "year"; }
$s = $iQuant . " " . $sUnit . "s ago";
An improvement: if the quantity is one (week, minute…) it is nicer to get “a week ago” or “a minute ago”. Then we have:
if( $iQuant == 1 ) $s = "about a " . $sUnit . " ago"; else $s = $iQuant . " " . $sUnit . "s ago";
Almost done. Just a filter for one hour (“an hour ago”):
if( $iQuant == 1 && $sUnit == "hour" ) $s = "about an hour ago"; elseif( $iQuant == 1 ) $s = "about a " . $sUnit . " ago"; else $s = $iQuant . " " . $sUnit . "s ago";
The final function
/*
* datedistance: function to calculate time distance, twitter style
* $date_old: string format YmdHis, like 20100526232500 -- i.e. 11:25 PM, 26/05/2010
*
* author: Fulgencio Sanmartin
*/
function datedistance( $date_old )
{
$time_now = date( "YmdHis" );
$seconds = $time_now - $date_old;
if( $seconds < 60 ) { $iQuant = $seconds; $sUnit = "second"; }
elseif( $seconds < ( 60 * 60 ) ) { $iQuant = (int) ( $seconds / 60 ); $sUnit = "minute"; }
elseif( $seconds < ( 24 * 60 * 60 ) ) { $iQuant = (int) ( $seconds / ( 60 * 60 ) ); $sUnit = "hour"; }
elseif( $seconds < ( 31 * 24 * 60 * 60 ) ) { $iQuant = (int) ( $seconds / ( 24 * 60 * 60 ) ); $sUnit = "day"; }
elseif( $seconds < ( 12 * 31 * 24 * 60 * 60 ) ) { $iQuant = (int) ( $seconds / ( 31 * 24 * 60 * 60 ) ); $sUnit = "month"; }
else { $iQuant = (int) ( $seconds / ( 12 * 31 * 24 * 60 * 60 ) ); $sUnit = "year"; }
if( $iQuant == 1 && $sUnit == "hour" )
$s = "about an hour ago";
elseif( $iQuant == 1 )
$s = "about a " . $sUnit . " ago";
else
$s = $iQuant . " " . $sUnit . "s ago";
return $s;
}

The date semantics by geometrus, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.

















