我正在尝试转换格式为2009-09-12 20:57:19的时间戳,并将其转换为3分钟前用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?)格式?


当前回答

上面的回答略有修改:

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

}

回显时间已用(1201570814);

样例输出:

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

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

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

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个月等时间内返回。 你可以使用本地化来获取其他语言,多元化也很好 如果你开始用碳来做其他事情,处理日期就会变得非常容易。

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

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

这将导致:

2年1个月2周1天1分2秒

or

1年2个月1周2天1分1秒

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

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