suin.io

Twitterのように時間を「○分前」と表現をするメソッドをDateTimeクラスに追加してみた

suin2011年2月6日

TwitterやFacebookなどのリアルタイム性の高いソーシャルメディアは、 投稿した時間を年月日時分秒ではなく、投稿時点からの経過時間で表現しています。 大雑把に見たところ、今日中の時間は「○時間前」「○分前」と表現し、 昨日以前の時間は年月日時分秒で表現しているようです。 ここでは、便宜上「○時間前」「○分前」などの表現を「相対時間」、 年月日時分秒を「絶対時間」と言う事にします。

仕様

上の動作を仕様に落としこむと次のようになります。

  • 比較対象日時と現在日時の日付が一致する場合、相対時間で表現する。
  • 比較対象日時と現在日時の日付が異なる場合、絶対時間で表現する。

上の2つだけだと、日付変更直後の時間が考慮されないので、 日付変更後しばらくは、相対時間で表現する必要があるので、次の仕様も追加しておきます。

  • 比較対象日時と現在日時の差が3時間以内の場合、相対時間で表現する。

DateTimeクラスとDateIntervalクラス

相対時間を表現する関数を別途定義してもいいのですが、今回はDateTimeクラスを継承する形で実装します。 具体的にはDateTimeクラスを継承し、timeAgo()メソッドを追加で定義します。

DateTimeは時間をオブジェクト指向的に扱えて便利です。 DateIntervalクラスと組み合わせることで、日時の差が簡単に求められるのも利点です。 ただし、DateIntervalはPHP5.3以上の環境が必要になるので注意が必要です。 相対時間を求める処理に、DateIntervalクラスを活用します。

メソッド実装

<?php
namespace Suin;

class DateTime extends \DateTime
{
	public function timeAgo()
	{
		$now = new DateTime('2011-02-06 00:00:00');
		$nowDate  = $now->format('Ymd');
		$thisDate = $this->format('Ymd');
		$nowTimestamp  = $now->getTimestamp();
		$thisTimestamp = $this->getTimeStamp();

		// 同一日時か、日付変更直後の場合でも3時間以内の差なら、○○前と表現する
		if ( $nowDate === $thisDate or $nowTimestamp - $thisTimestamp <= 60 * 60 * 3 )
		{
			$diff = $this->diff($now);

			switch ( $diff )
			{
				case ( $diff->h > 0 ) : $format = '%h hours ago'; break;
				case ( $diff->i > 0 ) : $format = '%i minutes ago'; break;
				case ( $diff->s > 0 ) : $format = '%s seconds ago'; break;
				default : $format = 'just now'; break;
			}
	
			return $diff->format($format);
		}
		else
		{
			// 昨日以前の日時は○年○月○日○時○分○秒で表現する
			return $this->format('Y-m-d H:i:s');
		}
	}
}

使い方

<?php

namespace;

$postedDatetime = new \Suin\DateTime('2011-02-05 16:30:00');
$ago = $postedDatetime->timeAgo();

上の例では、2011-02-05 16:30:00からの相対時間を取得して$agoに代入してます。

まとめ

TwitterやFacebookで見かける投稿時間からの経過時間を表現するクラスをDateTimeクラスを継承して作ってみました。 このクラスを使うと、今日中の時間は経過時間で、昨日以前の日時は年月日時分秒で表現することができます。

RELATED POSTS