【Laravel】Carbonを初めて使ってみた

　LaravelもPHPも初心者です。
　日付と時間を文字列化する際にPHPのビルトイン関数である[date()](https://www.php.net/manual/ja/function.date.php)が使える事はすぐ分かった
のですが、日付・時刻を操作するためには、Conposerで公開されているパッケージの中に存在
するライブラリである**Carbon**というものを使ったほうが便利だと教えてもらったので、基本的
な使い方をまとめてみようと思います。

#Carbonとは
　PHPに標準実装されている[DateTime](https://www.php.net/manual/ja/class.datetime)クラスを継承した日時を扱うクラス。
　Laravelでも採用されている。

#Carbonインスタンスを生成
##基本的な取得方法

```php
    // インスタンス生成
    $datetime = new Carbon();
```
##引数に文字列を指定すると、様々なインスタンスを取得できる。

```php
    new Carbon('now'); // 今
    new Carbon('today'); // 今日
    new Carbon('tomorrow'); // 明日
    new Carbon('yesterday'); // 昨日

    new Carbon('+1 day'); // １日後
    new Carbon('+3 minutes'); // ３分後
    new Carbon('first day of next month'); // 来月の最初の日

    new Carbon('2020-04-15'); // 2020年4月15日
    new Carbon('2020-04-15 00:00:00'); // 2020年4月15日 00時00分00秒
```
　　**第２引数にはタイムゾーンを指定できる**

```php
    new Carbon('today', 'Asia/Tokyo');
```

#様々なメソッド
##インスタンス生成

```php
    // 現在の日時を取得
    $now = Carbon::now();
    $now = Carbon::now('Asia/Tokyo'); // タイムゾーン付き

    // 「今日の日付」＋「00時00分00秒」を取得
    $today = Carbon::today();
    $today = Carbon::today('Asia/Tokyo'); // タイムゾーン付き

    // 日付からインスタンスを生成
    $year = 2020;
    $month = 4;
    $day = 15;
    $dateTime = Carbon::createFromDate($year, $month, $day);
                                    // 2020-04-15 01:30:30 ※時間は現在時間となる
    
    // 日付と時間からインスタンスを生成
    $hour = 11
    $minute = 11
    $socond = 11
    $dateTime = Carbon::create($year, 
                               $month, 
                               $day, 
                               $hour, 
                               $minute, 
                               $second, 
                               'Asia/Tokyo' // タイムゾーンは指定してもしなくても良い
                               );  // 2020-04-15 11:11:11

```

##出力する
　　　Carbonクラスには__toString()メソッドが実行されていて、echoするだけでデフォルトの
　　フォーマットを返すことができる。もちろんフォーマット指定もできる。

```php
   // 現在の日時を取得
   $now = Carbon::now();

   // echoするだけでデフォルトのフォーマットで出力できる
   echo $now
   //出力結果 → 2020-04-15 01:30:00


   // 指定フォーマットで出力
   echo $now->format('Y_m_d-H_i_s');
   //出力結果 → 2020_04_15-01_30_00


   // int型のUNIXTIMEを返す
   echo $now->getTimestamp();
   //出力結果 → 1586914200
```
####※UNIXTIMEとは
　　　コンピューターシステム上での時刻表現の一種で、**UNIXエポック(協定世界時 (UTC))**
　　での`1970年1月1日午前0時0分0秒`からの経過秒数(ほとんどのシステムでは、本当の
　　経過秒数ではない)として表される。

　　**蛇足な補足：2038年問題について**
　　　　UNIXTIMEは、システム内部では主に32ビットや64ビットの符号付き整数で扱われて
　　　いるが、以前主流だった32ビットで符号付きの場合、その最大値2,147,483,647を
　　　超えると負の値になってしまい、正しく時刻を扱えなくなるという問題がある。
　　　これを2038年問題という。

##時間の加算・減算をする
　　　時間の各単位(**Year,Month,Day,Hour,Minute,Second**...etc)ごとに
　　加算メソッド(add○○○)と減算メソッド(sub○○○)があり、直感的に時間の加算・減算
　　を行うことができるので便利。

```php
    $dateTime = new Carbon('2020-04-15 00:00:00'); // 2020-04-15 00:00:00
    
    // 1日加算
    $dateTime = addDay(); // 2020-04-16 00:00:00
    $dateTime = addDays(1); // 2020-04-17 00:00:00
    // 1日(24時間)加算
    $dateTime = addHours(24); // 2020-04-18 00:00:00

    // 1日減算
    $dateTime = subDay(); // 2020-04-17 00:00:00
    $dateTime = subDays(1); // 2020-04-16 00:00:00

    // 1年加算
    $dateTime = addYear(); // 2021-04-16 00:00:00
    $dateTime = addYears(1); // 2022-04-16 00:00:00
```

##相対時間を表す
　　○年後や○日前などの、現在の時間からどれくらい離れているかを相対時間という。

```php
    $now = new Carbon('2020-04-15 00:00:00');
    $future = new Carbon('2021-04-15 00:00:00');

    // 相対時間を出力
    echo $future->diffForHumans($now);
                 // デフォルトでは英語表記で出力される
    // 出力結果 → 1 year after

    // 相対時間の表示を日本語に変更
    Carbon::setLocale('ja');
    // 相対時間を出力
    echo $future->diffForHumans($now);
                 
    // 出力結果 → 1年後
```

##テストで便利な時刻指定ができる
　　　アプリケーション内で日時を扱う関数を使う場合、その機能のテストを行うためには、
　　該当関数の実行タイミングの時刻を再現できないとテストができない...。
　　　こんなとき、Carbonの**setTestNnow()**メソッドを使って時刻指定をすれば、
　　それ以降に作成された現在時刻のインスタンスは全て指定時刻のインスタンスとして作成
　　できる。

```php
    echo Carbon::now() // 2020-04-15 01:30:00
    
    // 現在時刻を2000年1月1日0時0分0秒に設定
    Carbon::setTestNow('2000-01-01 00:00:00');
    echo Carbon::now() // 2000-01-01 00:00:00

    // 現在時刻を戻す
    Carbon::setTestNow(null);
    echo Carbon::now() // 2020-04-15 01:30:00
```

#参考文献
- [テクナレジ/PHP/Composer/【第1回】PHPで日付や時刻を扱うときに便利なライブラリ「Carbon」：著|ソルダー](https://technoledge.net/composer-carbon/)
- [CONSOLE DOT LOG/全217件！Carbonで時間操作する実例：著|九保すこひ ](https://blog.capilano-fw.com/?p=867)
- [Wikipedia/UNIX時間](https://ja.wikipedia.org/wiki/UNIX%E6%99%82%E9%96%93)