4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

株式会社デジタルクエストAdvent Calendar 2020

Day 17

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

Posted at

##はじめに
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件でした。

4
4
0

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
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?