在 PHP 中将时间戳转换为时间前,例如 1 天前,2 天前...
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1416697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting timestamp to time ago in PHP e.g 1 day ago, 2 days ago...
提问by willdanceforfun
I am trying to convert a timestamp of the format 2009-09-12 20:57:19and turn it into something like 3 minutes agowith PHP.
我正在尝试转换格式的时间戳2009-09-12 20:57:19并将其转换为类似3 minutes agoPHP的格式。
I found a useful script to do this, but I think it's looking for a different format to be used as the time variable. The script I'm wanting to modify to work with this format is:
我找到了一个有用的脚本来做到这一点,但我认为它正在寻找一种不同的格式来用作时间变量。我要修改以使用此格式的脚本是:
function _ago($tm,$rcs = 0) {
$cur_tm = time();
$dif = $cur_tm-$tm;
$pds = array('second','minute','hour','day','week','month','year','decade');
$lngh = array(1,60,3600,86400,604800,2630880,31570560,315705600);
for($v = sizeof($lngh)-1; ($v >= 0)&&(($no = $dif/$lngh[$v])<=1); $v--); if($v < 0) $v = 0; $_tm = $cur_tm-($dif%$lngh[$v]);
$no = floor($no);
if($no <> 1)
$pds[$v] .='s';
$x = sprintf("%d %s ",$no,$pds[$v]);
if(($rcs == 1)&&($v >= 1)&&(($cur_tm-$_tm) > 0))
$x .= time_ago($_tm);
return $x;
}
I think on those first few lines the script is trying to do something that looks like this (different date format math):
我认为在前几行脚本试图做一些看起来像这样的事情(不同的日期格式数学):
$dif = 1252809479 - 2009-09-12 20:57:19;
How would I go about converting my timestamp into that (unix?) format?
我将如何将我的时间戳转换为(unix?)格式?
回答by Glavi?
Use example :
使用示例:
echo time_elapsed_string('2013-05-01 00:22:35');
echo time_elapsed_string('@1367367755'); # timestamp input
echo time_elapsed_string('2013-05-01 00:22:35', true);
Input can be any supported date and time format.
输入可以是任何支持的日期和时间格式。
Output :
输出 :
4 months ago
4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago
Function :
功能 :
function time_elapsed_string($datetime, $full = false) {
$now = new DateTime;
$ago = new DateTime($datetime);
$diff = $now->diff($ago);
$diff->w = floor($diff->d / 7);
$diff->d -= $diff->w * 7;
$string = array(
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
foreach ($string as $k => &$v) {
if ($diff->$k) {
$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
} else {
unset($string[$k]);
}
}
if (!$full) $string = array_slice($string, 0, 1);
return $string ? implode(', ', $string) . ' ago' : 'just now';
}
回答by Ayman Hussein
function time_elapsed_string($ptime)
{
$etime = time() - $ptime;
if ($etime < 1)
{
return '0 seconds';
}
$a = array( 365 * 24 * 60 * 60 => 'year',
30 * 24 * 60 * 60 => 'month',
24 * 60 * 60 => 'day',
60 * 60 => 'hour',
60 => 'minute',
1 => 'second'
);
$a_plural = array( 'year' => 'years',
'month' => 'months',
'day' => 'days',
'hour' => 'hours',
'minute' => 'minutes',
'second' => 'seconds'
);
foreach ($a as $secs => $str)
{
$d = $etime / $secs;
if ($d >= 1)
{
$r = round($d);
return $r . ' ' . ($r > 1 ? $a_plural[$str] : $str) . ' ago';
}
}
}
回答by Captain Red
$time_elapsed = timeAgo($time_ago); //The argument $time_ago is in timestamp (Y-m-d H:i:s)format.
//Function definition
function timeAgo($time_ago)
{
$time_ago = strtotime($time_ago);
$cur_time = time();
$time_elapsed = $cur_time - $time_ago;
$seconds = $time_elapsed ;
$minutes = round($time_elapsed / 60 );
$hours = round($time_elapsed / 3600);
$days = round($time_elapsed / 86400 );
$weeks = round($time_elapsed / 604800);
$months = round($time_elapsed / 2600640 );
$years = round($time_elapsed / 31207680 );
// Seconds
if($seconds <= 60){
return "just now";
}
//Minutes
else if($minutes <=60){
if($minutes==1){
return "one minute ago";
}
else{
return "$minutes minutes ago";
}
}
//Hours
else if($hours <=24){
if($hours==1){
return "an hour ago";
}else{
return "$hours hrs ago";
}
}
//Days
else if($days <= 7){
if($days==1){
return "yesterday";
}else{
return "$days days ago";
}
}
//Weeks
else if($weeks <= 4.3){
if($weeks==1){
return "a week ago";
}else{
return "$weeks weeks ago";
}
}
//Months
else if($months <=12){
if($months==1){
return "a month ago";
}else{
return "$months months ago";
}
}
//Years
else{
if($years==1){
return "one year ago";
}else{
return "$years years ago";
}
}
}
回答by Panama Hyman
This is actually a better solution I've found. Uses jQuery however it works perfectly. Also it refreshes automaticallysimilar to the way SO and Facebook does so you don't have to refresh the page to see the updates.
这实际上是我找到的更好的解决方案。使用 jQuery 但它工作得很好。此外,它会以类似于 SO 和 Facebook 的方式自动刷新,因此您无需刷新页面即可查看更新。
This plugin will read your datetimeattr in the <time>tag and fill it in for you.
这个插件会datetime在<time>标签中读取你的属性并为你填写。
e.g. "4 minutes ago" or "about 1 day ago
回答by Krzysztof Duszczyk
I don't know why nobody mention Carbon yet.
我不知道为什么还没有人提到碳。
https://github.com/briannesbitt/Carbon
https://github.com/briannesbitt/Carbon
This is actually an extension to php dateTime (which was already used here) and it has: diffForHumans method. So all you need to do is:
这实际上是 php dateTime 的扩展(这里已经使用过),它有: diffForHumans 方法。所以你需要做的就是:
$dt = Carbon::parse('2012-9-5 23:26:11.123789');
echo $dt->diffForHumans();
more examples: http://carbon.nesbot.com/docs/#api-humandiff
更多示例:http: //carbon.nesbot.com/docs/#api-humandiff
Pros of this solution:
该解决方案的优点:
- it works for future dates and will return something like in 2 months etc.
- you can use localization to get other languages and the pluralization works fine
- if you will start using Carbon for other things working with dates will be as easy as never.
- 它适用于未来的日期,并会在 2 个月后返回等。
- 您可以使用本地化来获取其他语言,并且复数化工作正常
- 如果您将开始使用 Carbon 处理其他与日期相关的事情,将会变得前所未有的简单。
回答by mgutt
I found results like the following ugly:
我发现如下丑陋的结果:
1 years, 2 months, 0 days, 0 hours, 53 minutes and 1 seconds
1年2个月0天0小时53分1秒
Because of that I realized a function that respects plurals, removes empty values and optionally it is possible to shorten the output:
因此,我实现了一个尊重复数的函数,删除空值,并且可以选择缩短输出:
function since($timestamp, $level=6) {
global $lang;
$date = new DateTime();
$date->setTimestamp($timestamp);
$date = $date->diff(new DateTime());
// build array
$since = array_combine(array('year', 'month', 'day', 'hour', 'minute', 'second'), explode(',', $date->format('%y,%m,%d,%h,%i,%s')));
// remove empty date values
$since = array_filter($since);
// output only the first x date values
$since = array_slice($since, 0, $level);
// build string
$last_key = key(array_slice($since, -1, 1, true));
$string = '';
foreach ($since as $key => $val) {
// separator
if ($string) {
$string .= $key != $last_key ? ', ' : ' ' . $lang['and'] . ' ';
}
// set plural
$key .= $val > 1 ? 's' : '';
// add date value
$string .= $val . ' ' . $lang[ $key ];
}
return $string;
}
Looks much better:
看起来好多了:
1 year, 2 months, 53 minutes and 1 second
1年2个月53分1秒
Optionally use $level = 2to shorten it as follows:
可选地使用$level = 2缩短它如下:
1 year and 2 months
1年2个月
Remove the $langpart if you need it only in English or edit this translation to fit your needs:
$lang如果您只需要英文版,请删除该部分或编辑此翻译以满足您的需要:
$lang = array(
'second' => 'Sekunde',
'seconds' => 'Sekunden',
'minute' => 'Minute',
'minutes' => 'Minuten',
'hour' => 'Stunde',
'hours' => 'Stunden',
'day' => 'Tag',
'days' => 'Tage',
'month' => 'Monat',
'months' => 'Monate',
'year' => 'Jahr',
'years' => 'Jahre',
'and' => 'und',
);
回答by brycejl
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':'');
}
}
echo humanTiming( strtotime($mytimestring) );
回答by Bobb Fwed
I modified the original function a bit to be (in my opinion more useful, or logical).
我稍微修改了原始函数(在我看来更有用,或更合乎逻辑)。
// display "X time" ago, $rcs is precision depth
function time_ago ($tm, $rcs = 0) {
$cur_tm = time();
$dif = $cur_tm - $tm;
$pds = array('second','minute','hour','day','week','month','year','decade');
$lngh = array(1,60,3600,86400,604800,2630880,31570560,315705600);
for ($v = count($lngh) - 1; ($v >= 0) && (($no = $dif / $lngh[$v]) <= 1); $v--);
if ($v < 0)
$v = 0;
$_tm = $cur_tm - ($dif % $lngh[$v]);
$no = ($rcs ? floor($no) : round($no)); // if last denomination, round
if ($no != 1)
$pds[$v] .= 's';
$x = $no . ' ' . $pds[$v];
if (($rcs > 0) && ($v >= 1))
$x .= ' ' . $this->time_ago($_tm, $rcs - 1);
return $x;
}
回答by Ahmad ghoneim
i made this and it's working just fine it's working for both unix timestamp like 1470919932or formatted time like 16-08-11 14:53:30
我做了这个,它工作得很好,它适用于类似 unix 时间戳1470919932或类似格式化的时间16-08-11 14:53:30
function timeAgo($time_ago) {
$time_ago = strtotime($time_ago) ? strtotime($time_ago) : $time_ago;
$time = time() - $time_ago;
switch($time):
// seconds
case $time <= 60;
return 'lessthan a minute ago';
// minutes
case $time >= 60 && $time < 3600;
return (round($time/60) == 1) ? 'a minute' : round($time/60).' minutes ago';
// hours
case $time >= 3600 && $time < 86400;
return (round($time/3600) == 1) ? 'a hour ago' : round($time/3600).' hours ago';
// days
case $time >= 86400 && $time < 604800;
return (round($time/86400) == 1) ? 'a day ago' : round($time/86400).' days ago';
// weeks
case $time >= 604800 && $time < 2600640;
return (round($time/604800) == 1) ? 'a week ago' : round($time/604800).' weeks ago';
// months
case $time >= 2600640 && $time < 31207680;
return (round($time/2600640) == 1) ? 'a month ago' : round($time/2600640).' months ago';
// years
case $time >= 31207680;
return (round($time/31207680) == 1) ? 'a year ago' : round($time/31207680).' years ago' ;
endswitch;
}
?>
回答by TMH
Just to throw in another option...
只是为了提供另一种选择......
Whilst I prefer the DateTime method posting here, I didn't like the fact it displayed 0 years etc.
虽然我更喜欢在这里发布的 DateTime 方法,但我不喜欢它显示 0 年等的事实。
/*
* Returns a string stating how long ago this happened
*/
private function timeElapsedString($ptime){
$diff = time() - $ptime;
$calc_times = array();
$timeleft = array();
// Prepare array, depending on the output we want to get.
$calc_times[] = array('Year', 'Years', 31557600);
$calc_times[] = array('Month', 'Months', 2592000);
$calc_times[] = array('Day', 'Days', 86400);
$calc_times[] = array('Hour', 'Hours', 3600);
$calc_times[] = array('Minute', 'Minutes', 60);
$calc_times[] = array('Second', 'Seconds', 1);
foreach ($calc_times AS $timedata){
list($time_sing, $time_plur, $offset) = $timedata;
if ($diff >= $offset){
$left = floor($diff / $offset);
$diff -= ($left * $offset);
$timeleft[] = "{$left} " . ($left == 1 ? $time_sing : $time_plur);
}
}
return $timeleft ? (time() > $ptime ? null : '-') . implode(' ', $timeleft) : 0;
}

