Nice dates with PHP

Published on Sunday 17 April 2016. Tagged as CSSPHP.

MySql gives the posted date of the post back in this format: 2016-04-17 20:58:00. I want to display this date in a more human readable format. To emphasize that this is a daily web log, I also want to display a nice tear-off calender cartouche in lists.

From SQL datetime to nice date

There's more than one format to store date/time values in MySql, but I have chosen 'datetime'. This is the SQL code that generates the posts table:

CREATE TABLE IF NOT EXISTS `posts` (
  `id` bigint(20) unsigned NOT NULL,
  `subject` varchar(255) NOT NULL,
  `description` text NOT NULL,
  `publishdate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `slug` varchar(255) NOT NULL,
  `status` enum('Draft','Published','Retired','') NOT NULL DEFAULT 'Published',
  `body` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

I use some simple string and array processing to convert this format: 2016-04-17 20:58:00 to a more human readable format:

function niceDate($val){
	$tmp=split('-', $val);
	$mNames=split(' ', 'January February March April May June July August September October November December');
	return (int)$tmp[2].' '.$mNames[(int) $tmp[1]-1].' '.$tmp[0];
}

This gives the more readable '17 April 2016', a compromise between the English format (aka: 'April 17th, 2016') and the European mainland format.

A tear-off calendar style cartouche

To render the date as a nice recognisable tear-off calendar style cartouche, I need a PHP function to generate the HTML tags and then some CSS to style them. This is the PHP function I made:

function dateBlock($val){
	$tmp=split('-', $val);
	$mNames=split(' ', 'January February March April May June July August September October November December');
	$day=(int)$tmp[2];
	$month=$mNames[(int) $tmp[1]-1];
	$year=$tmp[0];
	return "<div class=\"dateBlock\"><b>$month</b><i>$day</i>$year</div>";
}

Instead of using multiple divs or spans with classes, I use one <div class="dateBlock"> and the semantically neutral tag <b> for the month and <i> for the day number. Some on the internet say never to use the tags <b> and <i>, but I read this as: never use them when the semantic meaning of its content is 'emphasis' or 'strong emphasis'... but to tag elements just to have a CSS handle without symantic annotation, why not?

Next I added some CSS. I position them absolute instead of having it float left, because then I can add left padding to the parent to prevent the content 'closing the gap' under the cartouche when the content gets higher. This is the entire CSS for the list and the calendar date cartouche:

.list{list-style:none;margin:0;padding:0}
.list li{margin:0}
.list a{display:block;text-decoration:none;color:inherit;border-bottom:solid 1px #b6b6b6;padding:8px 16px 4px 122px;position:relative;min-height:116px}
.list li:last-child a{border:0}
.list a:hover{background:#f0f0f0}
.list :hover h2{color:#f57c00}

.dateBlock{position:absolute;top:12px;left:16px;width:90px;border:solid 1px #b6b6b6;text-align:center;margin-right:16px;border-radius:10px;font-size:15px;background:#fff}
.dateBlock b,.dateBlock i{display:block}
.dateBlock b{background:#ff9800;color:#fff;border-radius:10px 10px 0 0;padding:3px}
.dateBlock i{font-style:normal;font-size:3em;color:#727272;line-height:1;padding-bottom:10px}

And here is the resulting display:

What next? Tomorrow I will write about how to reduce the number of HTTP request on a page. I'll also explain the benefits of using SVG instead of icon fonts or image sprites for icons and logos.