Преобразование метки времени в время назад в PHP, например, 1 день назад, 2 дня назад ... - PullRequest
208 голосов
/ 13 сентября 2009

Я пытаюсь преобразовать метку времени в формате 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?) Формат?

Ответы [ 27 ]

2 голосов
/ 26 августа 2016

это поможет вам проверить

   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 голос
/ 19 марта 2018

Многие решения здесь не учитывают округление. Например:

Событие произошло в 3 часа дня два дня назад. Если вы проверяете в 2 часа дня, это покажет один день назад. Если вы проверяете в 4 часа дня, это будет показано два дня назад.

Если вы работаете с Unix Time, это поможет:

// 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.';

Это не идеально, если вы беспокоитесь о високосных секундах и летнем времени.

1 голос
/ 05 декабря 2017

Это то, с чем я пошел. Это модифицированная версия поста Абббас хана:

<?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); 
1 голос
/ 14 января 2015

Я знаю, что здесь есть несколько ответов, но это то, что я придумал. Это только обрабатывает значения 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';
}
1 голос
/ 24 октября 2017

Я попробовал это и отлично работает для меня

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

Проверьте эту ссылку для справки здесь

Спасибо! и получай удовольствие.

0 голосов
/ 16 декабря 2014

Эта функция не предназначена для использования на английском языке. Я перевел слова на английский. Это требует дополнительной фиксации перед использованием для английского языка.

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;
    }
0 голосов
/ 20 апреля 2014

просто передайте дату и время этой функции. он вывел бы формат времени назад для вас

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';
  }
0 голосов
/ 18 марта 2014
$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;
0 голосов
/ 28 июля 2016

Слегка измененный ответ сверху:

  $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';
    }
}
0 голосов
/ 24 июня 2014

Ниже приведено очень простое и чрезвычайно эффективное решение.

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 секунд.

...