3

phpを使用して、指定した日付と現在の日付の間の日付間隔を計算しています。これを行うと、次のようなソーシャルフレンドリーなタイムスタンプを印刷できますA few mins ago2 hours ago

私が時間の部分に来るとき、私はphpで本当に面白い振る舞いをする何かを手に入れます。以下は完全に機能するコードですが、パーツをこのコードに置き換えると、hours常に3時間印刷されます。

定義された定数DATE

// The current date timestamp
define('DATE', time());

ここにバギーコード:

//Only the hours part that' doing something weird
case ($interval >= 3600 && $interval < 86400) :
            $return = ( date('H', $interval) < 2)
                ? (int)date('H', $interval) . ' hour ago'
                : (int)date('H', $interval) . ' hours ago';
            break;

指定された日付、たとえばこの場合は作成日が1時間強前である場合に中断するため、間隔は3660秒になります。dateメソッドの呼び出しのdate('H', 3660)結果は03のようです。結果は01になるべきではありませんか?やっぱり1時間強です。

ここでの作業コード:

public static function getTimeInterval($date)
{
    $interval = DATE - $date;

    $return = '';

    switch ( $interval )
    {
        case ($interval <= 60) :
            $return = 'a few secs ago';
            break;

        case ($interval > 60 && $interval < 3600) :
            $return = (int)date('i', $interval) . ' mins ago';
            break;

        case ($interval >= 3600 && $interval < 86400) :
            $return = ( abs((date('G', DATE) - date('G', $date))) < 2)
                ? abs((date('G', DATE) - date('G', $date))) . ' hour ago'
                : abs((date('G', DATE) - date('G', $date))) . ' hours ago';
            break;

        case ($interval >= 86400 && $interval < 604800) :
            $return = ( (int)date('j', $interval) === 1)
                ? (int)date('j', $interval) . ' day ago'
                : (int)date('j', $interval) . ' days ago';
            break;

        case ($interval > 604800 && $interval <= 2592000) :
            $return = 'A few weeks ago';
            break;
        case ($interval > 2592000) :
            $return = date('n', $interval) . ' months ago';
            break;
        case ($interval > 31536000) :
            $return = 'Over a year ago';
            break;

    }

    return $return;

}
4

6 に答える 6

3

date()の結果は、タイムゾーンによって異なります。date_default_timezone_set()でタイムゾーンを手動で設定することにより、この動作を変更できます。

于 2011-06-28T07:01:38.743 に答える
3

このコードを確認してください、それはうまくいきます:

function do_plurals($nb, $str)
{
    return $nb > 1 ? $str . 's' : $str;
}


function dates_interval_text(DateTime $start, DateTime $end)
{
    $interval = $end->diff($start);

    $format = array();
    if ($interval->y !== 0)
    {
        $format[] = "%y " . do_plurals($interval->y, "year");
    }
    if ($interval->m !== 0)
    {
        $format[] = "%m " . do_plurals($interval->m, "month");
    }
    if ($interval->d !== 0)
    {
        $format[] = "%d " . do_plurals($interval->d, "day");
    }
    if ($interval->h !== 0)
    {
        $format[] = "%h " . do_plurals($interval->h, "hour");
    }
    if ($interval->i !== 0)
    {
        $format[] = "%i " . do_plurals($interval->i, "minute");
    }
    if (!count($format))
    {
        return "less than a minute ago";
    }

    // We use the two biggest parts
    if (count($format) > 1)
    {
        $format = array_shift($format) . " and " . array_shift($format);
    }
    else
    {
        $format = array_pop($format);
    }

    // Prepend 'since ' or whatever you like
    return $interval->format($format) . ' ago';
}

次のような結果が得られます2 hours and 3 minutes ago

于 2011-06-28T07:01:51.820 に答える
2

date('H', 3660)結果は01になります。おそらく、あなたのインが適用されているタイムゾーンです。これは、ローカルレベル(アプリケーション)またはグローバルレベル(php構成)である可能性があります。多分それはあなたのOSです。申し訳ありませんが、どのPHP設定を検索するかなどについてはこれ以上お役に立てません。

于 2011-06-28T07:00:17.903 に答える
2

の2番目の引数dateは期間ではなく、タイムスタンプです。date「1970年1月1日00:00UTCからN秒後、何時でしたか?」という質問に答えます。この質問への回答はタイムゾーンで指定されるため、タイムゾーンオフセットが回答に追加されます。

date('Z')タイムゾーンオフセットを秒単位で見つけるために使用します。または、さらに良いことfloor($time/3600)に、時間を計算するために使用します。

于 2011-06-28T07:02:05.060 に答える
1

私の最初の質問は、どこから時刻/タイムスタンプ/日時を取得しているのかということです。

当社では、ドイツでいくつかのサーバーを実行しており、それらでホストされているアプリケーションはパキスタン(GMT + 5)用です。Unixタイムスタンプを使用して「人間が読める」日時を返すこの関数を使用します。

/**
 * @desc Converts UNIX Time into human readable time like '1 hour', 3 weeks', etc.
 * @param number $timestamp
 * @return string
 */
function readable_time($timestamp, $num_times = 2)  {
    // this returns human readable time when it was uploaded
    $times = array (
    31536000 => 'year', 2592000 => 'month',
    604800 => 'week', 86400 => 'day',
    3600 => 'hour', 60 => 'minute', 1 => 'second'
    );
    $now = time ();
    $secs = $now - $timestamp;
    // Fix so that something is always displayed
    if ($secs == 0) $secs = 1;
    $count = 0; $time = '';
    foreach ( $times as $key => $value )    {
        if ($secs >= $key)  {
            // time found
            $s = '';
            $time .= floor ( $secs / $key );
            if ((floor ( $secs / $key ) != 1))  $s = 's';
            $time .= ' ' . $value . $s;
            $count ++;
            $secs = $secs % $key;
            if ($count > $num_times - 1 || $secs == 0) break;
            else $time .= ', ';
        }
    }
    return ($time != "") ? $time." ago" : "now";
}

変数を変更すると、$num_times「4か月、3日、2時間、3分、15秒前」のようになります(この例では、変数を5に設定します)。

論理的には、タイムスタンプはデータベース(この場合はMySQL)から取得されるため、MySQLタイムスタンプを取得してUnixタイムスタンプに変換する別の関数を使用します。

/**
 * @desc Converts UNIX Time into human readable time like '1 hour', 3 weeks', etc.
 * @param number $timestamp
 * @return string
 */
function RelativeTime($timestamp)   {
    $difference = time() - $timestamp;
    $periods = array("sec", "min", "hour", "day", "week", "month", "years", "decade");
    $lengths = array("60", "60", "24", "7", "4.35", "12", "10");
    if ($difference > 0)    { // this was in the past
        $ending = "ago";
    }   else    { // this was in the future
        $difference = -$difference;
        $ending = "to go";
    }
    for($j = 0; $difference >= $lengths[$j]; $j++) $difference /= $lengths[$j];
    $difference = round($difference);
    if($difference != 1) $periods[$j].= "s";
    $text = "$difference $periods[$j] $ending";
    return $text;
}

幸運を!

于 2011-06-28T07:20:26.910 に答える
1

コードは正常に実行されています。あなたがそれを呼んでいる方法にエラーがあります。$ dateがUNIXタイムスタンプとして渡される場合(たとえば、$ date = time()-1 * 60 * 60(1時間前))、非常にうまく動作します。

http://codepad.org/HS25qThK

$aboutHourAgo = time() - 2.5*60*60;   // 2 and half hours ago
var_dump(getTimeInterval($aboutHourAgo));
于 2011-06-28T07:00:01.040 に答える