PHPで日付時刻処理を書くならCarbonを使うべき


PHPの日付計算って結構厄介な思い出ありませんか？
PHP5.2からDateTimeクラスが登場し幾分マシになりましたが、それでもまだまだなところがあります。

そんな厄介なこともCarbonを使えば解決するかもしれません！

### Carbonとは

[A simple PHP API extension for DateTime.](http://carbon.nesbot.com/)

CarbonとはPHPのDateTimeクラスをオーバーラップした日付操作ライブラリです。

### 流行ってるの？
[Github](https://github.com/briannesbitt/Carbon)では4300を超える☆を獲得していますし、「Laravel」などの人気フレームワークに組み込まれています。

では使い方を見ていきましょう。

### インストール

Composerを使ってインストールします。
Composerをインストールしていない方は、[こちら](https://getcomposer.org/)からお使いの環境に合わせてインストールしましょう。

```
composer require nesbot/carbon
```

### 使い方

#### 現在時刻や指定した日時
```carbon.php
<?php

require 'vendor/autoload.php';

use Carbon\Carbon;

$dt = new Carbon();
echo $dt . "\n"; // 2016-05-01 11:17:38

// スタティック
$dt = Carbon::now();
echo $dt . "\n"; // 2016-05-01 11:17:38

$dt = new Carbon('2016-04-30');
echo $dt . "\n"; // 2016-04-30 00:00:00

$dt = Carbon::today();
echo $dt . "\n"; // 2016-05-01 00:00:00

$dt = Carbon::tomorrow();
echo $dt . "\n"; // 2016-05-02 00:00:00

$dt = Carbon::yesterday();
echo $dt . "\n"; //2016-04-30 00:00:00

$dt = Carbon::parse('2016-04-30 10:32:32');
echo $dt . "\n"; //2016-04-30 10:32:32
```

#### Carbonインスタンスから必要な日時を取得
```carbon.php
<?php

require 'vendor/autoload.php';

use Carbon\Carbon;

$dt = Carbon::now();

echo $dt->year . "\n"; // 2016
echo $dt->month . "\n"; // 5
echo $dt->day. "\n"; // 1
echo $dt->hour . "\n"; // 11
echo $dt->minute . "\n"; // 22
echo $dt->second. "\n"; //56
echo $dt->format('Y年m月d日'); // 2016年05月01日

// 週のうちの何日目か 0 (日曜)から 6 (土曜)
echo $dt->dayOfWeek . "\n"; // 0

// 年のうちの何日目か 0から開始
echo $dt->dayOfYear . "\n"; // 121

// 月のうちの何週目か
echo $dt->weekOfMonth . "\n"; // 1

// 年のうちの何週目か
echo $dt->weekOfYear . "\n"; // 17

// 月の日数
echo $dt->daysInMonth . "\n"; // 31

// 四半期
echo $dt->quarter . "\n"; // 2

// タイムスタンプ
echo $dt->timestamp . "\n"; //1462069596

// タイムゾーン名
echo $dt->tzName . "\n"; // Asia/Tokyo
```

#### 日付の判定
```carbon.php
<?php

require 'vendor/autoload.php';

use Carbon\Carbon;

$dt = Carbon::now();

// 今日かどうか
var_dump($dt->isToday()); // true

// 明日かどうか
var_dump($dt->isTomorrow()); // false

// 昨日かどうか
var_dump($dt->isYesterday()); // false

// 未来かどうか
var_dump($dt->isFuture()); // false

// 過去かどうか
var_dump($dt->isPast()); // false

// うるう年かどうか
var_dump($dt->isLeapYear()); // true

// 平日かどうか
var_dump($dt->isWeekday()); // false

// 週末かどうか デフォルトで土日が週末っぽい。
var_dump($dt->isWeekend()); // true

// 週末の定義
$dt->setWeekendDays([
	Carbon::MONDAY,
	Carbon::TUESDAY,
	Carbon::WEDNESDAY,
	Carbon::THURSDAY,
	Carbon::FRIDAY,
	Carbon::SATURDAY,
	Carbon::SUNDAY,
]);

// 全部設定したのでいつでもtrue
var_dump($dt->isWeekend()); // true


// 同じ日かどうか
var_dump($dt->isSameDay(Carbon::parse('2016-04-30'))); // false

// 日曜かどうか
var_dump($dt->isSunday()); // true

// 月曜かどうか
var_dump($dt->isMonday()); // false

// 火曜かどうか
var_dump($dt->isTuesday()); // false

// 水曜かどうか
var_dump($dt->isWednesday()); // false

// 木曜かどうか
var_dump($dt->isThursday()); // false

// 金曜かどうか
var_dump($dt->isFriday()); // false

// 土曜かどうか
var_dump($dt->isSaturday()); // false

```

#### 日付の比較
```carbon.php
<?php

require 'vendor/autoload.php';

use Carbon\Carbon;

$dt1 = new Carbon('2016-05-01');
$dt2 = new Carbon('2016-06-01');

// イコール
var_dump($dt1->eq($dt2)); // false

// より大きい
var_dump($dt1->gt($dt2)); // false

// 以上
var_dump($dt1->gte($dt2)); // false

// より小さい
var_dump($dt1->lt($dt2)); // true

// 以下
var_dump($dt1->lte($dt2)); // true

// 日付が２つの日付の間にあるか
var_dump(Carbon::parse('2016-05-15')->between($dt1, $dt2)); // true
```


#### 日付の加算減算
```carbon.php
<?php

require 'vendor/autoload.php';

use Carbon\Carbon;

/** 加算 **/

$dt = new Carbon('2016-05-01');

// 1日後
echo $dt->addDay() . "\n"; // 2016-05-02 00:00:00

// 1ヶ月後
echo $dt->addMonth() . "\n"; // 2016-06-02 00:00:00

// 1年後後
echo $dt->addYear() . "\n"; // 2017-06-02 00:00:00

// 1時間後
echo $dt->addHour() . "\n"; // 2017-06-02 01:00:00

// 1秒後
echo $dt->addSecond() . "\n"; // 2017-06-02 01:00:01


$dt = new Carbon('2016-05-01');

// 5日後
echo $dt->addDay(5) . "\n"; // 2016-05-06 00:00:00

// 5ヶ月後
echo $dt->addMonth(5) . "\n"; // 2016-10-06 00:00:00

// 5年後
echo $dt->addYear(5) . "\n"; // 2021-10-06 00:00:00

// 5時間後
echo $dt->addHour(5) . "\n"; // 2021-10-06 05:00:00

// 5秒後
echo $dt->addSecond(5) . "\n"; // 2021-10-06 05:00:05



/** 減算 **/

$dt = new Carbon('2016-05-01');

// 1日前
echo $dt->subDay() . "\n"; // 2016-04-30 00:00:00

// 1ヶ月前
echo $dt->subMonth() . "\n"; // 2016-03-30 00:00:00

// 1年前
echo $dt->subYear() . "\n"; // 2015-03-30 00:00:00

// 1時間前
echo $dt->subHour() . "\n"; // 2015-03-29 23:00:00

// 1秒前
echo $dt->subSecond() . "\n"; // 2015-03-29 22:59:59

$dt = new Carbon('2016-05-01');

// 5日前
echo $dt->subDay(5) . "\n"; // 2016-04-26 00:00:00

// 5ヶ月前
echo $dt->subMonth(5) . "\n"; // 2015-11-26 00:00:00

// 5年前
echo $dt->subYear(5) . "\n"; // 2010-11-26 00:00:00

// 5時間前
echo $dt->subHour(5) . "\n"; // 2010-11-25 19:00:00

// 5秒前
echo $dt->subSecond(5) . "\n"; // 2010-11-25 18:59:55


/** copyメソッド **/
$dt = new Carbon('2016-05-01');

// インスタンスのコピーを作る
echo $dt->copy()->subDay(); // 2016-04-30 00:00:00

// 元のインスタンスには影響がない
echo $dt->subDay(); // 2016-04-30 00:00:00

```

#### 日付の差分
```carbon.php
<?php

require 'vendor/autoload.php';

use Carbon\Carbon;

$dt1 = new Carbon('2016-05-01');
$dt2 = Carbon::parse('2016-05-01')->endOfYear();

// 秒
$dt1->diffInSeconds($dt2); // 21167999秒

// 分
$dt1->diffInMinutes($dt2); // 352799分

// 時間
$dt1->diffInHours($dt2); // 5879時間

// 日
$dt1->diffInDays($dt2); // 244日

// 週
$dt1->diffInWeeks($dt2); // 34週

// 年
$dt1->diffInYears($dt2); // 0年

// 2016-05-01から年末まで平日が何日あるか
echo $dt1->diffInDaysFiltered(function(Carbon $date) {
	return $date->isWeekday();
}, $dt2); // 175日
```


#### 便利系
```carbon.php
<?php

require 'vendor/autoload.php';

use Carbon\Carbon;

// 誕生日の設定
$birthday = Carbon::parse('1987-02-18');

// 年齢
echo $birthday->age . "\n"; //29

```

### Carbonまとめ
以上のCarbonの使い方をみて、直感的で非常に使いやすいと思われたのではないでしょうか？

そのほかにも便利メソッドがたくさんあります。
余力のある方は[公式サイト](http://carbon.nesbot.com/)を御覧ください。