Last active
August 29, 2015 13:56
-
-
Save headquarters/8996249 to your computer and use it in GitHub Desktop.
A PHP class to turn a timestamp into more user-friendly relative date.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A class for turning timestamps into more user-friendly relative dates. | |
* | |
$date = new Relative_Date(); | |
echo $date->relative_formatted_date; //"Today" | |
*/ | |
class Relative_Date { | |
const DAY = 86400; | |
public $timestamp; //keep timestamp used to instantiate object | |
public $daystamp; //timestamp for that day, 12:00:00 | |
public $info; //getdate() info (Array) | |
public $day_of_week; //string day of week, ex. "Monday" | |
public $relative_formatted_date; //string of date compared to today - "Today", "Yesterday", "x days ago", etc. | |
public $formatted_date; //string of date compared to today - "Today", "Yesterday", "Wednesday", "Tuesday", etc. | |
public function __construct($timestamp = null){ | |
if(empty($timestamp)){ | |
$timestamp = time(); | |
} | |
if(is_string($timestamp)){ | |
$timestamp = strtotime($timestamp); | |
} | |
$this->timestamp = $timestamp; | |
$this->info = getdate($timestamp); | |
$this->daystamp = mktime(0, 0, 0, $this->info['mon'], $this->info['mday'], $this->info['year']); | |
$this->day_of_week = $this->info['weekday']; //"Friday" | |
$this->relative_formatted_date = $this->get_formatted_date(true); //"Today"|"Yesterday"|"x days ago" | |
$this->formatted_date = $this->get_formatted_date(); //"Today"|"Yesterday"|"Wednesday" | |
} | |
/** | |
* | |
* @param int $timestamp [optional] | |
* @return the number of days between this App_Date object and a given timestamp (0: today, 1+: future, -1: past) | |
*/ | |
public function get_day_difference($timestamp = null){ | |
if(empty($timestamp)){ | |
$timestamp = time(); | |
} | |
//get # of days in first timestamp | |
$first = $this->timestamp/self::DAY; | |
//get # of days in second timestamp | |
$second = $timestamp/self::DAY; | |
//get difference in days | |
$difference = floor($second) - floor($first); | |
return $difference; | |
} | |
/** | |
* gets the previous working day (Friday before a Monday, or M-Th otherwise) | |
* @return previous working day as an instance of App_Date | |
*/ | |
public function get_previous_working_day(){ | |
$date = $this->info; | |
$day_of_month = $date['mday']; | |
$day_of_week = $date['wday']; | |
if($day_of_week == 0){ | |
//is Sunday, get Friday | |
$previous_work_day = $day_of_month - 2; | |
} | |
elseif($day_of_week == 1){ | |
//is Monday, get Friday | |
$previous_work_day = $day_of_month - 3; | |
} else { | |
//is any other day of the week, get previous | |
$previous_work_day = $day_of_month - 1; | |
} | |
$timestamp = mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $previous_work_day, $date['year']); | |
$new_date = new App_Date($timestamp); | |
return $new_date; | |
} | |
/** | |
* gets the next working day (Monday after a Friday, or other Tues-F otherwise) | |
* @return next working day as an instance of App_Date | |
*/ | |
public function get_next_working_day(){ | |
$date = $this->info; | |
$day_of_month = $date['mday']; | |
$day_of_week = $date['wday']; | |
if($day_of_week == 5){ | |
//is Friday, get Monday | |
$next_work_day = $day_of_month + 3; | |
} | |
elseif($day_of_week == 6){ | |
//is Saturday, get Monday | |
$next_work_day = $day_of_month + 2; | |
} else { | |
//is any other day of the week, get previous | |
$next_work_day = $day_of_month + 1; | |
} | |
$timestamp = mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $next_work_day, $date['year']); | |
$new_date = new App_Date($timestamp); | |
return $new_date; | |
} | |
/** | |
* A helper function for getting many previous work days (including current day) - NOTE that this returns an array of App_Date objects | |
* @param object $number_of_days [optional] | |
* @return Array of App_Date instances | |
*/ | |
public function get_previous_working_days($number_of_days = 1){ | |
$working_days = array(); | |
//beginning date is this | |
$current_date = $this; | |
for($i = 0; $i < $number_of_days; $i++){ | |
$working_days[] = $current_date; | |
$new_date = new App_Date($current_date->timestamp); | |
$current_date = $new_date->get_previous_working_day(); | |
} | |
return $working_days; | |
} | |
/** | |
* Get the formatted string based on relationship of current object's week to the current (actual) week | |
* @return formatted string | |
*/ | |
public function get_formatted_week(){ | |
$difference = $this->get_week_difference(); | |
if($difference == 0){ | |
return "This Week"; | |
} | |
elseif($difference == -1){ | |
return "Last Week"; | |
} | |
elseif($difference == 1){ | |
return "Next Week"; | |
} | |
else { | |
$date = $this->info; | |
//get day of month | |
$mday = $date['mday']; | |
//get day of week | |
$wday = $date['wday']; | |
//get the day of the month that is the Sunday of the current week | |
$sunday = $mday - $wday; | |
$timestamp = mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $sunday, $date['year']); | |
return 'Week of ' . date('F j, Y', $timestamp); | |
} | |
} | |
/** | |
* get the difference in weeks between two timestamps, within the context of a business week | |
* e.g. A Monday of the current week is in a different week than the previous Friday, despite the difference being < 7 days | |
* @param object $timestamp [optional] | |
* @return | |
*/ | |
public function get_week_difference($timestamp = null){ | |
if(empty($timestamp)){ | |
$timestamp = time(); | |
} | |
//date('W') assumes week starts on Monday | |
$week_of_year = date('W', $this->timestamp); | |
$other_week_of_year = date('W', $timestamp); | |
$difference = $week_of_year - $other_week_of_year; | |
return $difference; | |
} | |
/** | |
* Return formatted string determining if $this date is "Tomorrow", "Today", "Yesterday" or "X days ago" | |
* @return a string representing how "now" compares to calling object | |
*/ | |
public function get_formatted_date($relative = false, $unix_date = null){ | |
if(empty($unix_date)){ | |
$unix_date = $this->timestamp; | |
} | |
$periods = array("second", "minute", "hour", "day", "week", "month", "year", "decade"); | |
$lengths = array("60","60","24","7","4.35","12","10"); | |
$now = time(); | |
// is it future date or past date | |
if($now > $unix_date) { | |
//past date | |
$difference = $now - $unix_date; | |
$tense = "ago"; | |
} else { | |
//future date | |
$difference = $unix_date - $now; | |
$tense = "from now"; | |
} | |
$formatted_date = "Incorrect format."; | |
$day_difference = $this->get_day_difference(); | |
//if difference is less than a day, check for yesterday, tomorrow, or today; | |
if($day_difference <= 1 && $day_difference >= -1){ | |
if($day_difference == 1){ | |
$formatted_date = "Yesterday"; | |
} | |
elseif($day_difference == 0){ | |
$formatted_date = "Today"; | |
} | |
else { | |
$formatted_date = "Tomorrow"; | |
} | |
} | |
elseif($relative) { | |
//difference is more than a day and the format should be "relative" | |
for($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) { | |
$difference /= $lengths[$j]; | |
} | |
$difference = round($difference); | |
if($difference != 1) { | |
$periods[$j].= "s"; | |
} | |
$formatted_date = "$difference $periods[$j] {$tense}"; | |
} | |
else { | |
//difference is more than a day and the format should NOT be "relative" | |
$formatted_date = $this->day_of_week; | |
} | |
return $formatted_date; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment