想要改进这篇文章?提供这个问题的详细答案,包括引文和解释为什么你的答案是正确的。没有足够细节的答案可能会被编辑或删除。
我正在尝试转换格式为 2009-09-12 20:57:19
的时间戳,并使用 PHP 将其转换为 3 minutes ago
之类的东西。
我找到了一个有用的脚本来执行此操作,但我认为它正在寻找一种不同的格式来用作时间变量。我要修改以使用这种格式的脚本是:
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?)格式?
使用示例:
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);
输入可以是任何 supported date and time format。
输出 :
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';
}
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';
}
}
}
30days for month
和 12x30days for year
,因此它将返回低于年 <= 1978 年的无效年数。Example 它返回 39 年,但应该是 38 . 它在 1970 年以后的几年里也行不通。
$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";
}
}
}
我不知道为什么还没有人提到碳。
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 个月内返回类似的东西。
您可以使用本地化来获取其他语言,并且多元化工作正常
如果您将开始将 Carbon 用于其他事情,那么使用日期将变得前所未有的简单。
这实际上是我找到的更好的解决方案。使用 jQuery,但它完美地工作。此外,它会自动刷新,类似于 SO 和 Facebook 的方式,因此您无需刷新页面即可查看更新。
该插件将读取您在 <time>
标记中的 datetime
属性并为您填写。
e.g. "4 minutes ago" or "about 1 day ago
2020-12-19 13:12:58
我发现如下丑陋的结果:
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',
);
explode
和 array_combine
的行。
global
?请阅读一些 www.PhpTheRightWay.com。
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) );
我稍微修改了原始功能(在我看来更有用,或更合乎逻辑)。
// 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;
}
我做了这个,它工作得很好,它适用于像 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;
}
?>
$time
将评估为 true
,那不应该是 switch (true)
吗?
只是为了提供另一种选择......
虽然我更喜欢发布 here 的 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;
}
我通常用它来找出 current
和 passed
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 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);
试试这个,我从我的旧代码中找到它,它显示了正确的结果
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
要直接回答问题...您可以使用...
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 天前
我知道这里有几个答案,但这就是我想出的。这仅根据我回答的原始问题处理 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';
}
我试过了,对我来说效果很好
$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");
}
}
检查此链接以获取参考 here
谢谢!玩得开心。
这就是我一起去的。它是 Abbbas khan 帖子的修改版本:
<?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.';
如果您担心闰秒和夏令时,这并不完美。
您必须获取时间戳的每一部分,并将其转换为 Unix 时间。例如时间戳,2009-09-12 20:57:19。
(((2008-1970)*365)+(8*30)+12)*24+20 会给你一个粗略估计自 1970 年 1 月 1 日以来的小时数。
取那个数字,乘以 60 再加上 57 得到分钟。
把它乘以 60 再加上 19。
然而,这会非常粗略且不准确地转换它。
你有什么理由不能从正常的 Unix 时间开始?
某些语言显示时间之前存在一些问题,例如在阿拉伯语中,显示日期需要 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;
如果您使用的是 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();
}
我想要支持单数和复数的荷兰语版本。仅在末尾添加一个“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';
}
您可能应该先对其进行测试,因为我不是那么好的程序员:)
$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;
这是我的解决方案,请根据您的要求检查和修改
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;
}
用于:
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ı.';
}
}
从上面稍微修改的答案:
$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';
}
}
以下是一个非常简单且极其有效的解决方案。
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;
}
$full
应该是一个字符串输入,以根据需要过滤输出)。例如time_elapsed_string($datetime, $format = "ymw")
。 PS平面版:stackoverflow.com/a/5010169/318765$full = false
更改为$level = 7
并将if (!$full) $string = array_slice($string, 0, 1);
更改为$string = array_slice($string, 0, $level);
并调用time_elapsed_string($datetime, 2)
以仅获取两个最高日期字符串。我认为这应该满足所有需求。$diff->w = floor($diff->d / 7);
得到Unknown property (w)
Unknown property (w)
,请将 $diff 从对象转换为数组并相应地调整其余代码。我在此处发布了修复:stackoverflow.com/a/32723846/235633