在PHP中转换时间戳到时间之前,例如1天前,2天前…

我试图转换格式2009-09-12 20:57:19的时间戳,并将其转换为类似3 minutes ago的PHP。

我找到了一个有用的脚本来做这件事,但我认为它正在寻找一种不同的格式来用作时间变量。我想修改的脚本与此格式的工作是:

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;
}

我认为在前几行脚本试图做的事情看起来像这样(不同的日期格式数学):

$dif = 1252809479 - 2009-09-12 20:57:19;

如何将我的时间戳转换成那种(unix?)格式?

311293 次浏览

您必须将时间戳的每一部分都转换为Unix时间。例如时间戳:2009-09-12 20:57:19。

((2008-1970)*365)+(8*30)+12)*24+20可以大致估算出自1970年1月1日以来的工作时间。

用这个数字乘以60,再加57,就得到了分钟数。

用这个,乘以60,再加19。

这将非常粗略和不准确地转换它。

有什么原因让你不能开始使用正常的Unix时间吗?

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';
}
}
}

我修改了原来的函数一点(在我看来更有用,或更符合逻辑)。

// 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;
}

举个例子:

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);

输入可以是任意支持日期和时间格式

输出:

4 months ago
4 months ago
4 months, 2 weeks, 3 days, 1 hour, 49 minutes, 15 seconds ago

功能:

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';
}

这其实是我找到的一个更好的解决方案。使用jQuery,但它的工作完美。此外,它自动刷新类似于SO和Facebook的方式,所以你不必刷新页面来查看更新。

这个插件会读取你在<time>标签中的datetime attr,并为你填写它。

e.g. "4 minutes ago" or "about 1 day ago

http://timeago.yarp.com/

$time_ago = ' ';
$time = time() - $time; // to get the time since that moment
$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);
$time_ago = ' '.$time_ago. $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'').'  ';
$time = $time % $unit;}echo $time_ago;

只需将日期时间传递给这个func。它会按照之前的格式打印出来

date_default_timezone_set('your-time-zone');
function convert($datetime){
$time=strtotime($datetime);
$diff=time()-$time;
$diff/=60;
$var1=floor($diff);
$var=$var1<=1 ? 'min' : 'mins';
if($diff>=60){
$diff/=60;
$var1=floor($diff);
$var=$var1<=1 ? 'hr' : 'hrs';
if($diff>=24){$diff/=24;$var1=floor($diff);$var=$var1<=1 ? 'day' : 'days';
if($diff>=30.4375){$diff/=30.4375;$var1=floor($diff);$var=$var1<=1 ? 'month' : 'months';
if($diff>=12){$diff/=12;$var1=floor($diff);$var=$var1<=1 ? 'year' : 'years';}}}}
echo $var1,' ',$var,' ago';
}

下面是一个非常简单和非常有效的解决方案。

function timeElapsed($originalTime){


$timeElapsed=time()-$originalTime;


/*
You can change the values of the following 2 variables
based on your opinion. For 100% accuracy, you can call
php's cal_days_in_month() and do some additional coding
using the values you get for each month. After all the
coding, your final answer will be approximately equal to
mine. That is why it is okay to simply use the average
values below.
*/
$averageNumbDaysPerMonth=(365.242/12);
$averageNumbWeeksPerMonth=($averageNumbDaysPerMonth/7);


$time1=(((($timeElapsed/60)/60)/24)/365.242);
$time2=floor($time1);//Years
$time3=($time1-$time2)*(365.242);
$time4=($time3/$averageNumbDaysPerMonth);
$time5=floor($time4);//Months
$time6=($time4-$time5)*$averageNumbWeeksPerMonth;
$time7=floor($time6);//Weeks
$time8=($time6-$time7)*7;
$time9=floor($time8);//Days
$time10=($time8-$time9)*24;
$time11=floor($time10);//Hours
$time12=($time10-$time11)*60;
$time13=floor($time12);//Minutes
$time14=($time12-$time13)*60;
$time15=round($time14);//Seconds


$timeElapsed=$time2 . 'yrs ' . $time5 . 'months ' . $time7 .
'weeks ' . $time9 .  'days ' . $time11 . 'hrs '
. $time13 . 'mins and ' . $time15 . 'secs.';


return $timeElapsed;


}

回声timeElapsed (1201570814);

样例输出:

6年4个月3周4天12小时40分36秒。

下面是我不久前构建的通知模块的解决方案。它返回的输出类似于Facebook的通知下拉列表(例如。1天前,刚才,等等)。

public function getTimeDifference($time) {
//Let's set the current time
$currentTime = date('Y-m-d H:i:s');
$toTime = strtotime($currentTime);


//And the time the notification was set
$fromTime = strtotime($time);


//Now calc the difference between the two
$timeDiff = floor(abs($toTime - $fromTime) / 60);


//Now we need find out whether or not the time difference needs to be in
//minutes, hours, or days
if ($timeDiff < 2) {
$timeDiff = "Just now";
} elseif ($timeDiff > 2 && $timeDiff < 60) {
$timeDiff = floor(abs($timeDiff)) . " minutes ago";
} elseif ($timeDiff > 60 && $timeDiff < 120) {
$timeDiff = floor(abs($timeDiff / 60)) . " hour ago";
} elseif ($timeDiff < 1440) {
$timeDiff = floor(abs($timeDiff / 60)) . " hours ago";
} elseif ($timeDiff > 1440 && $timeDiff < 2880) {
$timeDiff = floor(abs($timeDiff / 1440)) . " day ago";
} elseif ($timeDiff > 2880) {
$timeDiff = floor(abs($timeDiff / 1440)) . " days ago";
}


return $timeDiff;
}
$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";
}
}
}

这是我的解决方案,请检查并根据您的要求修改

function getHowLongAgo($date, $display = array('Year', 'Month', 'Day', 'Hour', 'Minute', 'Second'), $ago = '') {
date_default_timezone_set('Australia/Sydney');
$timestamp = strtotime($date);
$timestamp = (int) $timestamp;
$current_time = time();
$diff = $current_time - $timestamp;


//intervals in seconds
$intervals = array(
'year' => 31556926, 'month' => 2629744, 'week' => 604800, 'day' => 86400, 'hour' => 3600, 'minute' => 60
);


//now we just find the difference
if ($diff == 0) {
return ' Just now ';
}


if ($diff < 60) {
return $diff == 1 ? $diff . ' second ago ' : $diff . ' seconds ago ';
}


if ($diff >= 60 && $diff < $intervals['hour']) {
$diff = floor($diff / $intervals['minute']);
return $diff == 1 ? $diff . ' minute ago ' : $diff . ' minutes ago ';
}


if ($diff >= $intervals['hour'] && $diff < $intervals['day']) {
$diff = floor($diff / $intervals['hour']);
return $diff == 1 ? $diff . ' hour ago ' : $diff . ' hours ago ';
}


if ($diff >= $intervals['day'] && $diff < $intervals['week']) {
$diff = floor($diff / $intervals['day']);
return $diff == 1 ? $diff . ' day ago ' : $diff . ' days ago ';
}


if ($diff >= $intervals['week'] && $diff < $intervals['month']) {
$diff = floor($diff / $intervals['week']);
return $diff == 1 ? $diff . ' week ago ' : $diff . ' weeks ago ';
}


if ($diff >= $intervals['month'] && $diff < $intervals['year']) {
$diff = floor($diff / $intervals['month']);
return $diff == 1 ? $diff . ' month ago ' : $diff . ' months ago ';
}


if ($diff >= $intervals['year']) {
$diff = floor($diff / $intervals['year']);
return $diff == 1 ? $diff . ' year ago ' : $diff . ' years ago ';
}
}

谢谢

# This function prints the difference between two php datetime objects
# in a more human readable form
# inputs should be like strtotime($date)
function humanizeDateDiffference($now,$otherDate=null,$offset=null){
if($otherDate != null){
$offset = $now - $otherDate;
}
if($offset != null){
$deltaS = $offset%60;
$offset /= 60;
$deltaM = $offset%60;
$offset /= 60;
$deltaH = $offset%24;
$offset /= 24;
$deltaD = ($offset > 1)?ceil($offset):$offset;
} else{
throw new Exception("Must supply otherdate or offset (from now)");
}
if($deltaD > 1){
if($deltaD > 365){
$years = ceil($deltaD/365);
if($years ==1){
return "last year";
} else{
return "<br>$years years ago";
}
}
if($deltaD > 6){
return date('d-M',strtotime("$deltaD days ago"));
}
return "$deltaD days ago";
}
if($deltaD == 1){
return "Yesterday";
}
if($deltaH == 1){
return "last hour";
}
if($deltaM == 1){
return "last minute";
}
if($deltaH > 0){
return $deltaH." hours ago";
}
if($deltaM > 0){
return $deltaM." minutes ago";
}
else{
return "few seconds ago";
}
}

此函数不是为英语语言而设计的。我把这些单词翻译成英语。在用于英语之前,这需要更多的修正。

function ago($d) {
$ts = time() - strtotime(str_replace("-","/",$d));


if($ts>315360000) $val = round($ts/31536000,0).' year';
else if($ts>94608000) $val = round($ts/31536000,0).' years';
else if($ts>63072000) $val = ' two years';
else if($ts>31536000) $val = ' a year';


else if($ts>24192000) $val = round($ts/2419200,0).' month';
else if($ts>7257600) $val = round($ts/2419200,0).' months';
else if($ts>4838400) $val = ' two months';
else if($ts>2419200) $val = ' a month';




else if($ts>6048000) $val = round($ts/604800,0).' week';
else if($ts>1814400) $val = round($ts/604800,0).' weeks';
else if($ts>1209600) $val = ' two weeks';
else if($ts>604800) $val = ' a week';


else if($ts>864000) $val = round($ts/86400,0).' day';
else if($ts>259200) $val = round($ts/86400,0).' days';
else if($ts>172800) $val = ' two days';
else if($ts>86400) $val = ' a day';


else if($ts>36000) $val = round($ts/3600,0).' year';
else if($ts>10800) $val = round($ts/3600,0).' years';
else if($ts>7200) $val = ' two years';
else if($ts>3600) $val = ' a year';


else if($ts>600) $val = round($ts/60,0).' minute';
else if($ts>180) $val = round($ts/60,0).' minutes';
else if($ts>120) $val = ' two minutes';
else if($ts>60) $val = ' a minute';


else if($ts>10) $val = round($ts,0).' second';
else if($ts>2) $val = round($ts,0).' seconds';
else if($ts>1) $val = ' two seconds';
else $val = $ts.' a second';




return $val;
}

我知道这里有几个答案,但这是我想到的。这只处理MySQL DATETIME值,根据我回应的原始问题。数组$a需要做一些工作。我欢迎就如何改进提出意见。电话为:

Echo time_elapsed_string('2014-11-14 09:42:28');

function time_elapsed_string($ptime)
{
// Past time as MySQL DATETIME value
$ptime = strtotime($ptime);


// Current time as MySQL DATETIME value
$csqltime = date('Y-m-d H:i:s');


// Current time as Unix timestamp
$ctime = strtotime($csqltime);


// Elapsed time
$etime = $ctime - $ptime;


// If no elapsed time, return 0
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){
// Divide elapsed time by seconds
$d = $etime / $secs;
if ($d >= 1){
// Round to the next lowest integer
$r = floor($d);
// Calculate time to remove from elapsed time
$rtime = $r * $secs;
// Recalculate and store elapsed time for next loop
if(($etime - $rtime)  < 0){
$etime -= ($r - 1) * $secs;
}
else{
$etime -= $rtime;
}
// Create string to return
$estring = $estring . $r . ' ' . ($r > 1 ? $a_plural[$str] : $str) . ' ';
}
}
return $estring . ' ago';
}

再加上另一个选择……

虽然我更喜欢发布在这里的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;
}

我使用以下功能几年了。它运行得很好:

function timeDifference($timestamp)
{
$otherDate=$timestamp;
$now=@date("Y-m-d H:i:s");


$secondDifference=@strtotime($now)-@strtotime($otherDate);
$extra="";
if ($secondDifference == 2592000) {
// months
$difference = $secondDifference/2592000;
$difference = round($difference,0);
if ($difference>1) { $extra="s"; }
$difference = $difference." month".$extra." ago";
}else if($secondDifference > 2592000)
{$difference=timestamp($timestamp);}
elseif ($secondDifference >= 604800) {
// weeks
$difference = $secondDifference/604800;
$difference = round($difference,0);
if ($difference>1) { $extra="s"; }
$difference = $difference." week".$extra." ago";
}
elseif ($secondDifference >= 86400) {
// days
$difference = $secondDifference/86400;
$difference = round($difference,0);
if ($difference>1) { $extra="s"; }
$difference = $difference." day".$extra." ago";
}
elseif ($secondDifference >= 3600) {
// hours


$difference = $secondDifference/3600;
$difference = round($difference,0);
if ($difference>1) { $extra="s"; }
$difference = $difference." hour".$extra." ago";
}
elseif ($secondDifference < 3600) {
// hours
// for seconds (less than minute)
if($secondDifference<=60)
{
if($secondDifference==0)
{
$secondDifference=1;
}
if ($secondDifference>1) { $extra="s"; }
$difference = $secondDifference." second".$extra." ago";


}
else
{


$difference = $secondDifference/60;
if ($difference>1) { $extra="s"; }else{$extra="";}
$difference = round($difference,0);
$difference = $difference." minute".$extra." ago";
}
}


$FinalDifference = $difference;
return $FinalDifference;
}
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) );

使用:

echo elapsed_time('2016-05-09 17:00:00'); // 18 saat 8 dakika önce yazıldı.

功能:

function elapsed_time($time){// Nekadar zaman geçmiş


$diff = time() - strtotime($time);


$sec = $diff;
$min = floor($diff/60);
$hour = floor($diff/(60*60));
$hour_min = floor($min - ($hour*60));
$day = floor($diff/(60*60*24));
$day_hour = floor($hour - ($day*24));
$week = floor($diff/(60*60*24*7));
$mon = floor($diff/(60*60*24*7*4));
$year = floor($diff/(60*60*24*7*4*12));


//difference calculate to string
if($sec < (60*5)){
return 'şimdi yazıldı.';
}elseif($min < 60){
return 'biraz önce yazıldı.';
}elseif($hour < 24){
return $hour.' saat '.$hour_min.' dakika önce yazıldı.';
}elseif($day < 7){
if($day_hour!=0){$day_hour=$day_hour.' saat ';}else{$day_hour='';}
return $day.' gün '.$day_hour.'önce yazıldı.';
}elseif($week < 4){
return $week.' hafta önce yazıldı.';
}elseif($mon < 12){
return $mon.' ay önce yazıldı.';
}else{
return $year.' yıl önce yazıldı.';
}
}

我不知道为什么还没有人提到碳。

https://github.com/briannesbitt/Carbon

这实际上是php dateTime的扩展(这里已经使用了),它有:diffForHumans方法。所以你所需要做的就是:

$dt = Carbon::parse('2012-9-5 23:26:11.123789');
echo $dt->diffForHumans();

更多例子:http://carbon.nesbot.com/docs/#api-humandiff

这个解决方案的优点:

  • 它适用于未来的日期,并将在2个月等时间内返回。
  • 你可以使用本地化来获取其他语言,多元化也很好
  • 如果你开始用碳来做其他事情,处理日期就会变得非常容易。

上面的回答略有修改:

  $commentTime = strtotime($whatever)
$today       = strtotime('today');
$yesterday   = strtotime('yesterday');
$todaysHours = strtotime('now') - strtotime('today');


private function timeElapsedString(
$commentTime,
$todaysHours,
$today,
$yesterday
) {
$tokens = array(
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
$time = time() - $commentTime;
$time = ($time < 1) ? 1 : $time;
if ($commentTime >= $today || $commentTime < $yesterday) {
foreach ($tokens as $unit => $text) {
if ($time < $unit) {
continue;
}
if ($text == 'day') {
$numberOfUnits = floor(($time - $todaysHours) / $unit) + 1;
} else {
$numberOfUnits = floor(($time)/ $unit);
}
return $numberOfUnits . ' ' . $text . (($numberOfUnits > 1) ? 's' : '') . ' ago';
}
} else {
return 'Yesterday';
}
}

我做了这个,它工作得很好,它既适用于像1470919932这样的unix时间戳,也适用于像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;
}


?>

它能帮你检查

   function calculate_time_span($seconds)
{
$year = floor($seconds /31556926);
$months = floor($seconds /2629743);
$week=floor($seconds /604800);
$day = floor($seconds /86400);
$hours = floor($seconds / 3600);
$mins = floor(($seconds - ($hours*3600)) / 60);
$secs = floor($seconds % 60);
if($seconds < 60) $time = $secs." seconds ago";
else if($seconds < 3600 ) $time =($mins==1)?$mins."now":$mins." mins ago";
else if($seconds < 86400) $time = ($hours==1)?$hours." hour ago":$hours." hours ago";
else if($seconds < 604800) $time = ($day==1)?$day." day ago":$day." days ago";
else if($seconds < 2629743) $time = ($week==1)?$week." week ago":$week." weeks ago";
else if($seconds < 31556926) $time =($months==1)? $months." month ago":$months." months ago";
else $time = ($year==1)? $year." year ago":$year." years ago";
return $time;
}
$seconds = time() - strtotime($post->post_date);
echo calculate_time_span($seconds);

我发现结果如下:

1年2个月0天0小时53分1秒

正因为如此,我实现了一个尊重复数的函数,删除空值,并有可能缩短输出:

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;
}

看起来好多了:

1年2个月53分1秒

可选地使用$level = 2将其缩短如下:

1年2个月

如果你只需要在英语中使用$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',
);

我试过了,效果很好

$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-10');
$difference = $datetime1->diff($datetime2);
echo formatOutput($difference);


function formatOutput($diff){
/* function to return the highrst defference fount */
if(!is_object($diff)){
return;
}


if($diff->y > 0){
return $diff->y .(" year".($diff->y > 1?"s":"")." ago");
}


if($diff->m > 0){
return $diff->m .(" month".($diff->m > 1?"s":"")." ago");
}


if($diff->d > 0){
return $diff->d .(" day".($diff->d > 1?"s":"")." ago");
}


if($diff->h > 0){
return $diff->h .(" hour".($diff->h > 1?"s":"")." ago");
}


if($diff->i > 0){
return $diff->i .(" minute".($diff->i > 1?"s":"")." ago");
}


if($diff->s > 0){
return $diff->s .(" second".($diff->s > 1?"s":"")." ago");
}
}

检查此链接以参考在这里

谢谢!玩得开心。

这就是我要的。这是阿巴斯汗帖子的修改版本:

<?php


function calculate_time_span($post_time)
{
$seconds = time() - strtotime($post);
$year = floor($seconds /31556926);
$months = floor($seconds /2629743);
$week=floor($seconds /604800);
$day = floor($seconds /86400);
$hours = floor($seconds / 3600);
$mins = floor(($seconds - ($hours*3600)) / 60);
$secs = floor($seconds % 60);
if($seconds < 60) $time = $secs." seconds ago";
else if($seconds < 3600 ) $time =($mins==1)?$mins."now":$mins." mins ago";
else if($seconds < 86400) $time = ($hours==1)?$hours." hour ago":$hours." hours ago";
else if($seconds < 604800) $time = ($day==1)?$day." day ago":$day." days ago";
else if($seconds < 2629743) $time = ($week==1)?$week." week ago":$week." weeks ago";
else if($seconds < 31556926) $time =($months==1)? $months." month ago":$months." months ago";
else $time = ($year==1)? $year." year ago":$year." years ago";
return $time;
}






// uses
// $post_time="2017-12-05 02:05:12";
// echo calculate_time_span($post_time);

这里的许多解决方案没有考虑舍入。例如:

事件发生在两天前的下午3点。如果您在下午2点查看,它会显示在一天前。如果你在下午4点查看,它会显示两天前。

如果你使用unix时间,这有助于:

// how long since event has passed in seconds
$secs = time() - $time_ago;


// how many seconds in a day
$sec_per_day = 60*60*24;


// days elapsed
$days_elapsed = floor($secs / $sec_per_day);


// how many seconds passed today
$today_seconds = date('G')*3600 + date('i') * 60 + date('s');


// how many seconds passed in the final day calculation
$remain_seconds = $secs % $sec_per_day;


if($today_seconds < $remain_seconds)
{
$days_elapsed++;
}


echo 'The event was '.$days_ago.' days ago.';

如果你担心闰秒和夏时制,这并不完美。

一些语言显示时间有一些问题,例如在阿拉伯语中,有3种格式来显示日期。 我在我的项目中使用这个函数,希望他们可以帮助别人(任何建议或改进,我会很感激:))

/**
*
* @param   string $date1
* @param   string $date2 the date that you want to compare with $date1
* @param   int $level
* @param   bool $absolute
*/


function app_date_diff( $date1, $date2, $level = 3, $absolute = false ) {


$date1 = date_create($date1);
$date2 = date_create($date2);
$diff = date_diff( $date1, $date2, $absolute );


$d = [
'invert' => $diff->invert
];


$diffs = [
'y' => $diff->y,
'm' => $diff->m,
'd' => $diff->d
];


$level_reached = 0;


foreach($diffs as $k=>$v) {


if($level_reached >= $level) {
break;
}


if($v > 0) {
$d[$k] = $v;
$level_reached++;
}


}


return  $d;


}


/**
*
*/


function date_timestring( $periods, $format = 'latin', $separator = ',' ) {


$formats = [
'latin' => [
'y' => ['year','years'],
'm' => ['month','months'],
'd' => ['day','days']
],
'arabic' => [
'y' => ['سنة','سنتين','سنوات'],
'm' => ['شهر','شهرين','شهور'],
'd' => ['يوم','يومين','أيام']
]
];


$formats = $formats[$format];


$string = [];


foreach($periods as $period=>$value) {


if(!isset($formats[$period])) {
continue;
}


$string[$period] = $value.' ';
if($format == 'arabic') {
if($value == 2) {
$string[$period] = $formats[$period][1];
}elseif($value > 2 && $value <= 10) {
$string[$period] .= $formats[$period][2];
}else{
$string[$period] .= $formats[$period][0];
}


}elseif($format == 'latin') {
$string[$period] .= ($value > 1) ? $formats[$period][1] : $formats[$period][0];
}


}


return implode($separator, $string);




}


function timeago( $date ) {


$today = date('Y-m-d h:i:s');


$diff = app_date_diff($date,$today,2);


if($diff['invert'] == 1) {
return '';
}


unset($diff[0]);


$date_timestring = date_timestring($diff,'latin');


return 'About '.$date_timestring;


}


$date1 = date('Y-m-d');
$date2 = '2018-05-14';


$diff = timeago($date2);
echo $diff;

我通常用它来找出currentpassed datetime stamp之间的区别

输出

//If difference is greater than 7 days
7 June 2019


// if difference is greater than 24 hours and less than 7 days
1 days ago
6 days ago


1 hour ago
23 hours ago


1 minute ago
58 minutes ago


1 second ago
20 seconds ago

代码

//return current date time
function getCurrentDateTime(){
//date_default_timezone_set("Asia/Calcutta");
return date("Y-m-d H:i:s");
}
function getDateString($date){
$dateArray = date_parse_from_format('Y/m/d', $date);
$monthName = DateTime::createFromFormat('!m', $dateArray['month'])->format('F');
return $dateArray['day'] . " " . $monthName  . " " . $dateArray['year'];
}


function getDateTimeDifferenceString($datetime){
$currentDateTime = new DateTime(getCurrentDateTime());
$passedDateTime = new DateTime($datetime);
$interval = $currentDateTime->diff($passedDateTime);
//$elapsed = $interval->format('%y years %m months %a days %h hours %i minutes %s seconds');
$day = $interval->format('%a');
$hour = $interval->format('%h');
$min = $interval->format('%i');
$seconds = $interval->format('%s');


if($day > 7)
return getDateString($datetime);
else if($day >= 1 && $day <= 7 ){
if($day == 1) return $day . " day ago";
return $day . " days ago";
}else if($hour >= 1 && $hour <= 24){
if($hour == 1) return $hour . " hour ago";
return $hour . " hours ago";
}else if($min >= 1 && $min <= 60){
if($min == 1) return $min . " minute ago";
return $min . " minutes ago";
}else if($seconds >= 1 && $seconds <= 60){
if($seconds == 1) return $seconds . " second ago";
return $seconds . " seconds ago";
}
}

试试这个,我从我的旧代码中找到的,它显示了正确的结果

function ago($datefrom, $dateto = -1) {
// Defaults and assume if 0 is passed in that
// its an error rather than the epoch


if ($datefrom == 0) {
return "A long time ago";
}
if ($dateto == -1) {
$dateto = time();
}


// Make the entered date into Unix timestamp from MySQL datetime field


$datefrom = strtotime($datefrom);


// Calculate the difference in seconds betweeen
// the two timestamps


$difference = $dateto - $datefrom;


// Based on the interval, determine the
// number of units between the two dates
// From this point on, you would be hard
// pushed telling the difference between
// this function and DateDiff. If the $datediff
// returned is 1, be sure to return the singular
// of the unit, e.g. 'day' rather 'days'


switch (true) {
// If difference is less than 60 seconds,
// seconds is a good interval of choice
case(strtotime('-1 min', $dateto) < $datefrom):
$datediff = $difference;
$res = ($datediff == 1) ? $datediff . ' second' : $datediff . ' seconds';
break;
// If difference is between 60 seconds and
// 60 minutes, minutes is a good interval
case(strtotime('-1 hour', $dateto) < $datefrom):
$datediff = floor($difference / 60);
$res = ($datediff == 1) ? $datediff . ' minute' : $datediff . ' minutes';
break;
// If difference is between 1 hour and 24 hours
// hours is a good interval
case(strtotime('-1 day', $dateto) < $datefrom):
$datediff = floor($difference / 60 / 60);
$res = ($datediff == 1) ? $datediff . ' hour' : $datediff . ' hours';
break;
// If difference is between 1 day and 7 days
// days is a good interval
case(strtotime('-1 week', $dateto) < $datefrom):
$day_difference = 1;
while (strtotime('-' . $day_difference . ' day', $dateto) >= $datefrom) {
$day_difference++;
}


$datediff = $day_difference;
$res = ($datediff == 1) ? 'yesterday' : $datediff . ' days';
break;
// If difference is between 1 week and 30 days
// weeks is a good interval
case(strtotime('-1 month', $dateto) < $datefrom):
$week_difference = 1;
while (strtotime('-' . $week_difference . ' week', $dateto) >= $datefrom) {
$week_difference++;
}


$datediff = $week_difference;
$res = ($datediff == 1) ? 'last week' : $datediff . ' weeks';
break;
// If difference is between 30 days and 365 days
// months is a good interval, again, the same thing
// applies, if the 29th February happens to exist
// between your 2 dates, the function will return
// the 'incorrect' value for a day
case(strtotime('-1 year', $dateto) < $datefrom):
$months_difference = 1;
while (strtotime('-' . $months_difference . ' month', $dateto) >= $datefrom) {
$months_difference++;
}


$datediff = $months_difference;
$res = ($datediff == 1) ? $datediff . ' month' : $datediff . ' months';


break;
// If difference is greater than or equal to 365
// days, return year. This will be incorrect if
// for example, you call the function on the 28th April
// 2008 passing in 29th April 2007. It will return
// 1 year ago when in actual fact (yawn!) not quite
// a year has gone by
case(strtotime('-1 year', $dateto) >= $datefrom):
$year_difference = 1;
while (strtotime('-' . $year_difference . ' year', $dateto) >= $datefrom) {
$year_difference++;
}


$datediff = $year_difference;
$res = ($datediff == 1) ? $datediff . ' year' : $datediff . ' years';
break;
}
return $res;
}

例如:echo ago('2020-06-03 00:14:21 AM');

输出:6 days

如果你正在使用PostgreSQL,那么它将为你做的工作:

const DT_SQL = <<<SQL
WITH lapse AS (SELECT (?::timestamp(0) - now()::timestamp(0))::text t)
SELECT CASE
WHEN (select t from lapse) ~ '^\s*-' THEN replace((select t from lapse), '-', '') ||' ago'
ELSE (select t from lapse) END;
SQL;


function timeSpanText($ts, $conn)
// $ts: date-time string, $conn: PostgreSQL PDO connection
{
return $conn -> prepare(DT_SQL) -> execute([ts]) -> fetchColumn();
}

直接回答这个问题…你可以用…

strtotime()

https://www.php.net/manual/en/function.strtotime.php

$dif = time() - strtotime("2009-09-12 20:57:19");

例句:

echo round(((( time() - strtotime("2021-08-01 21:57:50") )/60)/60)/24).' day(s) ago';

结果:1天前

我想有一个荷兰版本,支持单复数。仅仅在结尾加一个“s”是不够的,我们用的是完全不同的词,所以我重写了这篇文章的顶部答案。

这将导致:

2 jaren 1 maand 2 weken 1 dag 1 minuten 2 seconden

1 jaar 2 maanden 1 week 2 dagen 1 minuut 1 seconde

    public function getTimeAgo($full = false){


$now = new \DateTime;
$ago = new \DateTime($this->datetime());
$diff = $now->diff($ago);


$diff->w = floor($diff->d / 7);
$diff->d -= $diff->w * 7;


$string = array(
'y' => 'jaren',
'm' => 'maanden',
'w' => 'weken',
'd' => 'dagen',
'h' => 'uren',
'i' => 'minuten',
's' => 'seconden',
);
$singleString = array(
'y' => 'jaar',
'm' => 'maand',
'w' => 'week',
'd' => 'dag',
'h' => 'uur',
'i' => 'minuut',
's' => 'seconde',
);
// M.O. 2022-02-11 I rewrote this function to support dutch singles and plurals. Added some docs for next programmer to break his brain :)
// For each possible notation, if corresponding value of current key is true (>1) otherwise remove its key/value from array
// If the value from current key is 1, use value from $singleString array. Otherwise use value from $string array
foreach ($string as $k => &$v) {
if ($diff->$k) {
if($diff->$k == 1){
$v = $diff->$k . ' ' . $singleString[$k];
} else {
$v = $diff->$k . ' ' . $v;
}
} else {
if($diff->$k == 1){
unset($singleString[$k]);
} else {
unset($string[$k]);
}
}
}


// If $full = true, print all values.
// Values have already been filtered with foreach removing keys that contain a 0 as value
if (!$full) $string = array_slice($string, 0, 1);
return $string ? implode(', ', $string) . '' : 'zojuist';
}

你应该先测试一下,因为我不是一个优秀的程序员:)