I agree with astions. Always use braces with your if statements. And if you absolutely MUST leave out the braces, put it all on one line:
Obviously this is a question of taste, so leave it if you want, but I think most developers prefer that you not do that.
Also, I wrote a view helper with similar functionality a while back. I thought you might be able to take some inspiration from it. Or maybe not. Either way, here it is:
Code: Select all
<?php
/**
* Zend View Helper for "humanizing" dates and numbers.
*
* @package ImpSoft
* @copyright Luke Visinoni (luke.visinoni@gmail.com)
* @author Luke Visinoni (luke.visinoni@gmail.com)
* @license GNU Lesser General Public License
*/
class ImpSoft_View_Helper_Humanize {
const DAYFORMAT = 'M d, Y';
const TIMEFORMAT = 'g:ia';
const DATEFORMAT = 'm/d/Y h:i:sa';
public function humanize() {
return $this;
}
/**
* Converts an integer to its ordinal as a string. 1 is '1st', 2 is '2nd', etc.
* @todo Optionally humanize number as well and default to true. 1000 is 1,000th, etc.
*/
public function ordinal($value) {
$value = (integer) $value;
$ord = array('th','st','nd','rd','th','th','th','th','th','th');
// special cases
if (in_array($value % 100, array(11, 12, 13))) return sprintf("%d%s", $value, $ord[0]);
return sprintf('%d%s', $value, $ord[$value % 10]);
}
/**
* Converts a large integer to a friendly text representation. Works best for
* numbers over 1 million. For example, 1000000 becomes '1.0 million', 1200000
* becomes '1.2 million' and '1200000000' becomes '1.2 billion'.
*
* For now, don't send numbers larger than 2 billion to it.
*/
public function intword($value) {
$value = (integer) $value;
if ($value < 1000000) {
return $value;
}
if ($value < 1000000000) {
$new_value = $value / 1000000.0;
return sprintf("%.1f million", $new_value);
}
if ($value < 1000000000000) {
$new_value = $value / 1000000000.0;
return sprintf("%.1f billon", $new_value);
}
/** PHP doesn't support numbers this large without an extension.
if ($value < 1000000000000000) {
$new_value = $value / 1000000000000.0;
return sprintf("%.1f trillion", $new_value);
}
*/
return $value;
}
/**
* Returns a "humanized" day - today, tomorrow, yesterday if relevant,
* otherwise it returns the date in $format format
*
* I am sure this is not the best way to do this, but it works
*/
public function naturalDay($timestamp = null, $format = null) {
if (is_null($timestamp)) $timestamp = time();
if (is_null($format)) $format = self::DAYFORMAT;
$oneday = 60*60*24;
$today = strtotime('today');
$tomorrow = $today + $oneday;
$yesterday = $today - $oneday;
// if time is 12:00 yesterday or more
if ($timestamp >= $yesterday) {
// if time is less than 12:00 the day after tomorrow
if ($timestamp < $tomorrow + $oneday && $timestamp > $today) {
// if time is less than 12:00 tomorrow
if ($timestamp < $tomorrow) {
return 'today';
}
return 'tomorrow';
}
return 'yesterday';
}
return date($format, $timestamp);
}
/**
* Returns a "humanized" time - so, if entry was today, it will say "about 16 minutes ago", "about 8 hours ago",
* but if it isn't it will return the time formatted in $format format
*
* I am sure this is not the best way to do this, but it works
*/
public function naturalTime($timestamp = null, $format = null) {
if (is_null($timestamp)) $timestamp = time();
if (is_null($format)) $format = self::TIMEFORMAT;
$now = time();
$hour = 60*60;
if ($this->naturalDay($timestamp, $format) == 'today') {
$hourago = $now - $hour;
$hourfromnow = $now + $hour;
// if timestamp passed in was after an hour ago...
if ($timestamp > $hourago) {
// if timestamp passed in is in the future...
if ($timestamp > $now) {
// return how many minutes from now
$seconds = $timestamp - $now;
$minutes = (integer) round($seconds/60);
// if more than 60 minutes ago, report in hours
if ($minutes > 60) {
$hours = round($minutes/60);
return "in about $hours hours";
}
// if it got rounded down to zero, or it was one, report one
if (!$minutes || $minutes === 1) return "just now";
return "in about $minutes minutes";
}
// return how many minutes from now
$seconds = $now - $timestamp;
$minutes = (integer) round($seconds/60);
// if it got rounded down to zero, or it was one, report one
if (!$minutes || $minutes === 1) return "just now";
return "about $minutes minutes ago";
}
}
return date($format, $timestamp);
}
/**
* For now, this will only convert numbers 0-9
* @todo Convert a number to it's spelled-out version. For instance, 1 becomes one, 307 becomes
* three hundred seven, 28 becomes twenty-eight.
*/
public function strNum($value) {
$int = (integer) $value;
$numbers = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
if (isset($numbers[$value])) return $numbers[$value];
return $value;
}
}
It is used like this:
Code: Select all
Posted on <?= $this->humanize()->naturalDay($this->post->datetime) ?> at <?= $this->humanize()->naturalTime($this->post->datetime) ?>