Skip to content

Instantly share code, notes, and snippets.

@SeanJA
Created August 18, 2010 06:20
Show Gist options
  • Select an option

  • Save SeanJA/533676 to your computer and use it in GitHub Desktop.

Select an option

Save SeanJA/533676 to your computer and use it in GitHub Desktop.
<?php
class date {
/**
* Display the time from now in a readable way
* @param int $targetTime
* @param int $now
* @return string
*/
static function fromNow($targetTime=0, $now=null) {
if (!$now) {
$now = time();
}
$seconddiff = $now - $targetTime; // Raw time difference
$yeardiff = date('Y', $now) - date('Y', $targetTime);
$datediff = self::countDays($now, $targetTime);
//if the target is within 30 minutes, it is now
if (abs($seconddiff) <= 60 * 30) {
return 'Now';
}
//if the date is within a day
elseif (abs($datediff) <= 1) {
if ($datediff == 0) {
return 'Today @ ' . date('H:i', $targetTime);
} elseif ($datediff == -1) {
return 'Yesterday @ ' . date('H:i', $targetTime);
} else {
return 'Tomorrow @ ' . date('H:i', $targetTime);
}
}
//it is within the week, display that date as [day of the week] @ [hour]:[minute]
elseif($datediff > 1 && $datediff <= 6){
return date('D j @ H:i', $targetTime);
}
//otherwise, display the date as [Month] @ [hour]:[minute]
else {
return date('M j @ H:i', $targetTime);
}
}
/**
* Count the number of days between the two timestamps
* @param int $fromTimestamp
* @param int $toTimestamp
* @return int
*/
public static function countDays($fromTimestamp, $toTimestamp) {
// First we need to break these dates into their constituent parts:
$fromDate = getdate($fromTimestamp);
$toDate = getdate($toTimestamp);
// Now recreate these timestamps, based upon noon on each day
// The specific time doesn't matter but it must be the same each day
$fromTime = mktime(12, 0, 0, $fromDate['mon'], $fromDate['mday'], $fromDate['year']);
$toTime = mktime(12, 0, 0, $toDate['mon'], $toDate['mday'], $toDate['year']);
// Subtract these two numbers and divide by the number of seconds in a
// day. Round the result since crossing over a daylight savings time
// barrier will cause this time to be off by an hour or two.
return round(($toTime - $fromTime) / 86400);
}
}
<?php
require_once 'PHPUnit/Framework.php';
require_once dirname(__FILE__) . '/../date.php';
/**
* Test class for date.
* Generated by PHPUnit on 2010-08-18 at 19:22:49.
*/
class dateTest extends PHPUnit_Framework_TestCase {
protected $now = null;
/**
* @var date
*/
protected $object;
protected function setUp() {
//now == Jan 1 2010
$this->now = mktime(0, 0, 0, 1, 1, 2010);
$this->object = new date;
}
public function testFromNowYesterday() {
$tests = array(
'Yesterday @ 00:00' => mktime(0, 0, 0, 12, 31, 2009),
'Yesterday @ 03:15' => mktime(3, 15, 0, 12, 31, 2009),
'Yesterday @ 23:00' => mktime(23, 00, 0, 12, 31, 2009),
);
foreach($tests as $expected => $test){
$this->assertEquals($expected, date::fromNow($test, $this->now));
}
}
public function testNow(){
$tests = array(
'Now' => $this->now + (60 * 30),
'Now' => $this->now + (60 * 15),
'Now' => $this->now,
'Now' => $this->now + (60 * -15),
'Now' => $this->now + (60 * -30),
);
foreach($tests as $expected => $test){
$this->assertEquals($expected, date::fromNow($test, $this->now));
}
$this->assertEquals('Now', date::fromNow(time()));
}
public function testFromNowToday() {
$tests = array(
'Today @ 03:15'=>mktime(3, 15, 0, 1, 1, 2010),
'Today @ 23:59'=>mktime(23, 59, 0, 1, 1, 2010),
'Today @ 20:00'=>mktime(20, 00, 0, 1, 1, 2010),
);
foreach($tests as $expected => $test){
$this->assertEquals($expected, date::fromNow($test, $this->now));
}
}
public function testFromNowTomorrow() {
$tests = array(
'Tomorrow @ 00:00' => mktime(0, 0, 0, 1, 2, 2010),
'Tomorrow @ 03:15' => mktime(3, 15, 0, 1, 2, 2010),
'Tomorrow @ 23:59' => mktime(23, 59, 0, 1, 2, 2010),
);
//mktime($hour, $minute, $second, $month, $day, $year)
foreach($tests as $expected => $test){
$this->assertEquals($expected, date::fromNow($test, $this->now));
}
}
public function testThisWeek(){
$tests = array(
'Tomorrow @ 00:00' => mktime(0, 0, 0, 1, 2, 2010),
'Sun 3 @ 00:00' => mktime(0, 0, 0, 1, 3, 2010),
'Mon 4 @ 00:00' => mktime(0, 0, 0, 1, 4, 2010),
'Tue 5 @ 00:00' => mktime(0, 0, 0, 1, 5, 2010),
'Wed 6 @ 00:00' => mktime(0, 0, 0, 1, 6, 2010),
'Thu 7 @ 00:00' => mktime(0, 0, 0, 1, 7, 2010),
);
//mktime($hour, $minute, $second, $month, $day, $year)
foreach($tests as $expected => $test){
$this->assertEquals($expected, date::fromNow($test, $this->now));
}
}
public function testRandomDays(){
$tests = array(
'Jan 20 @ 00:00' => mktime(0, 0, 0, 1, 20, 2010),
'Feb 2 @ 03:15' => mktime(3, 15, 0, 2, 2, 2010),
'Mar 2 @ 23:59' => mktime(23, 59, 0, 3, 2, 2010),
);
//mktime($hour, $minute, $second, $month, $day, $year)
foreach($tests as $expected => $test){
$this->assertEquals($expected, date::fromNow($test, $this->now));
}
}
public function testCountDays(){
$tests = array(
array(31, mktime(0, 0, 0, 1, 20, 2010), mktime(0, 0, 0, 2, 20, 2010)),
array(1, mktime(0, 0, 0, 1, 20, 2010), mktime(0, 0, 0, 1, 21, 2010)),
array(3705, mktime(0, 0, 0, 0, 0, 0), mktime(0, 0, 0, 1, 21, 2010)),
array(1, mktime(0, 0, 0, 12, 31, 2009), mktime(0, 0, 0, 1, 1, 2010)),
array(-1, mktime(0, 0, 0, 1, 1, 2010), mktime(0, 0, 0, 12, 31, 2009)),
array(0, mktime(0, 0, 0, 1, 1, 2010), mktime(0, 0, 0, 1, 1, 2010)),
array(24855, 0, 2147483647), // Value of PHP_INT_MAX PHP 5.3
);
foreach($tests as $test){
list($expected, $start, $finish) = array_values($test);
$this->assertEquals($expected, date::countDays($start, $finish));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment