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クラスを継承して作ってみました。 このクラスを使うと、今日中の時間は経過時間で、昨日以前の日時は年月日時分秒で表現することができます。