PHP:从时间戳生成相对日期/时间

PHP:从时间戳生成相对日期/时间,php,time,timestamp,relative-date,Php,Time,Timestamp,Relative Date,我基本上是在尝试将Unix时间戳(time()函数)转换为与过去和未来日期兼容的相对日期/时间。因此,产出可以是: 两周前 1小时60分钟前 15分54秒前 10分15秒后 首先,我尝试编写代码,但生成了一个无法维护的巨大函数,然后我在互联网上搜索了几个小时,但我能找到的只是只生成一部分时间的脚本(例如:“1小时前”,没有分钟) 您是否有已经执行此操作的脚本?此函数在“现在”和“特定时间戳”之间提供类似“1小时前”或“明天”的结果 function time2str($ts) { if(

我基本上是在尝试将Unix时间戳(time()函数)转换为与过去和未来日期兼容的相对日期/时间。因此,产出可以是:

两周前

1小时60分钟前

15分54秒前

10分15秒后

首先,我尝试编写代码,但生成了一个无法维护的巨大函数,然后我在互联网上搜索了几个小时,但我能找到的只是只生成一部分时间的脚本(例如:“1小时前”,没有分钟)

您是否有已经执行此操作的脚本?

此函数在“现在”和“特定时间戳”之间提供类似“1小时前”或“明天”的结果

function time2str($ts)
{
    if(!ctype_digit($ts))
        $ts = strtotime($ts);

    $diff = time() - $ts;
    if($diff == 0)
        return 'now';
    elseif($diff > 0)
    {
        $day_diff = floor($diff / 86400);
        if($day_diff == 0)
        {
            if($diff < 60) return 'just now';
            if($diff < 120) return '1 minute ago';
            if($diff < 3600) return floor($diff / 60) . ' minutes ago';
            if($diff < 7200) return '1 hour ago';
            if($diff < 86400) return floor($diff / 3600) . ' hours ago';
        }
        if($day_diff == 1) return 'Yesterday';
        if($day_diff < 7) return $day_diff . ' days ago';
        if($day_diff < 31) return ceil($day_diff / 7) . ' weeks ago';
        if($day_diff < 60) return 'last month';
        return date('F Y', $ts);
    }
    else
    {
        $diff = abs($diff);
        $day_diff = floor($diff / 86400);
        if($day_diff == 0)
        {
            if($diff < 120) return 'in a minute';
            if($diff < 3600) return 'in ' . floor($diff / 60) . ' minutes';
            if($diff < 7200) return 'in an hour';
            if($diff < 86400) return 'in ' . floor($diff / 3600) . ' hours';
        }
        if($day_diff == 1) return 'Tomorrow';
        if($day_diff < 4) return date('l', $ts);
        if($day_diff < 7 + (7 - date('w'))) return 'next week';
        if(ceil($day_diff / 7) < 4) return 'in ' . ceil($day_diff / 7) . ' weeks';
        if(date('n', $ts) == date('n') + 1) return 'next month';
        return date('F Y', $ts);
    }
}
函数time2str($ts)
{
如果(!ctype_数字($ts))
$ts=实时时间($ts);
$diff=时间()-$ts;
如果($diff==0)
返回“现在”;
elseif($diff>0)
{
$day_diff=地板($diff/86400);
如果($day_diff==0)
{
如果($diff<60)返回“刚才”;
如果($diff<120)返回“1分钟前”;
如果($diff<3600)返回楼层($diff/60)。“分钟前”;
如果($diff<7200)返回“1小时前”;
如果($diff<86400)返回楼层($diff/3600)。“小时前”;
}
如果($day_diff==1)返回“昨天”;
如果($day_diff<7)返回$day_diff.'days ago';
如果($day_diff<31)返回ceil($day_diff/7)。“周前”;
如果($day_diff<60)返回“上个月”;
返回日期('F Y',$ts);
}
其他的
{
$diff=绝对值($diff);
$day_diff=地板($diff/86400);
如果($day_diff==0)
{
如果($diff<120)返回“一分钟内”;
如果($diff<3600)返回“in.”楼层($diff/60)。“分钟”;
如果($diff<7200)返回“一小时内”;
如果($diff<86400)返回“in.”楼层($diff/3600)。“小时”;
}
如果($day_diff==1)返回“明天”;
如果($day_diff<4)返回日期($l',$ts);
如果($day_diff<7+(7-日期('w'))返回“下周”;
如果(ceil($day_diff/7)<4)返回'in'。ceil($day_diff/7)。'weeks';
如果(日期('n',$ts)=日期('n')+1)返回“下个月”;
返回日期('F Y',$ts);
}
}
用法:

echo relativeTime((time()-256));
4 minutes 16 seconds ago

这是我写的。显示相对于今天日期的过去日期

/**
 * @param $date integer of unixtimestamp format, not actual date type
 * @return string
 */
function zdateRelative($date)
{
    $now = time();
    $diff = $now - $date;

    if ($diff < 60){
        return sprintf($diff > 1 ? '%s seconds ago' : 'a second ago', $diff);
    }

    $diff = floor($diff/60);

    if ($diff < 60){
        return sprintf($diff > 1 ? '%s minutes ago' : 'one minute ago', $diff);
    }

    $diff = floor($diff/60);

    if ($diff < 24){
        return sprintf($diff > 1 ? '%s hours ago' : 'an hour ago', $diff);
    }

    $diff = floor($diff/24);

    if ($diff < 7){
        return sprintf($diff > 1 ? '%s days ago' : 'yesterday', $diff);
    }

    if ($diff < 30)
    {
        $diff = floor($diff / 7);

        return sprintf($diff > 1 ? '%s weeks ago' : 'one week ago', $diff);
    }

    $diff = floor($diff/30);

    if ($diff < 12){
        return sprintf($diff > 1 ? '%s months ago' : 'last month', $diff);
    }

    $diff = date('Y', $now) - date('Y', $date);

    return sprintf($diff > 1 ? '%s years ago' : 'last year', $diff);
}
/**
*@param$date整数,unixtimestamp格式,非实际日期类型
*@返回字符串
*/
功能ZDaterRelative($date)
{
$now=时间();
$diff=$now-$date;
如果($diff<60){
返回sprintf($diff>1?'%s秒前]:'a second ago',$diff);
}
$diff=楼层($diff/60);
如果($diff<60){
返回sprintf($diff>1?“%s分钟前”:“一分钟前,$diff);
}
$diff=楼层($diff/60);
如果($diff<24){
返回sprintf($diff>1?“%s小时前”:“一小时前”,$diff);
}
$diff=楼层($diff/24);
如果($diff<7){
返回sprintf($diff>1?“%s天前”:“昨天”,$diff);
}
如果($diff<30)
{
$diff=楼层($diff/7);
返回sprintf($diff>1?“%s周前”:“一周前,$diff);
}
$diff=楼层($diff/30);
如果($diff<12){
返回sprintf($diff>1?'%s个月前]:'last month',$diff);
}
$diff=日期($Y',$now)-日期($Y',$date);
返回sprintf($diff>1?'%s年前】:'last year',$diff);
}

为什么不仿效drupal的做法-



您可能不需要替换t(),而且您可以很容易地为格式_复数做自己的事情,因为您(可能)不必支持多种语言

我喜欢xdebug的相对时间函数。问题是我需要它有一些粒度

换句话说,如果我决定的话,在几秒钟或几分钟内停止。 那么现在,

echo fTime(strtotime('-23 hours 5 minutes 55 seconds'),0); 
echo fTime(strtotime('-1 year 2 months 3 weeks 4 days 16 hours 15 minutes 22 seconds'),0); 
会显示,

23小时,5分钟前

而不是

23小时5分55秒前

我还希望它不会在数组中下降,如果它达到了较高的时间量之一。 所以如果它显示年份,我只想显示年份和月份。 那么现在,

echo fTime(strtotime('-23 hours 5 minutes 55 seconds'),0); 
echo fTime(strtotime('-1 year 2 months 3 weeks 4 days 16 hours 15 minutes 22 seconds'),0); 
会显示

1年,2个月前

而不是

1年、2个月、3周、4天、16小时、15分钟、22秒前

下面的代码更改满足了我的需要。当然,道具首先会转到xdebug。 希望其他人会觉得它有用:

function fTime($time, $gran=-1) {

    $d[0] = array(1,"second");
    $d[1] = array(60,"minute");
    $d[2] = array(3600,"hour");
    $d[3] = array(86400,"day");
    $d[4] = array(604800,"week");
    $d[5] = array(2592000,"month");
    $d[6] = array(31104000,"year");

    $w = array();

    $return = "";
    $now = time();
    $diff = ($now-$time);
    $secondsLeft = $diff;
    $stopat = 0;
    for($i=6;$i>$gran;$i--)
    {
         $w[$i] = intval($secondsLeft/$d[$i][0]);
         $secondsLeft -= ($w[$i]*$d[$i][0]);
         if($w[$i]!=0)
         {
            $return.= abs($w[$i]) . " " . $d[$i][1] . (($w[$i]>1)?'s':'') ." ";
             switch ($i) {
                case 6: // shows years and months
                    if ($stopat==0) { $stopat=5; }
                    break;
                case 5: // shows months and weeks
                    if ($stopat==0) { $stopat=4; }
                    break;
                case 4: // shows weeks and days
                    if ($stopat==0) { $stopat=3; }
                    break;
                case 3: // shows days and hours
                    if ($stopat==0) { $stopat=2; }
                    break;
                case 2: // shows hours and minutes
                    if ($stopat==0) { $stopat=1; }
                    break;
                case 1: // shows minutes and seconds if granularity is not set higher
                    break;
             }
             if ($i===$stopat) { break 0; }
         }
    }

    $return .= ($diff>0)?"ago":"left";
    return $return;
}

马库斯

你可以通过packagist使用碳,真是太神奇了:)

我需要一个来给我下面的结果,所以我写了我自己的。希望这能帮助一些人

用法示例:

$datetime = "2014-08-13 12:52:48";  
echo getRelativeTime($datetime);    //10 hours ago  
echo getRelativeTime($datetime, 1); //10 hours ago  
echo getRelativeTime($datetime, 2); //10 hours and 50 minutes ago  
echo getRelativeTime($datetime, 3); //10 hours, 50 minutes and 50 seconds ago  
echo getRelativeTime($datetime, 4); //10 hours, 50 minutes and 50 seconds ago  
代码:

公共函数getRelativeTime($datetime,$depth=1){
$units=数组(
“年”=>31104000,
“月”=>2592000,
“周”=>604800,
“日”=>86400,
“小时”=>3600,
“分钟”=>60,
“秒”=>1
);
$plural=“s”;
$conjugator=“和”;
$separator=“,”;
$suffix1=“ago”;
$supfix2=“左”;
$now=“now”;
$empty=“”;
#不要在下面编辑
$timediff=time()-strottime($datetime);
如果($timediff==0),立即返回$now;
如果($depth<1),则返回$empty;
$max_depth=计数(单位);
$resident=abs($timediff);
$output=“”;
$count_depth=0;
$fix_depth=true;
foreach($units为$unit=>$value){
如果($余数>$值&&$深度-->0){
如果($固定深度){
$max_depth-=+$count_depth;
如果($depth>=$max\u depth)$depth=$max\u depth;
$fix_depth=false;
}
$u=(整数)($余数/$value);
$resident%=$value;
$multilare=$u>1?$multilar:$empty;
$separate=$resident==0 | |$depth==0?$empty:
($depth==1?$conjugator:$separator);
$output.=“{$u}{$unit}{
public function getRelativeTime($datetime, $depth=1) {

    $units = array(
        "year"=>31104000,
        "month"=>2592000,
        "week"=>604800,
        "day"=>86400,
        "hour"=>3600,
        "minute"=>60,
        "second"=>1
    );

    $plural = "s";
    $conjugator = " and ";
    $separator = ", ";
    $suffix1 = " ago";
    $suffix2 = " left";
    $now = "now";
    $empty = "";

    # DO NOT EDIT BELOW

    $timediff = time()-strtotime($datetime);
    if ($timediff == 0) return $now;
    if ($depth < 1) return $empty;

    $max_depth = count($units);
    $remainder = abs($timediff);
    $output = "";
    $count_depth = 0;
    $fix_depth = true;

    foreach ($units as $unit=>$value) {
        if ($remainder>$value && $depth-->0) {
            if ($fix_depth) {
                $max_depth -= ++$count_depth;
                if ($depth>=$max_depth) $depth=$max_depth;
                $fix_depth = false;
            }
            $u = (int)($remainder/$value);
            $remainder %= $value;
            $pluralise = $u>1?$plural:$empty;
            $separate = $remainder==0||$depth==0?$empty:
                            ($depth==1?$conjugator:$separator);
            $output .= "{$u} {$unit}{$pluralise}{$separate}";
        }
        $count_depth++;
    }
    return $output.($timediff<0?$suffix2:$suffix1);
}
function zdateRelative($date)
{
  $diff = time() - $date;
  $periods[] = [60, 1, '%s seconds ago', 'a second ago'];
  $periods[] = [60*100, 60, '%s minutes ago', 'one minute ago'];
  $periods[] = [3600*70, 3600, '%s hours ago', 'an hour ago'];
  $periods[] = [3600*24*10, 3600*24, '%s days ago', 'yesterday'];
  $periods[] = [3600*24*30, 3600*24*7, '%s weeks ago', 'one week ago'];
  $periods[] = [3600*24*30*30, 3600*24*30, '%s months ago', 'last month'];
  $periods[] = [INF, 3600*24*265, '%s years ago', 'last year'];
  foreach ($periods as $period) {
    if ($diff > $period[0]) continue;
    $diff = floor($diff / $period[1]);
    return sprintf($diff > 1 ? $period[2] : $period[3], $diff);
  }
}
// return relative date/time string from timestamp
// [n yrs] [n mos] [n days] h:i:s
function relative_time(int $time): string
{
        $dt = new DateTime();
        $dt->setTimestamp($time);
        $diff = (new DateTime())->diff($dt);

        $s = "";
        if ($diff->y) $s .= " {$diff->y} " . (($diff->y > 1) ? "yrs" : "yr");
        if ($diff->m) $s .= " {$diff->m} " . (($diff->m > 1) ? "mos" : "mo");
        if ($diff->d) $s .= " {$diff->d} " . (($diff->d > 1) ? "days" : "day");
        $s .= sprintf(" %02d:%02d:%02d", $diff->h, $diff->i, $diff->s);
        return trim($s);
}