问题
I would like to display a time format like twitter and FB (Posted 3 hours ago, Posted 2 minutes ago and so on...)
I've tried this piece of code without success :
function format_interval($timestamp, $granularity = 2) {
$units = array('1 year|@count years' => 31536000, '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 ($timestamp >= $value) {
$floor = floor($timestamp / $value);
$output .= ($output ? ' ' : '') . ($floor == 1 ? $key[0] : str_replace('@count', $floor, $key[1]));
$timestamp %= $value;
$granularity--;
}
if ($granularity == 0) {
break;
}
}
I use this function with a callback into another function like : $this->format_interval(); and pass it to my View
My current format date is : 2012-07-26 09:31:pm and already stored in my DB
Any help will be very appreciated!
回答1:
The Date Helper's timespan()
method just does that:
The most common purpose for this function is to show how much time has elapsed from some point in time in the past to now.
Given a timestamp, it will show how much time has elapsed in this format:
1 Year, 10 Months, 2 Weeks, 5 Days, 10 Hours, 16 Minutes
So, in your example, all you need to do is convert your date to a timestamp and do something like this:
$post_date = '13436714242';
$now = time();
// will echo "2 hours ago" (at the time of this post)
echo timespan($post_date, $now) . ' ago';
回答2:
Try something like this in a my_date_helper.php
file (source: Codeigniter Forums):
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if( ! function_exists('relative_time'))
{
function relative_time($datetime)
{
$CI =& get_instance();
$CI->lang->load('date');
if(!is_numeric($datetime))
{
$val = explode(" ",$datetime);
$date = explode("-",$val[0]);
$time = explode(":",$val[1]);
$datetime = mktime($time[0],$time[1],$time[2],$date[1],$date[2],$date[0]);
}
$difference = time() - $datetime;
$periods = array("second", "minute", "hour", "day", "week", "month", "year", "decade");
$lengths = array("60","60","24","7","4.35","12","10");
if ($difference > 0)
{
$ending = $CI->lang->line('date_ago');
}
else
{
$difference = -$difference;
$ending = $CI->lang->line('date_to_go');
}
for($j = 0; $difference >= $lengths[$j]; $j++)
{
$difference /= $lengths[$j];
}
$difference = round($difference);
if($difference != 1)
{
$period = strtolower($CI->lang->line('date_'.$periods[$j].'s'));
} else {
$period = strtolower($CI->lang->line('date_'.$periods[$j]));
}
return "$difference $period $ending";
}
}
The format is a little different than the one you're using in your database (why do you mark times with pm/am rather than just use 24 hour times and convert for the frontend?). Either way, shouldn't take much work to get it working.
回答3:
I had a function that solved this like this:
$int_diff = (time() - $int_time);
$str_this_year = date('Y-01-01', $int_time);
$str_weekday = t('time_weekday_'.strtolower(date('l', $int_time)));
$str_month = t('time_month_'.strtolower(date('F', $int_time)));
$arr_time_formats = array( '-90 seconds' => t('time_a_minute_at_most'),
'-45 minutes' => t('time_minutes_ago', ceil($int_diff / (60))),
'-70 minutes' => t('time_an_hour_at_most'),
'-8 hours' => t('time_hours_ago', ceil($int_diff / (60 * 60))),
'today' => t('time_hours_ago', ceil($int_diff / (60 * 60))),
'yesterday' => t('time_yesterday', date('H:i', $int_time)),
'-4 days' => t('time_week_ago', $str_weekday, date('H:i', $int_time)),
$str_this_year => t('time_date', date('j', $int_time), $str_month, date('H:i', $int_time)),
0 => t('time_date_year', date('j', $int_time), $str_month, date('Y', $int_time), date('H:i', $int_time)));
if ($boo_whole)
return $arr_time_formats[0];
foreach(array_keys($arr_time_formats) as $h)
if ($int_time >= strtotime($h))
return $arr_time_formats[$h];
Basicly t()
is a function combined with $this->lang->line()
and sprintf()
. The idea here is to give keys that's runned through strtotime()
till you reach the closest time, with 0
being the fallback.
This approach is really good since you can easy adjust the times with a nice overview. I could give more piece of the code, but it feels like doing too much of the work :) Basicly this is just the theory behind how you can do it.
回答4:
<?php
$this->load->helper('date');
//client created date get from database
$date=$client_list->created_date;
// Declare timestamps
$last = new DateTime($date);
$now = new DateTime( date( 'Y-m-d h:i:s', time() )) ;
// Find difference
$interval = $last->diff($now);
// Store in variable to be used for calculation etc
$years = (int)$interval->format('%Y');
$months = (int)$interval->format('%m');
$days = (int)$interval->format('%d');
$hours = (int)$interval->format('%H');
$minutes = (int)$interval->format('%i');
// $now = date('Y-m-d H:i:s');
if($years > 0)
{
echo $years.' Years '.$months.' Months '.$days.' Days '. $hours.' Hours '.$minutes.' minutes ago.' ;
}
else if($months > 0)
{
echo $months.' Months '.$days.' Days '. $hours.' Hours '.$minutes.' minutes ago.' ;
}
else if($days > 0)
{
echo $days.' Days '.$hours.' Hours '.$minutes.' minutes ago.' ;
}
else if($hours > 0)
{
echo $hours.' Hours '.$minutes.' minutes ago.' ;
}
else
{
echo $minutes.' minutes ago.' ;
}
?>
来源:https://stackoverflow.com/questions/11728438/display-time-ago-instead-of-datetime-in-php-codeigniter