日付を扱う時に便利なPHPライブラリ「Chronos」



PHPでDate【日付】を扱う時に便利なライブラリ「Chronous」の紹介です。
 

Chronosの特徴

日付の計算を始め、比較、フォーマットの変更、タイムゾーン切り替えなどが簡単に出来る
 

Carbonとの違い

PHPのdateライブラリと言えばCarbonが一番広く知られています。Carbonは ' DateTime ' クラスをベースにしているのに対し、Chronosは ' DateTimeImmutable ' クラスを 拡張して開発されています。

また、Chronosは外部ライブラリに 依存していないのも特徴です。
 

Chronosのインストール

Chronousのインストールは ' composer ' コマンドを使っておこないます。また、インストールされている PHPのバージョンが  " 5.5.9 以上 " 、又は " 7.* "  の必要があります。

# composerを使ってchronosの安定版をインストール
composer require cakephp/chronos "@stable"


Chronosの使い方

Chronosは Carbonを更にシンプルにしたような設計で、 Carbonを使ったことがある人なら ホボ学習コスト0で使うことが出来ると思われます。

タイムインスタンスの作成

use Cake\Chronos\Chronos;

$now = Chronos::now(); // 現在時刻
$today = Chronos::today(); // 当日
$yesterday = Chronos::yesterday();  // 明日
$tomorrow = Chronos::tomorrow(); // 前日

// 文字列から作成
$data = Chronos::parse('2017-07-29 02:30:00');
// 現在日時から 2日後、3時間後で作成
// e.x : 2017/7/29 : 01:00 -> 2017/7/31 04:00
$date = Chronos::parse('+2 days, +3 hours');

// int型から作成
$date = Chronos::create(2017, 7, 29, 10, 35, 50);
$date = Chronos::createFromDate(2017, 7, 29); // 日付 + 現在時刻
$date = Chronos::createFromTime(10, 30, 20); // 日付 + 時間
// 指定フォーマットからインスタンスの作成
$date = Chronos::createFromFormat('m/d/Y', '07/29/2017');

// timezoneをセットする場合
$now = Chronos::now()->timezone("Asia/Tokyo");

// メソッドチェーンでも作成出来ます 2017-07-29 04:30:29.000000
$date = Chronos::create()
          ->year(2017)
          ->month(7)
          ->day(29)
          ->hour(4)
          ->minute(30);


日付の計算

日付計算のメソッドも充実していおり、日にちや時間の足し算・引き算を始め、週や月、その他 色々なメソッドが用意されています。

GitHub : chronos/src/Traits/ModifierTrait.php

use Cake\Chronos\Chronos;

// 2017年7月3日を元に作成 
$date = Chronos::parse('2017-07-03 02:30:00');

// 1日を加算
$date->addDay(1); // 2017-07-04
// 1日の減算
$date->subDay(1); // 2017-07-02
// 土日を除いた日の加算 * 10営業日後
$date->addWeekday(10); // 2017-07-17
// 土日を除いた日の減算 * 10営業日前
$date->subWeekday(10); // 2017-06-19

// 1週間を加算
$date->addWeek(1); // 2017-07-10
// $date->next();

// 1週間を減算
$date->subWeek(1); // 2017-06-26
// $date->previous();

// 一ヶ月を加算
$date->addMonth(1); // 2017-08-03
// 一ヶ月を減算
$date->subMonth(1); // 2017-06-03

// 月初めを取得
$date->firstOfMonth(); // 2017-07-01
// 月終わり
$date->lastOfMonth(); // 2017-07-30

// メソッドチェーンを使う場合
// 2018-07-15 00:25:00.000000
$future = Chronos::create('2017-07-03 02:30:00')
            ->addYear(1) // 1年を加算
            ->subMonth(1) // 1ヶ月を減算
            ->addDays(15) // 15日の加算
            ->addHours(20) // 20時間を加算
            ->subMinutes(2); // 2分を減算


日付の比較 ( compare )

日付の比較、判別のメソッドも用意されており、値がtrueの場合のみ 1 が返されます。例えば  " isWeekDay " メソッドをテンプレートエンジンに通せば、特定のフォームや要素を " 平日のみに表示 " のような使い方も簡単にできます。

$first->eq($second); // 等しい
$first->gte($second);  // 以上
$first->lt($second); // 未満
$first->lt($second); // 未満  or 等しい

// ベースの時間から2つの日付を比較
$now->between($start, $end);

// 近いほうの date valueが返されます
$now->closest($june, $november);
// 遠いほうの date valueが返されます
$now->farthest($june, $november);

// 日付の判別
$now->isToday(); // 当日
$now->isYesterday(); // 前日 
$now->isFuture(); // 未来( 当日より先の場合 )
$now->isPast(); // 過去 ( 当日より以前の場合 )
$now->isWeekday() // 平日 ( 月 - 金 )
$now->isWeekend(); // 週末 ( 土日 )

// 曜日の判別
$now->isMonday(); // 月曜日


差分 ( difference )

2つの日付の差分を比較するメソッドも用意されています。

use Cake\Chronos\Chronos;

$base = Chronos::parse('2017-07-01 01:30:00');
$target = Chronos::parse('2017-07-29 05:30:00');

$base->diff($target); // オブジェクトを返す

// 差分を返します
$base->diffInHours($target); // 676 ( 時間 )
$base->diffInDays($target); // 28 ( 日 )
$base->diffInWeeks($target); // 4 ( 週 )
$base->diffInYears($target); // 0 ( 年 )

// 「○○(日 | 週間 | 年)前」を表示するメソッド * 英語のみに対応
$base->diffForHumans($target); // 4 weeks before


 " diffForHumans " を日本語で返すようにしたメソッドを作ってみました。

use Cake\Chronos\Chronos;

function timeAgo($dateStr, $tz = "Asia/Tokyo")
{
    $keywords = [
      "1 year", "years", "1 month", "months",
      "1 day", "days", "1 hour", "hours",
      "1 minute", "minutes",
      "1 second","seconds",
      "ago", "from now",
      "before", "after", " "
    ];

    $replace = [
      "1年", "年", "1ヶ月", "ヶ月",
      "1日", "日", "1時間", "時間",
      "1分", "分", "1秒", "秒",
      "前", "前", "前", "後", ""
    ];

    $result = Chronos::parse($dateStr)
                 ->timezone($tz)
                 ->diffForHumans(Chronos::now());

    return str_replace($keywords, $replace, $result);
}

echo timeAgo("2017/3/25 4:32:58"); // 4ヶ月前


フォーマット

作成したタイムインスタンスのフォーマットも簡単に変更可能です。RSSなどのフィードを作成する際のタイムフォーマットもメソッド1つで簡単に変換出来ます。

$time = Chronos::parse('2017-07-29 05:30:00')
         ->timezone('Asia/Tokyo');

$time->toTimeString();           // 05:30:00
$time->toDateString();           // 2017-07-29
$time->toDateTimeString();       // 2017-07-29 05:30:00
$time->toFormattedDateString();  // Jul 29, 2017
$time->toDayDateTimeString();    // Sat, Jul 29, 2017 5:30 AM

$time->toWeek(); // 30
$time->toQuarter() // 3

$time->toW3cString();  // 2017-07-29T14:30:00+09:00
$time->toAtomString(); // 2017-07-29T14:30:00+09:00
$time->toCookieString(); // Saturday, 29-Jul-2017 14:30:00 JST
$time->toIso8601String(); // 2017-07-29T14:30:00+09:00
$time->toRfc822String(); // Sat, 29 Jul 17 14:30:00 +0900


時間の抽出

作成した日付の " 年 " や "日にち" の取り出しも簡単にできます。

$time = new Chronos('2017-07-29 05:30:00');

$time->year;    // 2017 ( 年 )
$time->month;   // 7 ( 月 )
$time->day;     // 28 ( 日 )
$time->hour;     // 5 ( 時 )
$time->minute;   // 30 ( 分 )
$time->second;   // 0 ( 秒 )


Summary

以上がChronousの紹介でした。Chronousは CakePHPのプラグインとして提供されているライブラリですが、依存関係無しなので、スタンドアローンでも 簡単に導入・使用ができます。

便利なメソッドが沢山用意されているので、管理システムなどによくある スケジュール機能 などで使うと 開発が楽になりそうです。

GitHub : cakephp/chronos

 

この記事のカテゴリ
プログラミング

この記事のタグ