Twitter Feeds for a PHP Website - php

Can I ask how can I show my tweets in my website? Like the Twitter feeds thingie. I want to have a table where in it will just show my Twitter account's tweets. Thanks guys!

$xml = simplexml_load_file('http://twitter.com/statuses/user_timeline/{yourfeed}.rss');
// display each tweet
foreach ($xml->channel->item as $tweet)
{
echo $tweet->title . '<br />';
}
Tons of other solution which can be found just by simple google search.
Check this
http://jquery.malsup.com/twitter/
http://dev.twitter.com/pages/libraries#php

Twitter provides a javascript widget that you can copy and insert into your website. Is this what you're looking for http://twitter.com/about/resources/widgets/widget_profile ?

Post this php above the head of your html:
<?php
//Replace XXXXX with your twitter username
$twitterUsername = "XXXXX";
//Change number to amount of tweets you would like to display
$amountToShow = 5;
$twitterRssFeedUrl = 'https://api.twitter.com/1/statuses/user_timeline.rss?screen_name='.$twitterUsername.'&count='.$amountToShow;
$twitterPosts = false;
$xml = #simplexml_load_file($twitterRssFeedUrl);
if(is_object($xml)){
foreach($xml->channel->item as $twit){
if(is_array($twitterPosts) && count($twitterPosts)==$amountToShow){
break;
}
$d['title'] = stripslashes(htmlentities($twit->title,ENT_QUOTES,'UTF-8'));
$description = stripslashes(htmlentities($twit->description,ENT_QUOTES,'UTF-8'));
if(strtolower(substr($description,0,strlen($twitterUsername))) == strtolower($twitterUsername)){
$description = substr($description,strlen($twitterUsername)+1);
}
$d['description'] = $description;
$d['pubdate'] = strtotime($twit->pubDate);
$d['guid'] = stripslashes(htmlentities($twit->guid,ENT_QUOTES,'UTF-8'));
$d['link'] = stripslashes(htmlentities($twit->link,ENT_QUOTES,'UTF-8'));
$twitterPosts[]=$d;
}
}else{
die('Can`t fetch the feed you requested');
}
 
?>
Post this in the body of your html:
<ul>
<?php
if(is_array($twitterPosts)){
echo '';
foreach($twitterPosts as $post){
$data = $post['description'];
echo '<li>'.$data.'. ';
echo 'Posted '.date('F j, Y, g:i a',$post['pubdate']).'</li>';
}
echo '';
}else{
echo 'No Twitter posts have been made';//Error message
}
?>
</ul>

With a couple more functions you can add the relative time (ie "Yesterday" "2 weeks ago" etc) and convert urls and usernames into links.
Insert the code below into the top of your php file:
<?php
######################################
## DISPLAY TWITTER FEED
######################################
//Replace XXXXX with your twitter username
$twitterUsername = "XXXXX";
//Change number to amount of tweets you would like to display
$amountToShow = 5;
$twitterRssFeedUrl = 'https://api.twitter.com/1/statuses/user_timeline.rss?screen_name='.$twitterUsername.'&count='.$amountToShow;
$twitterPosts = false;
$xml = #simplexml_load_file($twitterRssFeedUrl);
if(is_object($xml)){
foreach($xml->channel->item as $twit){
if(is_array($twitterPosts) && count($twitterPosts)==$amountToShow){
break;
}
$d['title'] = stripslashes(htmlentities($twit->title,ENT_QUOTES,'UTF-8'));
$description = stripslashes(htmlentities($twit->description,ENT_QUOTES,'UTF-8'));
if(strtolower(substr($description,0,strlen($twitterUsername))) == strtolower($twitterUsername)){
$description = substr($description,strlen($twitterUsername)+1);
}
$d['description'] = $description;
$d['pubdate'] = strtotime($twit->pubDate);
$d['guid'] = stripslashes(htmlentities($twit->guid,ENT_QUOTES,'UTF-8'));
$d['link'] = stripslashes(htmlentities($twit->link,ENT_QUOTES,'UTF-8'));
$twitterPosts[]=$d;
}
}else{
die('Can`t fetch the feed you requested');
}
 
######################################
## REPLACE URLS AND USERS WITH LINKS
######################################
function hyperlinks($text) {
// Props to Allen Shaw & webmancers.com
// match protocol://address/path/file.extension?some=variable&another=asf%
//$text = preg_replace("/\b([a-zA-Z]+:\/\/[a-z][a-z0-9\_\.\-]*[a-z]{2,6}[a-zA-Z0-9\/\*\-\?\&\%]*)\b/i","$1", $text);
$text = preg_replace('/\b([a-zA-Z]+:\/\/[\w_.\-]+\.[a-zA-Z]{2,6}[\/\w\-~.?=&%#+$*!]*)\b/i',"$1", $text);
// match www.something.domain/path/file.extension?some=variable&another=asf%
//$text = preg_replace("/\b(www\.[a-z][a-z0-9\_\.\-]*[a-z]{2,6}[a-zA-Z0-9\/\*\-\?\&\%]*)\b/i","$1", $text);
$text = preg_replace('/\b(?<!:\/\/)(www\.[\w_.\-]+\.[a-zA-Z]{2,6}[\/\w\-~.?=&%#+$*!]*)\b/i',"$1", $text);
// match name#address
$text = preg_replace("/\b([a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]*\#[a-zA-Z][a-zA-Z0-9\_\.\-]*[a-zA-Z]{2,6})\b/i","$1", $text);
//mach #trendingtopics. Props to Michael Voigt
$text = preg_replace('/([\.|\,|\:|\¡|\¿|\>|\{|\(]?)#{1}(\w*)([\.|\,|\:|\!|\?|\>|\}|\)]?)\s/i', "$1#$2$3 ", $text);
return $text;
}
function twitter_users($text) {
$text = preg_replace('/([\.|\,|\:|\¡|\¿|\>|\{|\(]?)#{1}(\w*)([\.|\,|\:|\!|\?|\>|\}|\)]?)\s/i', "$1#$2$3 ", $text);
return $text;
}
######################################
## DISPLAY RELATIVE DATES
######################################
//props to Osman Üngür for this (http://goo.gl/FrEMp)
function time2str($ts)
{
if(!ctype_digit($ts))
$ts = strtotime($ts);
$diff = time() - $ts;
if($diff == 0)
return 'now';
elseif($diff > 0)
{
$day_diff = floor($diff / 86400);
if($day_diff == 0)
{
if($diff < 60) return 'just now';
if($diff < 120) return '1 minute ago';
if($diff < 3600) return floor($diff / 60) . ' minutes ago';
if($diff < 7200) return '1 hour ago';
if($diff < 86400) return floor($diff / 3600) . ' hours ago';
}
if($day_diff == 1) return 'Yesterday';
if($day_diff < 7) return $day_diff . ' days ago';
if($day_diff == 7) return '1 week ago';
if($day_diff < 31) return ceil($day_diff / 7) . ' weeks ago';
if($day_diff < 60) return 'last month';
return date('F Y', $ts);
}
else
{
$diff = abs($diff);
$day_diff = floor($diff / 86400);
if($day_diff == 0)
{
if($diff < 120) return 'in a minute';
if($diff < 3600) return 'in ' . floor($diff / 60) . ' minutes';
if($diff < 7200) return 'in an hour';
if($diff < 86400) return 'in ' . floor($diff / 3600) . ' hours';
}
if($day_diff == 1) return 'Tomorrow';
if($day_diff < 4) return date('l', $ts);
if($day_diff < 7 + (7 - date('w'))) return 'next week';
if(ceil($day_diff / 7) < 4) return 'in ' . ceil($day_diff / 7) . ' weeks';
if(date('n', $ts) == date('n') + 1) return 'next month';
return date('F Y', $ts);
}
}
?>
Then post the following code in the body of your html:
<ul>
<?php
if(is_array($twitterPosts)){
echo '';
foreach($twitterPosts as $post){
$data = hyperlinks($post['description']);
$data = twitter_users($data);
echo '<li>'.$data.'. ';
echo 'Posted '.time2str(date($post['pubdate'])).'</li>';
}
echo '';
}else{
echo 'No Twitter posts have been made';//Error message
}
?>
</ul>

Related

Convert timestamp to time and keep seconds, minutes and hour

I have a function to convert timestamp to real hour, minute and second, I would to keep the format like: hh:mm:ss even if it is only some minutes and seconds, I should get 00:10:32 instead of 10:32:
// format can be either : or blank
function toTime($timestamp, $format)
{
$hours = floor($timestamp / 3600);
$minutes = floor($timestamp % 3600 / 60);
$seconds = $timestamp % 60;
if($format == ':') {
$hourDuration = sprintf('%02d:', $hours);
//echo 'hour: '.$hourDuration.'<br />';
$minDuration = sprintf('%02d:', $minutes);
//echo 'min: '.$minDuration.'<br />';
$secDuration = sprintf('%02d', $seconds);
//echo 'sec: '.$secDuration.'<br />';
$HourMinSec = $hourDuration.$minDuration.$secDuration;
} else {
$hourDuration = sprintf('%02d h', $hours);
//echo 'hour: '.$hourDuration.'<br />';
$minDuration = sprintf('%02d m', $minutes);
//echo 'min: '.$minDuration.'<br />';
$secDuration = sprintf('%02d s', $seconds);
//echo 'sec: '.$secDuration.'<br />';
$HourMinSec = '';
}
if($hourDuration > 0){
$hourDuration = $hourDuration;
} else {
$hourDuration = '';
}
if($minDuration > 0){
$minDuration = $minDuration;
} else {
$minDuration = '';
}
if($secDuration > 0){
$secDuration = $secDuration;
} else {
$secDuration = '';
}
//$HourMinSec = $hourDuration.' '.$minDuration.' '.$secDuration;
$HourMinSec = $hourDuration.$minDuration.$secDuration;
return $HourMinSec;
}
This function is used to get a video timestamp like: 1508.7397460938, and I would like to sort out, how many hours, minutes and seconds are in that video
Thanks for your assistance
I would have done it that way
function toTime($timestamp, $format)
{
$hours = floor($timestamp / 3600);
$minutes = floor($timestamp % 3600 / 60);
$seconds = $timestamp % 60;
if($format == ':') {
$hourDuration = sprintf('%02d:', $hours);
//echo 'hour: '.$hourDuration.'<br />';
$minDuration = sprintf('%02d:', $minutes);
//echo 'min: '.$minDuration.'<br />';
$secDuration = sprintf('%02d', $seconds);
//echo 'sec: '.$secDuration.'<br />';
$HourMinSec = $hourDuration.$minDuration.$secDuration;
} else {
$hourDuration = sprintf('%02d h', $hours);
//echo 'hour: '.$hourDuration.'<br />';
$minDuration = sprintf('%02d m', $minutes);
//echo 'min: '.$minDuration.'<br />';
$secDuration = sprintf('%02d s', $seconds);
//echo 'sec: '.$secDuration.'<br />';
$HourMinSec = '';
}
if($hourDuration > 0){
$hourDuration = $hourDuration;
} else {
$hourDuration = ($format == ':' ? '00:' : '00 h');
}
if($minDuration > 0){
$minDuration = $minDuration;
} else {
$minDuration = ($format == ':' ? '00:' : '00 m');
}
if($secDuration > 0){
$secDuration = $secDuration;
} else {
$secDuration = '00';
}
//$HourMinSec = $hourDuration.' '.$minDuration.' '.$secDuration;
$HourMinSec = $hourDuration.$minDuration.$secDuration;
return $HourMinSec;
}
In that case it would bring you the following result for adding
echo toTime(1508.7397460938);
Output --> 00 h25 m08 s
echo toTime(1508.7397460938,':');
Output --> 00:25:08
The other variant is to use the php ready function gmdate by typing:
echo gmdate("H:i:s", 1508.7397460938);
// Use that only if the amount of hours is less than 24 , that function would now show more than 24 hours and if so it would show inaccurate data.

show time from mysql as soon as content is posted?

can anyone help please. i have this script which converts mysql timestamp from the horrible standard date and puts it in a user friendly way "about 2 seconds ago or about 1 hour ago".
my question is this. it works perfectly apart from, when a user posts content, the most recent content they post echos out " about 0 ago" not giving the time it was posted and it isnt until they post something else after this that they see the time on the one they posted before this.
so im wondering why this is because i cant figure it out, i preferabley want it to say "added just now" as soon as the users posted it, and then carry on as the script says saying added 20 seconds ago, 2 minutes ago etc.
an example is;
(content 1) "posted about 0 ago"
(content 2) "posted about 8 minute ago"
(content 3) "posted about 5 hours ago"
then content 1 will only every update the time when another piece of content is posted else it wont.
so content 1 should say posted just now, then after a few seconds, post about 5 seconds ago, 1 minute ago, 5 hours ago, 7 days ago etc.
<div class="board-wall-feeds">
<div class="social_header">
<?php echo "$profile[2]" ?>'s News & Updates:
</div>
<?php
$timeline_set = get_timeline();
while ($news = mysql_fetch_array($timeline_set)) {
echo "
<div class=\"news_feeds_board_text\">{$news['content']}
<div class=\"social_footer\">about ".$t.$labels[$i]." ago</div></div>";
$datetime1 = new DateTime();
$datetime2 = new DateTime ($news['date_added']);
$interval = $datetime1->diff($datetime2);
$mdhms = explode('-',$interval->format('%m-%d-%H-%i-%s'));
$labels = Array(' months', ' days', ' hours', ' minutes', ' seconds');
$i = 0;
foreach($mdhms as $t){
if($t > 0) break;
$i+=1;
}
} ?>
</div>
You can try relative time function for this here it is
function relativetime($ts)
{
$diff = time() - $ts;
if($diff == 0)
return 'now';
elseif($diff > 0)
{
$day_diff = floor($diff / 86400);
if($day_diff == 0)
{
if($diff < 60) return 'just now';
if($diff < 120) return '1 minute ago';
if($diff < 3600) return floor($diff / 60) . ' minutes ago';
if($diff < 7200) return '1 hour ago';
if($diff < 86400) return floor($diff / 3600) . ' hours ago';
}
if($day_diff == 1) return 'Yesterday';
if($day_diff < 7) return $day_diff . ' days ago';
if($day_diff < 31) return ceil($day_diff / 7) . ' weeks ago';
if($day_diff < 60) return 'last month';
return date('F Y', $ts);
}
else
{
$diff = abs($diff);
$day_diff = floor($diff / 86400);
if($day_diff == 0)
{
if($diff < 120) return 'in a minute';
if($diff < 3600) return 'in ' . floor($diff / 60) . ' minutes';
if($diff < 7200) return 'in an hour';
if($diff < 86400) return 'in ' . floor($diff / 3600) . ' hours';
}
if($day_diff == 1) return 'Tomorrow';
if($day_diff < 4) return date('l', $ts);
if($day_diff < 7 + (7 - date('w'))) return 'next week';
if(ceil($day_diff / 7) < 4) return 'in ' . ceil($day_diff / 7) . ' weeks';
if(date('n', $ts) == date('n') + 1) return 'next month';
return date('F Y', $ts);
}
}
In this function you have to pass time as $ts, converted by strtotime function.
Can be possible duplicate of PHP: producing relative date/time from timestamps

Show x time ago if time is less than 24 hour ago

I use Codeigniter and it has the timespan() function that returns the time as 1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes.
What I'd like to do is only show the time formatted in x hours ago if the time is within the last 24 hours, otherwise just show a normal datetime.
I feel like there's got to be a function already made to do this but I haven't had any luck finding it.
This is the timespan function included with Codeigniter, how can I alter it?
/**
* Timespan
*
* Returns a span of seconds in this format:
* 10 days 14 hours 36 minutes 47 seconds
*
* #access public
* #param integer a number of seconds
* #param integer Unix timestamp
* #return integer
*/
if ( ! function_exists('timespan'))
{
function timespan($seconds = 1, $time = '')
{
$CI =& get_instance();
$CI->lang->load('date');
if ( ! is_numeric($seconds))
{
$seconds = 1;
}
if ( ! is_numeric($time))
{
$time = time();
}
if ($time <= $seconds)
{
$seconds = 1;
}
else
{
$seconds = $time - $seconds;
}
$str = '';
$years = floor($seconds / 31536000);
if ($years > 0)
{
$str .= $years.' '.$CI->lang->line((($years > 1) ? 'date_years' : 'date_year')).', ';
}
$seconds -= $years * 31536000;
$months = floor($seconds / 2628000);
if ($years > 0 OR $months > 0)
{
if ($months > 0)
{
$str .= $months.' '.$CI->lang->line((($months > 1) ? 'date_months' : 'date_month')).', ';
}
$seconds -= $months * 2628000;
}
$weeks = floor($seconds / 604800);
if ($years > 0 OR $months > 0 OR $weeks > 0)
{
if ($weeks > 0)
{
$str .= $weeks.' '.$CI->lang->line((($weeks > 1) ? 'date_weeks' : 'date_week')).', ';
}
$seconds -= $weeks * 604800;
}
$days = floor($seconds / 86400);
if ($months > 0 OR $weeks > 0 OR $days > 0)
{
if ($days > 0)
{
$str .= $days.' '.$CI->lang->line((($days > 1) ? 'date_days' : 'date_day')).', ';
}
$seconds -= $days * 86400;
}
$hours = floor($seconds / 3600);
if ($days > 0 OR $hours > 0)
{
if ($hours > 0)
{
$str .= $hours.' '.$CI->lang->line((($hours > 1) ? 'date_hours' : 'date_hour')).', ';
}
$seconds -= $hours * 3600;
}
$minutes = floor($seconds / 60);
if ($days > 0 OR $hours > 0 OR $minutes > 0)
{
if ($minutes > 0)
{
$str .= $minutes.' '.$CI->lang->line((($minutes > 1) ? 'date_minutes' : 'date_minute')).', ';
}
$seconds -= $minutes * 60;
}
if ($str == '')
{
$str .= $seconds.' '.$CI->lang->line((($seconds > 1) ? 'date_seconds' : 'date_second')).', ';
}
return substr(trim($str), 0, -1);
}
}
This function will accept a string, a numeric (unix) timestamp, or a DateTime object. It also accepts jQuery.now(). Time may be in the future or past.
function time_ago($time=false, $just_now=false) {
if ($time instanceOf DateTime)
$time = $time->getTimestamp();
elseif (is_numeric($time))
$time = date('m/d/y h:i A', $time);
if (strtotime($time) === false)
$time = date('m/d/y h:i A', time());
$interval = date_create($time)->diff(date_create('now'));
$adjective = strtotime($time) > time() ? 'from now' : 'ago';
return (
$interval->days > 0 ?
$time : (
$interval->h < 1 && $interval->i < 1 && $just_now ?
'just now' :
(
$interval->h > 1 ?
$interval->h.' hour'.(
$interval->h > 1 ?
's' :
''
).' ago' :
$interval->i.' minutes'.' '.$adjective
)
)
);
}
echo time_ago('8/22/2012 5:00 PM'); // 3 hours ago
echo time_ago('8/21/2012 5:00 PM'); // 8/21/2012 5:00 PM
echo time_ago(time()); // 0 hours ago
echo time_ago(time(), true); // just now
echo time_ago(strtotime('5 days ago')); // 08/17/12 08:18 PM
echo time_ago(strtotime('5 hours ago')); // 5 hours ago
echo time_ago(strtotime('5 minutes ago')); // 5 minutes ago
echo time_ago(strtotime('+5 minutes')); // 5 minutes from now
echo time_ago('jQuery.now()', true); // just now
echo time_ago('sweet explosions, bro!', true); // just now
Documentation
date - http://php.net/manual/en/function.date.php
DateTime object - http://www.php.net/manual/en/book.datetime.php
DateInterval object - http://www.php.net/manual/en/class.dateinterval.php
is_numeric - http://php.net/manual/en/function.is-numeric.php
if( time() - $yourTime <= 86400 ) { // 86400 seconds in a day
echo timespan($yourTime);
} else {
echo date('m/d/Y \a\t H:i:s', $yourTime);
}
Don't rely on a framework, especially a bad one, for everything!
Fiddle with $format to suit your needs. Will accept almost anything as input.
<?php
/**
* RelativeTime - pretty printed
* #author Dejan Marjanovic
*/
class Site5_RelativeTime
{
private $interval = '';
public function __construct()
{
call_user_func_array(array($this, 'calculate'), func_get_args());
}
public function calculate($start, $end = NULL)
{
if ( empty($start))
return false;
if (empty($end))
$end = time();
if ( ! is_numeric($start))
$start = strtotime($start);
if ( ! is_numeric($end))
$end = strtotime($end);
if($start > $end)
$future = TRUE;
$start = '#' . $start;
$end = '#' . $end;
if ( ! ($start instanceof DateTime))
$start = new DateTime($start);
if ($end === null)
$end = new DateTime();
if ( ! ($end instanceof DateTime))
$end = new DateTime($end);
$interval = $end->diff($start);
$get_plural = function($int, $str)
{
return $int > 1? $str.'s': $str;
};
$format = array();
if ($interval->y !== 0)
$format[] = "%y " . $get_plural($interval->y, "year");
if ($interval->m !== 0)
$format[] = "%m " . $get_plural($interval->m, "month");
if ($interval->d !== 0)
$format[] = "%d " . $get_plural($interval->d, "day");
if ($interval->h !== 0)
$format[] = "%h " . $get_plural($interval->h, "hour");
if ($interval->i !== 0)
$format[] = "%i " . $get_plural($interval->i, "minute");
if ($interval->s !== 0)
{
if ( ! count($format))
{
$this->interval = "less than a minute";
return;
}
else
{
$format[] = "%s " . $get_plural($interval->s, "second");
}
}
if (count($format) > 1)
{
$format = array_shift($format) . " and " . array_shift($format);
}
else
{
$format = array_pop($format);
}
$tense = ($future === TRUE)? 'from now': 'ago';
$this->interval = $interval->format($format) . ' ' . $tense;
}
public function __toString()
{
return $this->interval;
}
}

codeigniter timespan function

Hello i have now search the hole web and found a lot but i just dont know how to make it to work so now im asking here for help
i want to do so then a person create a comment it should said "created 1 sec. ago" and then 1 min and 1 hour and like that :)
can some one help me with that ?
thanks
This is basically human readable format, and can be completed by mathematical checks to check the distance of times, working snippet below:
function RelativeTime($timestamp)
{
$difference = time() - $timestamp;
$periods = array("sec", "min", "hour", "day", "week", "month", "years", "decade");
$lengths = array("60","60","24","7","4.35","12","10");
if ($difference > 0)
{
$ending = "ago";
}
else
{
$difference = -$difference;
$ending = "to go";
}
for($j = 0; $difference >= $lengths[$j]; $j++)
{
$difference /= $lengths[$j];
}
$difference = round($difference);
if($difference != 1)
{
$periods[$j].= "s";
}
return $difference . $periods[$j] . $ending;
}
This will do future timestamps such as 12 days to go aswell as timestamps such as 12 days ago
Hope this helps.
Original Source: http://blog.evandavey.com/2008/04/php-date-in-human-readable-form-facebook-style.html
I think this is exactly what you want. When you using the function set $deep parameter to 1.
function timespan($seconds = 1, $time = '', $deep = NULL)
{
$CI = & get_instance();
$CI->lang->load('date');
$current_deep = 0;
if (!is_numeric($seconds))
{
$seconds = 1;
}
if (!is_numeric($time))
{
$time = time();
}
if ($time <= $seconds)
{
$seconds = 1;
}
else
{
$seconds = $time - $seconds;
}
$str = '';
$years = floor($seconds / 31536000);
if ($years > 0)
{
$str .= $years . ' ' . $CI->lang->line((($years > 1) ? 'date_years' : 'date_year')) . ', ';
if (++$current_deep == $deep)
return substr(trim($str), 0, -1);
}
$seconds -= $years * 31536000;
$months = floor($seconds / 2628000);
if ($years > 0 OR $months > 0)
{
if ($months > 0)
{
$str .= $months . ' ' . $CI->lang->line((($months > 1) ? 'date_months' : 'date_month')) . ', ';
if (++$current_deep == $deep)
return substr(trim($str), 0, -1);
}
$seconds -= $months * 2628000;
}
$weeks = floor($seconds / 604800);
if ($years > 0 OR $months > 0 OR $weeks > 0)
{
if ($weeks > 0)
{
$str .= $weeks . ' ' . $CI->lang->line((($weeks > 1) ? 'date_weeks' : 'date_week')) . ', ';
if (++$current_deep == $deep)
return substr(trim($str), 0, -1);
}
$seconds -= $weeks * 604800;
}
$days = floor($seconds / 86400);
if ($months > 0 OR $weeks > 0 OR $days > 0)
{
if ($days > 0)
{
$str .= $days . ' ' . $CI->lang->line((($days > 1) ? 'date_days' : 'date_day')) . ', ';
if (++$current_deep == $deep)
return substr(trim($str), 0, -1);
}
$seconds -= $days * 86400;
}
$hours = floor($seconds / 3600);
if ($days > 0 OR $hours > 0)
{
if ($hours > 0)
{
$str .= $hours . ' ' . $CI->lang->line((($hours > 1) ? 'date_hours' : 'date_hour')) . ', ';
if (++$current_deep == $deep)
return substr(trim($str), 0, -1);
}
$seconds -= $hours * 3600;
}
$minutes = floor($seconds / 60);
if ($days > 0 OR $hours > 0 OR $minutes > 0)
{
if ($minutes > 0)
{
$str .= $minutes . ' ' . $CI->lang->line((($minutes > 1) ? 'date_minutes' : 'date_minute')) . ', ';
if (++$current_deep == $deep)
return substr(trim($str), 0, -1);
}
$seconds -= $minutes * 60;
}
if ($str == '')
{
$str .= $seconds . ' ' . $CI->lang->line((($seconds > 1) ? 'date_seconds' : 'date_second')) . ', ';
}
return substr(trim($str), 0, -1);
}
Source
Assuming you have the difference $now - $creation_time in seconds, a way to do it is to divide it by X seconds (1 minute = 60, 1 hour = 3600, 1 day = 86400) starting with the largest number to see how many of those units fit in your creation time, then use its remainder to try and fit the smaller units in.
$diffSeconds = time() - $creation_time ;
$numDays = $diffSeconds / 86400 ;
$remainderDaySeconds = $diffSeconds % 86400 ;
$numHours = $remainderDaySeconds / 3600 ;
$remainderSeconds = $remainderDaySeconds % 3600 ;
The modulo operator % will give you the remainder of a division. This way, if a post was created less than a day ago then $numDays is 0 and $remainderDaySeconds is $diffSeconds, so you can check and print out accordingly.
Edit I got curious and looked in SO, turns out there are quite a few questions expanding on this. Linking some:
Calculate relative time in C#
calculating and showing a date as 'secs ago', 'mins ago', 'hours ago' etc which points to http://www.php.net/manual/en/function.time.php#89415

PHP: producing relative date/time from timestamps

I'm basically trying to convert a Unix timestamp (the time() function) to a relative date/time that's both compatible with past and future date. So outputs could be:
2 weeks ago
1 hour and 60 minutes ago
15 minutes and 54 seconds ago
after 10 minutes and 15 seconds
First I tried to code this, but made a huge unmaintainable function, and then I searched the internet for a couple of hours, yet all I can find are scripts that produce only one part of the time (e.h: "1 hour ago" without the minutes).
Do you have a script that already does this?
This function gives you "1 hour ago" or "Tomorrow" like results between 'now' and 'specific timestamp'.
function time2str($ts)
{
if(!ctype_digit($ts))
$ts = strtotime($ts);
$diff = time() - $ts;
if($diff == 0)
return 'now';
elseif($diff > 0)
{
$day_diff = floor($diff / 86400);
if($day_diff == 0)
{
if($diff < 60) return 'just now';
if($diff < 120) return '1 minute ago';
if($diff < 3600) return floor($diff / 60) . ' minutes ago';
if($diff < 7200) return '1 hour ago';
if($diff < 86400) return floor($diff / 3600) . ' hours ago';
}
if($day_diff == 1) return 'Yesterday';
if($day_diff < 7) return $day_diff . ' days ago';
if($day_diff < 31) return ceil($day_diff / 7) . ' weeks ago';
if($day_diff < 60) return 'last month';
return date('F Y', $ts);
}
else
{
$diff = abs($diff);
$day_diff = floor($diff / 86400);
if($day_diff == 0)
{
if($diff < 120) return 'in a minute';
if($diff < 3600) return 'in ' . floor($diff / 60) . ' minutes';
if($diff < 7200) return 'in an hour';
if($diff < 86400) return 'in ' . floor($diff / 3600) . ' hours';
}
if($day_diff == 1) return 'Tomorrow';
if($day_diff < 4) return date('l', $ts);
if($day_diff < 7 + (7 - date('w'))) return 'next week';
if(ceil($day_diff / 7) < 4) return 'in ' . ceil($day_diff / 7) . ' weeks';
if(date('n', $ts) == date('n') + 1) return 'next month';
return date('F Y', $ts);
}
}
function relativeTime($time) {
$d[0] = array(1,"second");
$d[1] = array(60,"minute");
$d[2] = array(3600,"hour");
$d[3] = array(86400,"day");
$d[4] = array(604800,"week");
$d[5] = array(2592000,"month");
$d[6] = array(31104000,"year");
$w = array();
$return = "";
$now = time();
$diff = ($now-$time);
$secondsLeft = $diff;
for($i=6;$i>-1;$i--)
{
$w[$i] = intval($secondsLeft/$d[$i][0]);
$secondsLeft -= ($w[$i]*$d[$i][0]);
if($w[$i]!=0)
{
$return.= abs($w[$i]) . " " . $d[$i][1] . (($w[$i]>1)?'s':'') ." ";
}
}
$return .= ($diff>0)?"ago":"left";
return $return;
}
Usage:
echo relativeTime((time()-256));
4 minutes 16 seconds ago
Here is what I've written. Displays a past date relative to today's date.
/**
* #param $date integer of unixtimestamp format, not actual date type
* #return string
*/
function zdateRelative($date)
{
$now = time();
$diff = $now - $date;
if ($diff < 60){
return sprintf($diff > 1 ? '%s seconds ago' : 'a second ago', $diff);
}
$diff = floor($diff/60);
if ($diff < 60){
return sprintf($diff > 1 ? '%s minutes ago' : 'one minute ago', $diff);
}
$diff = floor($diff/60);
if ($diff < 24){
return sprintf($diff > 1 ? '%s hours ago' : 'an hour ago', $diff);
}
$diff = floor($diff/24);
if ($diff < 7){
return sprintf($diff > 1 ? '%s days ago' : 'yesterday', $diff);
}
if ($diff < 30)
{
$diff = floor($diff / 7);
return sprintf($diff > 1 ? '%s weeks ago' : 'one week ago', $diff);
}
$diff = floor($diff/30);
if ($diff < 12){
return sprintf($diff > 1 ? '%s months ago' : 'last month', $diff);
}
$diff = date('Y', $now) - date('Y', $date);
return sprintf($diff > 1 ? '%s years ago' : 'last year', $diff);
}
I love the relativeTime function by xdebug. Problem is I needed it to have some granularity.
In other words stop at seconds or minutes if I decide.
So now,
echo fTime(strtotime('-23 hours 5 minutes 55 seconds'),0);
would show,
23 hours, 5 minutes ago
Instead of
23 hours, 5 minutes, 55 seconds ago
I also wanted it to NOT go lower in the array if it reached one of the higher time amounts.
So if it shows years, I only want to show years and months.
So now,
echo fTime(strtotime('-1 year 2 months 3 weeks 4 days 16 hours 15 minutes 22 seconds'),0);
Would show
1 year, 2 months ago
Instead of
1 year, 2 months, 3 weeks, 4 days, 16 hours, 15 minutes, 22 seconds ago
The following code change did what I needed. Props go to xdebug first of course.
Hopefully someone else might find it useful:
function fTime($time, $gran=-1) {
$d[0] = array(1,"second");
$d[1] = array(60,"minute");
$d[2] = array(3600,"hour");
$d[3] = array(86400,"day");
$d[4] = array(604800,"week");
$d[5] = array(2592000,"month");
$d[6] = array(31104000,"year");
$w = array();
$return = "";
$now = time();
$diff = ($now-$time);
$secondsLeft = $diff;
$stopat = 0;
for($i=6;$i>$gran;$i--)
{
$w[$i] = intval($secondsLeft/$d[$i][0]);
$secondsLeft -= ($w[$i]*$d[$i][0]);
if($w[$i]!=0)
{
$return.= abs($w[$i]) . " " . $d[$i][1] . (($w[$i]>1)?'s':'') ." ";
switch ($i) {
case 6: // shows years and months
if ($stopat==0) { $stopat=5; }
break;
case 5: // shows months and weeks
if ($stopat==0) { $stopat=4; }
break;
case 4: // shows weeks and days
if ($stopat==0) { $stopat=3; }
break;
case 3: // shows days and hours
if ($stopat==0) { $stopat=2; }
break;
case 2: // shows hours and minutes
if ($stopat==0) { $stopat=1; }
break;
case 1: // shows minutes and seconds if granularity is not set higher
break;
}
if ($i===$stopat) { break 0; }
}
}
$return .= ($diff>0)?"ago":"left";
return $return;
}
Marcus
Here is what I use for past times:
function zdateRelative($date)
{
$diff = time() - $date;
$periods[] = [60, 1, '%s seconds ago', 'a second ago'];
$periods[] = [60*100, 60, '%s minutes ago', 'one minute ago'];
$periods[] = [3600*70, 3600, '%s hours ago', 'an hour ago'];
$periods[] = [3600*24*10, 3600*24, '%s days ago', 'yesterday'];
$periods[] = [3600*24*30, 3600*24*7, '%s weeks ago', 'one week ago'];
$periods[] = [3600*24*30*30, 3600*24*30, '%s months ago', 'last month'];
$periods[] = [INF, 3600*24*265, '%s years ago', 'last year'];
foreach ($periods as $period) {
if ($diff > $period[0]) continue;
$diff = floor($diff / $period[1]);
return sprintf($diff > 1 ? $period[2] : $period[3], $diff);
}
}
I needed one to give me results as below, so I wrote my own. Hopefully, this will help somebody.
Example usage:
$datetime = "2014-08-13 12:52:48";
echo getRelativeTime($datetime); //10 hours ago
echo getRelativeTime($datetime, 1); //10 hours ago
echo getRelativeTime($datetime, 2); //10 hours and 50 minutes ago
echo getRelativeTime($datetime, 3); //10 hours, 50 minutes and 50 seconds ago
echo getRelativeTime($datetime, 4); //10 hours, 50 minutes and 50 seconds ago
Code:
public function getRelativeTime($datetime, $depth=1) {
$units = array(
"year"=>31104000,
"month"=>2592000,
"week"=>604800,
"day"=>86400,
"hour"=>3600,
"minute"=>60,
"second"=>1
);
$plural = "s";
$conjugator = " and ";
$separator = ", ";
$suffix1 = " ago";
$suffix2 = " left";
$now = "now";
$empty = "";
# DO NOT EDIT BELOW
$timediff = time()-strtotime($datetime);
if ($timediff == 0) return $now;
if ($depth < 1) return $empty;
$max_depth = count($units);
$remainder = abs($timediff);
$output = "";
$count_depth = 0;
$fix_depth = true;
foreach ($units as $unit=>$value) {
if ($remainder>$value && $depth-->0) {
if ($fix_depth) {
$max_depth -= ++$count_depth;
if ($depth>=$max_depth) $depth=$max_depth;
$fix_depth = false;
}
$u = (int)($remainder/$value);
$remainder %= $value;
$pluralise = $u>1?$plural:$empty;
$separate = $remainder==0||$depth==0?$empty:
($depth==1?$conjugator:$separator);
$output .= "{$u} {$unit}{$pluralise}{$separate}";
}
$count_depth++;
}
return $output.($timediff<0?$suffix2:$suffix1);
}
You can use Carbon via packagist, just amazing :)
https://github.com/briannesbitt/Carbon#api-humandiff
PHP 8.0.0 now has a pretty weak implementation of relative dates via IntlDateFormatter::format with the addition of the IntlDateFormatter::RELATIVE_* constants.
This likely isn't super useful at the time of writing as it only outputs the strings "yesterday", "today", and "tomorrow"... It then falls back to the full/long/medium/short dates for anything outside of those bounds.
The big drawcard for this is that it's fully internationalized; so using other locales such as de_DE, ko_KR, or pa_IN will give you translated strings in the relevant scripts... It could be worth the compromise.
$formatter = new IntlDateFormatter(
'en_US',
IntlDateFormatter::RELATIVE_FULL,
IntlDateFormatter::NONE,
'America/Los_Angeles',
IntlDateFormatter::GREGORIAN
);
echo $formatter->format( time() - 86400 );
echo $formatter->format( time() );
echo $formatter->format( time() + 86400 );
It's also possible that readers from the future will be using newer version of PHP that have more comprehensive relative time formats too.
Why not rip off the way that drupal does it - http://api.drupal.org/api/drupal/includes%21common.inc/function/format_interval/7
<?php
function format_interval($interval, $granularity = 2, $langcode = NULL) {
$units = array(
'1 year|#count years' => 31536000,
'1 month|#count months' => 2592000,
'1 week|#count weeks' => 604800,
'1 day|#count days' => 86400,
'1 hour|#count hours' => 3600,
'1 min|#count min' => 60,
'1 sec|#count sec' => 1,
);
$output = '';
foreach ($units as $key => $value) {
$key = explode('|', $key);
if ($interval >= $value) {
$output .= ($output ? ' ' : '') . format_plural(floor($interval / $value), $key[0], $key[1], array(), array('langcode' => $langcode));
$interval %= $value;
$granularity--;
}
if ($granularity == 0) {
break;
}
}
return $output ? $output : t('0 sec', array(), array('langcode' => $langcode));
}
?>
You probably don't need a replacement for t() and you could do your own thing for format_plural pretty easily as you (probably) don't have to support multiple languages. http://api.drupal.org/api/drupal/includes%21common.inc/function/format_plural/7
Should be easy enough to adapt to different formats. This simple function only works with timestamps in the past.
// return relative date/time string from timestamp
// [n yrs] [n mos] [n days] h:i:s
function relative_time(int $time): string
{
$dt = new DateTime();
$dt->setTimestamp($time);
$diff = (new DateTime())->diff($dt);
$s = "";
if ($diff->y) $s .= " {$diff->y} " . (($diff->y > 1) ? "yrs" : "yr");
if ($diff->m) $s .= " {$diff->m} " . (($diff->m > 1) ? "mos" : "mo");
if ($diff->d) $s .= " {$diff->d} " . (($diff->d > 1) ? "days" : "day");
$s .= sprintf(" %02d:%02d:%02d", $diff->h, $diff->i, $diff->s);
return trim($s);
}

Categories