【PHP】ある月の初日と末日を取得する方法（DateTimeクラス & Carbon編）

# ある月の初日と末日を取得したい
月初は必ず1日だけど、末日となるとそうはいかない


# `DateTime`クラスを使用した取得方法

```php
date_default_timezone_set('Asia/Tokyo');

$setYear = 2018;
$setMonth = 2;

$date = new DateTime();
$month['first_day'] = $date->setDate($setYear, $setMonth, 1)->format('Y-m-d'); // 日を1で固定値を入れている
$month['last_day']  = $date->setDate($setYear, $setMonth, 1)->format('Y-m-t'); // 日を1で固定値を入れている

var_dump($month);

/* 実行結果

array(2) {
  ["first_day"]=>
  string(10) "2018-02-01"
  ["last_day"]=>
  string(10) "2018-02-28"
}

*/
```

`Y-m-t`の`t`は以下を参照

http://php.net/manual/ja/function.date.php

> t　指定した月の日数。　28 から 31


# [Carbon](https://carbon.nesbot.com/)を使用した取得方法

```php
$setYear = 2018;
$setMonth = 2;

$month['first_day'] = Carbon::create($setYear, $setMonth, 1)->firstOfMonth(); // 日を1で固定値を入れている
$month['last_day']  = Carbon::create($setYear, $setMonth, 1)->lastOfMonth();  // 日を1で固定値を入れている

var_dump($month);

/* 実行結果

array(2) {
  ["first_day"]=>
  string(10) "2018-02-01"
  ["last_day"]=>
  string(10) "2018-02-28"
}

*/

```

# 【要注意】引数は年月日を渡しましょう

`DateTime`クラスの仕様みたいなんですが、
月だけを引数に渡してしまうと、2月などの場合返り値がおかしくなる**タイミング**があるみたいです。

以下は**2018年6月29日**にtinker上でCarbonを実行した結果

```
Psy Shell v0.9.6 (PHP 7.2.5-1+ubuntu18.04.1+deb.sury.org+1 — cli) by Justin Hileman
>>> use Carbon\Carbon;
>>> Carbon::create(2018, 1)->lastOfMonth();
=> Carbon\Carbon @1517356800 {#2846
     date: 2018-01-31 00:00:00.0 UTC (+00:00),
   }
>>> Carbon::create(2018, 2)->lastOfMonth();
=> Carbon\Carbon @1522454400 {#2839
     date: 2018-03-31 00:00:00.0 UTC (+00:00),
   }
>>> Carbon::create(2018, 3)->lastOfMonth();
=> Carbon\Carbon @1522454400 {#2844
     date: 2018-03-31 00:00:00.0 UTC (+00:00),
   }
>>> Carbon::create(2018, 6)->lastOfMonth();
=> Carbon\Carbon @1530316800 {#2847
     date: 2018-06-30 00:00:00.0 UTC (+00:00),
   }
>>> Carbon::create(2018, 2)->daysInMonth;
=> 31
>>>
```

なぜか3月の情報が返ってくる

以下は**2018年7月2日**にtinker上でCarbonを実行した結果

```
Psy Shell v0.9.6 (PHP 7.2.5-1+ubuntu18.04.1+deb.sury.org+1 — cli) by Justin Hileman
>>> use Carbon\Carbon;
>>> Carbon::create(2018, 1)->lastOfMonth();
=> Carbon\Carbon @1517356800 {#2846
     date: 2018-01-31 00:00:00.0 UTC (+00:00),
   }
>>> Carbon::create(2018, 2)->lastOfMonth();
=> Carbon\Carbon @1519776000 {#2839
     date: 2018-02-28 00:00:00.0 UTC (+00:00),
   }
>>> Carbon::create(2018, 3)->lastOfMonth();
=> Carbon\Carbon @1522454400 {#2844
     date: 2018-03-31 00:00:00.0 UTC (+00:00),
   }
>>> Carbon::create(2018, 6)->lastOfMonth();
=> Carbon\Carbon @1530316800 {#2847
     date: 2018-06-30 00:00:00.0 UTC (+00:00),
   }
>>> Carbon::create(2018, 2)->daysInMonth;
=> 28
>>>
```

こちらは正常

どうやら引数にない情報は現時点の情報を使っているらしい。
**2018年6月29日**に実行した際は引数として**`2018, 2, 29`**が渡されているらしく、

```
2018-02-28 + 1 = 2018-03-01 
```
になるみたいです。

なので引数に渡す値は日までちゃんと渡しましょう

# おわり
- [PHPユーザーズ](https://phpusers-ja.slack.com/)の #random チャンネルの皆様ありがとうございました:bow:

# 参考
- [php - How to find the last day of the month from date? - Stack Overflow](https://stackoverflow.com/questions/1686724/how-to-find-the-last-day-of-the-month-from-date)
- [DateTime クラスのまとめメモ - Qiita](https://qiita.com/re-24/items/c3ed814f2e1ee0f8e811)
- [PHPユーザーズ](https://phpusers-ja.slack.com/)の #random チャンネルの皆様