search
LoginSignup
4

More than 1 year has passed since last update.

posted at

Laravel Collectionクラスで日付の絞り込みをするときに気をつけること

はじめに

PHPでLaravelのCollectionクラスを利用しているときに、私が以前ハマった問題について共有します。

動作環境

PHP 7.2
laravel/framework 6.0

やりたいこと

日付のカラムを持つデータに対して、○日~△日の間という条件で絞り込みをしたい。

問題のあった書き方

$between_days = getBetweenDays('2020-12-21', '2020-12-23');
foreach ($between_days as $date) {
    var_dump($date->format('Y-m-d'));
}

public function getBetweenDays($start_date, $end_date) {
    $date_list = collect([
        ['date' => new Carbon('2020-12-20')],
        ['date' => new Carbon('2020-12-21')],
        ['date' => new Carbon('2020-12-22')],
        ['date' => new Carbon('2020-12-23')],
        ['date' => new Carbon('2020-12-24')],
    ]);
    return $date_list->whereBetween('date', [$start_date, $end_date])
                     ->pluck('date')
                     ->all();
}

// 結果
// string(10) "2020-12-21"
// string(10) "2020-12-22"

Carbon型にキャストされた日付情報に対して、String型で日付の情報を渡して絞り込みを行っています。
Laravelはかしこいので、こんなゆるい書き方でもエラーを吐かずに処理してくれます。
ですが、出力結果を見てみると、start_date側は境界の日付を含めて取得できていますが、end_date側は境界の日付を取得できていません。
単純なint型で絞り込みを行ったときは境界値を含めた絞り込みになるので、この挙動には問題があることが分かります。

修正した書き方

$between_days = getBetweenDays(new Carbon('2020-12-21'), new Carbon('2020-12-23'));
foreach ($between_days as $date) {
    var_dump($date->format('Y-m-d'));
}

public function getBetweenDays($start_date, $end_date) {
    $date_list = collect([
        ['date' => new Carbon('2020-12-20')],
        ['date' => new Carbon('2020-12-21')],
        ['date' => new Carbon('2020-12-22')],
        ['date' => new Carbon('2020-12-23')],
        ['date' => new Carbon('2020-12-24')],
    ]);
    return $date_list->whereBetween('date', [$start_date, $end_date])
                     ->pluck('date')
                     ->all();
}

// 結果
// string(10) "2020-12-21"
// string(10) "2020-12-22"
// string(10) "2020-12-23"

先程はString型で渡していた絞り込み条件を、予めCarbon型にキャストして絞り込みをしました。
出力結果を見てみると、start_dateもend_dateも境界値を含めて取得できています。

さいごに

Collectionクラスに日付を自動で解釈させると、予期しない挙動をするかもしれない。という内容です。
Laravelの最新版では修正されているかもしれませんが、このような不具合にぶつからない為にも、ちゃんとデータの型を意識して扱おうと思った1件でした。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4