如何找到自2010-04-28 17:25:43
之类的日期时间戳以来经过的时间,最终输出文字应该像xx Minutes Ago
/ xx Days Ago
答案 0 :(得分:225)
大多数答案似乎都集中在将日期从字符串转换为时间。看起来你大部分时间都在考虑将日期纳入“5天前”格式等等。对吗?
这就是我要这样做的方式:
$time = strtotime('2010-04-28 17:25:43');
echo 'event happened '.humanTiming($time).' ago';
function humanTiming ($time)
{
$time = time() - $time; // to get the time since that moment
$time = ($time<1)? 1 : $time;
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
我没有测试过,但它应该有效。
结果看起来像
event happened 4 days ago
或
event happened 1 minute ago
欢呼声
答案 1 :(得分:16)
想要分享php功能,这会导致语法正确的Facebook,如人类可读的时间格式。
示例:
echo get_time_ago(strtotime('now'));
结果:
不到1分钟前
function get_time_ago($time_stamp)
{
$time_difference = strtotime('now') - $time_stamp;
if ($time_difference >= 60 * 60 * 24 * 365.242199)
{
/*
* 60 seconds/minute * 60 minutes/hour * 24 hours/day * 365.242199 days/year
* This means that the time difference is 1 year or more
*/
return get_time_ago_string($time_stamp, 60 * 60 * 24 * 365.242199, 'year');
}
elseif ($time_difference >= 60 * 60 * 24 * 30.4368499)
{
/*
* 60 seconds/minute * 60 minutes/hour * 24 hours/day * 30.4368499 days/month
* This means that the time difference is 1 month or more
*/
return get_time_ago_string($time_stamp, 60 * 60 * 24 * 30.4368499, 'month');
}
elseif ($time_difference >= 60 * 60 * 24 * 7)
{
/*
* 60 seconds/minute * 60 minutes/hour * 24 hours/day * 7 days/week
* This means that the time difference is 1 week or more
*/
return get_time_ago_string($time_stamp, 60 * 60 * 24 * 7, 'week');
}
elseif ($time_difference >= 60 * 60 * 24)
{
/*
* 60 seconds/minute * 60 minutes/hour * 24 hours/day
* This means that the time difference is 1 day or more
*/
return get_time_ago_string($time_stamp, 60 * 60 * 24, 'day');
}
elseif ($time_difference >= 60 * 60)
{
/*
* 60 seconds/minute * 60 minutes/hour
* This means that the time difference is 1 hour or more
*/
return get_time_ago_string($time_stamp, 60 * 60, 'hour');
}
else
{
/*
* 60 seconds/minute
* This means that the time difference is a matter of minutes
*/
return get_time_ago_string($time_stamp, 60, 'minute');
}
}
function get_time_ago_string($time_stamp, $divisor, $time_unit)
{
$time_difference = strtotime("now") - $time_stamp;
$time_units = floor($time_difference / $divisor);
settype($time_units, 'string');
if ($time_units === '0')
{
return 'less than 1 ' . $time_unit . ' ago';
}
elseif ($time_units === '1')
{
return '1 ' . $time_unit . ' ago';
}
else
{
/*
* More than "1" $time_unit. This is the "plural" message.
*/
// TODO: This pluralizes the time unit, which is done by adding "s" at the end; this will not work for i18n!
return $time_units . ' ' . $time_unit . 's ago';
}
}
答案 2 :(得分:8)
我认为我有一个应该做你想做的功能:
function time2string($timeline) {
$periods = array('day' => 86400, 'hour' => 3600, 'minute' => 60, 'second' => 1);
foreach($periods AS $name => $seconds){
$num = floor($timeline / $seconds);
$timeline -= ($num * $seconds);
$ret .= $num.' '.$name.(($num > 1) ? 's' : '').' ';
}
return trim($ret);
}
只需将其应用于time()
和strtotime('2010-04-28 17:25:43')
之间的差异即可:
print time2string(time()-strtotime('2010-04-28 17:25:43')).' ago';
答案 3 :(得分:3)
如果你使用php Datetime类,你可以使用:
function time_ago(Datetime $date) {
$time_ago = '';
$diff = $date->diff(new Datetime('now'));
if (($t = $diff->format("%m")) > 0)
$time_ago = $t . ' months';
else if (($t = $diff->format("%d")) > 0)
$time_ago = $t . ' days';
else if (($t = $diff->format("%H")) > 0)
$time_ago = $t . ' hours';
else
$time_ago = 'minutes';
return $time_ago . ' ago (' . $date->format('M j, Y') . ')';
}
答案 4 :(得分:3)
请注意,大多数数学计算的示例都有2038-01-18
个日期的严格限制,并且不适用于虚构日期。
由于缺少基于DateTime
和DateInterval
的示例,我想提供一个满足OP需求的多功能功能,以及其他想要复合经过时间的功能,例如{{1} }。与一堆其他用例一起,例如显示日期而不是经过时间的限制,或过滤掉经过时间结果的部分。
此外,大多数示例假设已经过了当前时间,其中下面的函数允许用期望的结束日期覆盖它。
1 month 2 days ago
有一点需要注意 - 提供的过滤器值的检索间隔不会延续到下一个周期。过滤器仅显示所提供期间的结果值,并且不会重新计算期间以仅显示所需的过滤器总数。
<强>用法强>
OP需要显示最高时期(截至2015-02-24)。
/**
* multi-purpose function to calculate the time elapsed between $start and optional $end
* @param string|null $start the date string to start calculation
* @param string|null $end the date string to end calculation
* @param string $suffix the suffix string to include in the calculated string
* @param string $format the format of the resulting date if limit is reached or no periods were found
* @param string $separator the separator between periods to use when filter is not true
* @param null|string $limit date string to stop calculations on and display the date if reached - ex: 1 month
* @param bool|array $filter false to display all periods, true to display first period matching the minimum, or array of periods to display ['year', 'month']
* @param int $minimum the minimum value needed to include a period
* @return string
*/
function elapsedTimeString($start, $end = null, $limit = null, $filter = true, $suffix = 'ago', $format = 'Y-m-d', $separator = ' ', $minimum = 1)
{
$dates = (object) array(
'start' => new DateTime($start ? : 'now'),
'end' => new DateTime($end ? : 'now'),
'intervals' => array('y' => 'year', 'm' => 'month', 'd' => 'day', 'h' => 'hour', 'i' => 'minute', 's' => 'second'),
'periods' => array()
);
$elapsed = (object) array(
'interval' => $dates->start->diff($dates->end),
'unknown' => 'unknown'
);
if ($elapsed->interval->invert === 1) {
return trim('0 seconds ' . $suffix);
}
if (false === empty($limit)) {
$dates->limit = new DateTime($limit);
if (date_create()->add($elapsed->interval) > $dates->limit) {
return $dates->start->format($format) ? : $elapsed->unknown;
}
}
if (true === is_array($filter)) {
$dates->intervals = array_intersect($dates->intervals, $filter);
$filter = false;
}
foreach ($dates->intervals as $period => $name) {
$value = $elapsed->interval->$period;
if ($value >= $minimum) {
$dates->periods[] = vsprintf('%1$s %2$s%3$s', array($value, $name, ($value !== 1 ? 's' : '')));
if (true === $filter) {
break;
}
}
}
if (false === empty($dates->periods)) {
return trim(vsprintf('%1$s %2$s', array(implode($separator, $dates->periods), $suffix)));
}
return $dates->start->format($format) ? : $elapsed->unknown;
}
显示复合句点并提供自定义结束日期(请注意缺少时间和虚构日期)。
echo elapsedTimeString('2010-04-26');
/** 4 years ago */
显示过滤期的结果(数组排序无关紧要)。
echo elapsedTimeString('1920-01-01', '2500-02-24', null, false);
/** 580 years 1 month 23 days ago */
如果达到限制,以所提供的格式显示开始日期(默认为Y-m-d)。
echo elapsedTimeString('2010-05-26', '2012-02-24', null, ['month', 'year']);
/** 1 year 8 months ago */
还有很多其他用例。它也可以很容易地适用于接受开始,结束或限制参数的unix时间戳和/或DateInterval对象。
答案 5 :(得分:2)
我喜欢Mithun的代码,但我稍微调整了一下,以便给出更合理的答案。
function getTimeSince($eventTime)
{
$totaldelay = time() - strtotime($eventTime);
if($totaldelay <= 0)
{
return '';
}
else
{
$first = '';
$marker = 0;
if($years=floor($totaldelay/31536000))
{
$totaldelay = $totaldelay % 31536000;
$plural = '';
if ($years > 1) $plural='s';
$interval = $years." year".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$marker = 1;
$first = ", ";
}
if($months=floor($totaldelay/2628000))
{
$totaldelay = $totaldelay % 2628000;
$plural = '';
if ($months > 1) $plural='s';
$interval = $months." month".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$marker = 1;
$first = ", ";
}
if($days=floor($totaldelay/86400))
{
$totaldelay = $totaldelay % 86400;
$plural = '';
if ($days > 1) $plural='s';
$interval = $days." day".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$marker = 1;
$first = ", ";
}
if ($marker) return $timesince;
if($hours=floor($totaldelay/3600))
{
$totaldelay = $totaldelay % 3600;
$plural = '';
if ($hours > 1) $plural='s';
$interval = $hours." hour".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$marker = 1;
$first = ", ";
}
if($minutes=floor($totaldelay/60))
{
$totaldelay = $totaldelay % 60;
$plural = '';
if ($minutes > 1) $plural='s';
$interval = $minutes." minute".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$first = ", ";
}
if($seconds=floor($totaldelay/1))
{
$totaldelay = $totaldelay % 1;
$plural = '';
if ($seconds > 1) $plural='s';
$interval = $seconds." second".$plural;
$timesince = $timesince.$first.$interval;
}
return $timesince;
}
}
答案 6 :(得分:2)
为了改进@arnorhs的答案我已经增加了获得更精确结果的能力,所以如果你想要年,月,日和时间。例如,自用户加入以来的小时数。
我添加了一个新参数,以便您指定要返回的精确点数。
function get_friendly_time_ago($distant_timestamp, $max_units = 3) {
$i = 0;
$time = time() - $distant_timestamp; // to get the time since that moment
$tokens = [
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
];
$responses = [];
while ($i < $max_units && $time > 0) {
foreach ($tokens as $unit => $text) {
if ($time < $unit) {
continue;
}
$i++;
$numberOfUnits = floor($time / $unit);
$responses[] = $numberOfUnits . ' ' . $text . (($numberOfUnits > 1) ? 's' : '');
$time -= ($unit * $numberOfUnits);
break;
}
}
if (!empty($responses)) {
return implode(', ', $responses) . ' ago';
}
return 'Just now';
}
答案 7 :(得分:1)
尝试其中一个回购:
https://github.com/salavert/time-ago-in-words
https://github.com/jimmiw/php-time-ago
我刚刚开始使用后者,诀窍,但是当相关日期太远时,没有stackoverflow风格的回退确切日期,也没有对未来日期的支持 - 而且API有点时髦,但是至少它看起来完美无瑕并且得以维持...
答案 8 :(得分:1)
可以与任何版本的PHP一起使用的一个选项是执行已经建议的内容,如下所示:
$eventTime = '2010-04-28 17:25:43';
$age = time() - strtotime($eventTime);
这会给你几秒钟的年龄。从那里,您可以随意显示它。
然而,这种方法的一个问题是它不会考虑DST引起的时间偏移。如果这不是一个问题,那就去吧。否则,您可能想要使用diff() method in the DateTime class。不幸的是,如果你至少使用PHP 5.3,这只是一个选项。
答案 9 :(得分:1)
使用这个,你可以得到
$previousDate = '2013-7-26 17:01:10';
$startdate = new DateTime($previousDate);
$endDate = new DateTime('now');
$interval = $endDate->diff($startdate);
echo$interval->format('%y years, %m months, %d days');
答案 10 :(得分:0)
这里我使用自定义函数来查找自日期时间以来经过的时间。
echo Datetodays('2013-7-26 17:01:10'); function Datetodays($d) { $date_start = $d; $date_end = date('Y-m-d H:i:s'); define('SECOND', 1); define('MINUTE', SECOND * 60); define('HOUR', MINUTE * 60); define('DAY', HOUR * 24); define('WEEK', DAY * 7); $t1 = strtotime($date_start); $t2 = strtotime($date_end); if ($t1 > $t2) { $diffrence = $t1 - $t2; } else { $diffrence = $t2 - $t1; } //echo "
".$date_end." ".$date_start." ".$diffrence; $results['major'] = array(); // whole number representing larger number in date time relationship $results1 = array(); $string = ''; $results['major']['weeks'] = floor($diffrence / WEEK); $results['major']['days'] = floor($diffrence / DAY); $results['major']['hours'] = floor($diffrence / HOUR); $results['major']['minutes'] = floor($diffrence / MINUTE); $results['major']['seconds'] = floor($diffrence / SECOND); //print_r($results); // Logic: // Step 1: Take the major result and transform it into raw seconds (it will be less the number of seconds of the difference) // ex: $result = ($results['major']['weeks']*WEEK) // Step 2: Subtract smaller number (the result) from the difference (total time) // ex: $minor_result = $difference - $result // Step 3: Take the resulting time in seconds and convert it to the minor format // ex: floor($minor_result/DAY) $results1['weeks'] = floor($diffrence / WEEK); $results1['days'] = floor((($diffrence - ($results['major']['weeks'] * WEEK)) / DAY)); $results1['hours'] = floor((($diffrence - ($results['major']['days'] * DAY)) / HOUR)); $results1['minutes'] = floor((($diffrence - ($results['major']['hours'] * HOUR)) / MINUTE)); $results1['seconds'] = floor((($diffrence - ($results['major']['minutes'] * MINUTE)) / SECOND)); //print_r($results1); if ($results1['weeks'] != 0 && $results1['days'] == 0) { if ($results1['weeks'] == 1) { $string = $results1['weeks'] . ' week ago'; } else { if ($results1['weeks'] == 2) { $string = $results1['weeks'] . ' weeks ago'; } else { $string = '2 weeks ago'; } } } elseif ($results1['weeks'] != 0 && $results1['days'] != 0) { if ($results1['weeks'] == 1) { $string = $results1['weeks'] . ' week ago'; } else { if ($results1['weeks'] == 2) { $string = $results1['weeks'] . ' weeks ago'; } else { $string = '2 weeks ago'; } } } elseif ($results1['weeks'] == 0 && $results1['days'] != 0) { if ($results1['days'] == 1) { $string = $results1['days'] . ' day ago'; } else { $string = $results1['days'] . ' days ago'; } } elseif ($results1['days'] != 0 && $results1['hours'] != 0) { $string = $results1['days'] . ' day and ' . $results1['hours'] . ' hours ago'; } elseif ($results1['days'] == 0 && $results1['hours'] != 0) { if ($results1['hours'] == 1) { $string = $results1['hours'] . ' hour ago'; } else { $string = $results1['hours'] . ' hours ago'; } } elseif ($results1['hours'] != 0 && $results1['minutes'] != 0) { $string = $results1['hours'] . ' hour and ' . $results1['minutes'] . ' minutes ago'; } elseif ($results1['hours'] == 0 && $results1['minutes'] != 0) { if ($results1['minutes'] == 1) { $string = $results1['minutes'] . ' minute ago'; } else { $string = $results1['minutes'] . ' minutes ago'; } } elseif ($results1['minutes'] != 0 && $results1['seconds'] != 0) { $string = $results1['minutes'] . ' minute and ' . $results1['seconds'] . ' seconds ago'; } elseif ($results1['minutes'] == 0 && $results1['seconds'] != 0) { if ($results1['seconds'] == 1) { $string = $results1['seconds'] . ' second ago'; } else { $string = $results1['seconds'] . ' seconds ago'; } } return $string; } ?>
答案 11 :(得分:0)
最近不得不这样做 - 希望这有助于某人。它并不能满足每种可能性,但满足了我对项目的需求。
https://github.com/duncanheron/twitter_date_format
https://github.com/duncanheron/twitter_date_format/blob/master/twitter_date_format.php
答案 12 :(得分:0)
arnorhs对“humanTiming”功能的即兴创作。它将计算时间字符串到人类可读文本版本的“完全拉伸”转换。比如说它像“1周2天1小时28分14秒”
function humantime ($oldtime, $newtime = null, $returnarray = false) {
if(!$newtime) $newtime = time();
$time = $newtime - $oldtime; // to get the time since that moment
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
$htarray = array();
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
$htarray[$text] = $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
$time = $time - ( $unit * $numberOfUnits );
}
if($returnarray) return $htarray;
return implode(' ', $htarray);
}
答案 13 :(得分:0)
你可以直接从WordPress核心文件中获取一个函数来看看这里
http://core.trac.wordpress.org/browser/tags/3.6/wp-includes/formatting.php#L2121
function human_time_diff( $from, $to = '' ) {
if ( empty( $to ) )
$to = time();
$diff = (int) abs( $to - $from );
if ( $diff < HOUR_IN_SECONDS ) {
$mins = round( $diff / MINUTE_IN_SECONDS );
if ( $mins <= 1 )
$mins = 1;
/* translators: min=minute */
$since = sprintf( _n( '%s min', '%s mins', $mins ), $mins );
} elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) {
$hours = round( $diff / HOUR_IN_SECONDS );
if ( $hours <= 1 )
$hours = 1;
$since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours );
} elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) {
$days = round( $diff / DAY_IN_SECONDS );
if ( $days <= 1 )
$days = 1;
$since = sprintf( _n( '%s day', '%s days', $days ), $days );
} elseif ( $diff < 30 * DAY_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) {
$weeks = round( $diff / WEEK_IN_SECONDS );
if ( $weeks <= 1 )
$weeks = 1;
$since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks );
} elseif ( $diff < YEAR_IN_SECONDS && $diff >= 30 * DAY_IN_SECONDS ) {
$months = round( $diff / ( 30 * DAY_IN_SECONDS ) );
if ( $months <= 1 )
$months = 1;
$since = sprintf( _n( '%s month', '%s months', $months ), $months );
} elseif ( $diff >= YEAR_IN_SECONDS ) {
$years = round( $diff / YEAR_IN_SECONDS );
if ( $years <= 1 )
$years = 1;
$since = sprintf( _n( '%s year', '%s years', $years ), $years );
}
return $since;
}
答案 14 :(得分:0)
要查找已用时间,我通常使用time()
代替date()
和格式化的时间戳。
然后得到后一个值和早期值之间的差异并相应地格式化。 time()
不同于date()
的替代品,但在计算经过时间时完全有帮助。
示例:
time()
的值看起来像这样1274467343
每秒递增一次。因此,您可以$erlierTime
的值为1274467343
,$latterTime
的值为1274467500
,然后只需$latterTime - $erlierTime
即可获得时间,以秒为单位。
答案 15 :(得分:0)
写了我自己的
function getElapsedTime($eventTime)
{
$totaldelay = time() - strtotime($eventTime);
if($totaldelay <= 0)
{
return '';
}
else
{
if($days=floor($totaldelay/86400))
{
$totaldelay = $totaldelay % 86400;
return $days.' days ago.';
}
if($hours=floor($totaldelay/3600))
{
$totaldelay = $totaldelay % 3600;
return $hours.' hours ago.';
}
if($minutes=floor($totaldelay/60))
{
$totaldelay = $totaldelay % 60;
return $minutes.' minutes ago.';
}
if($seconds=floor($totaldelay/1))
{
$totaldelay = $totaldelay % 1;
return $seconds.' seconds ago.';
}
}
}
答案 16 :(得分:0)
将[saved_date]转换为时间戳。获取当前时间戳。
当前时间戳 - [saved_date]时间戳。
然后你可以用date();
格式化它您通常可以使用strtotime()函数将大多数日期格式转换为时间戳。