31

私は基本的に、Unix タイムスタンプ (time() 関数) を、過去と未来の両方の日付と互換性のある相対的な日付/時刻に変換しようとしています。したがって、出力は次のようになります。

2週間前

1時間60分前

15分54秒前

10分15秒後

最初にこれをコーディングしようとしましたが、巨大な保守不可能な関数を作成しました。次に、インターネットを数時間検索しましたが、見つけることができるのは、時間の一部のみを生成するスクリプトだけです (えー: "1 時間前" なし)短い間)。

すでにこれを行うスクリプトはありますか?

4

10 に答える 10

60

この関数は、「今」と「特定のタイムスタンプ」の間の結果のような「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);
    }
}
于 2010-04-22T12:01:39.627 に答える
15
function relativeTime($time) {

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

    for($i=6;$i>-1;$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':'') ." ";
         }

    }

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

使用法:

echo relativeTime((time()-256));
4 minutes 16 seconds ago
于 2011-09-20T15:35:30.883 に答える
10

これが私が書いたものです。今日の日付を基準にした過去の日付を表示します。

/**
 * @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);
}
于 2012-05-25T03:00:36.547 に答える
5

xdebugによるrelativeTime 関数が大好きです。問題は、ある程度の粒度が必要だったことです。

言い換えれば、私が決めたら数秒または数分で停止します。だから今、

echo fTime(strtotime('-23 hours 5 minutes 55 seconds'),0); 

示すだろう、

23時間5分前

それ以外の

23時間5分55秒前

また、より高い時間量のいずれかに達した場合に、配列内でそれが下がらないようにしたかったのです。したがって、年を表示する場合は、年と月のみを表示したいと思います。だから今、

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

マーカス

于 2013-05-05T00:02:21.840 に答える
0

drupal のやり方を盗んでみませんか - http://api.drupal.org/api/drupal/includes%21common.inc/function/format_interval/7

<?php
function format_interval($interval, $granularity = 2, $langcode = NULL) {
  $units = array(
    '1 year|@count years' => 31536000, 
    '1 month|@count months' => 2592000, 
    '1 week|@count weeks' => 604800, 
    '1 day|@count days' => 86400, 
    '1 hour|@count hours' => 3600, 
    '1 min|@count min' => 60, 
    '1 sec|@count sec' => 1,
  );
  $output = '';
  foreach ($units as $key => $value) {
    $key = explode('|', $key);
    if ($interval >= $value) {
      $output .= ($output ? ' ' : '') . format_plural(floor($interval / $value), $key[0], $key[1], array(), array('langcode' => $langcode));
      $interval %= $value;
      $granularity--;
    }

    if ($granularity == 0) {
      break;
    }
  }
  return $output ? $output : t('0 sec', array(), array('langcode' => $langcode));
}
?>

おそらく t() を置き換える必要はなく、(おそらく) 複数の言語をサポートする必要がないため、 format_plural に対して独自のことを簡単に行うことができます。http://api.drupal.org/api/drupal/includes%21common.inc/function/format_plural/7

于 2012-12-10T03:18:32.493 に答える