LoginSignup
5
4

More than 3 years have passed since last update.

Laravel 日付データから年度を取得し配列に入れる

Last updated at Posted at 2020-01-27

やってみた

dateカラムから年度に変換し、重複を削除、値(年度)を降順ソートしました。
dateカラムに存在する年度のみ取得します。

一般的な年度(4月1日~翌年3月31日までを年度)とします。
※2019年を例にすると、2019年4月1日から2020年3月31日までのことを指します。

StatusContoller.php
$dates = Status::pluck('date');
foreach ($dates as $date) {
  $array[] = $date->subMonthsNoOverflow(3)->format('Y');
}
$years = collect($array)->unique()->sort()->reverse()->values();

dd($years);

sort()について

最初、->values()->sortByDesc('date'); でできるかな~と思ってのですが下記のように…
dd($years);の取得結果
image.png
↑ 求めてるソートにならない!なんでだ~~と日本語ドキュメントを見て試行錯誤したのですが、降参!!!

@mpywさんに相談し教えていただきました(いつも有難うございます。)!
値(年度)を降順で表示!
->sort()->reverse()->values();

・pluckの時点で中身取り出している
・sortBy は2次元配列想定してるけど既に1次元配列になってる
・生PHPの場合はsort関数に対応してrsort関数とかあったりはする
・collectionは逆順ソート用のメソッドがないので,昇順ソートしてから配列を逆に並べてる

とのことでした。。
これで求めてる値(年度)のソートになりました!👏
image.png

ちなみにどうしてもsortByDescを使うのであれば、pluckの前につけると使えるみたいですが、
sortByDesc('date')->pluck('date')
メモリ消費するのであまりおすすめできないそうです!

map()を使った方法

コメントより、kiyoamiさんに教えていただきました。

StatusContoller.php

$years = Status::pluck('date')->map(function ($date) {
     return $date->subMonthsNoOverflow(3)->format('Y');
})->unique()->sort()->reverse()->values();

dd($years);

クエリビルダを使った方法

kiyoamiさんに教えていただきました。度々ありがとうございます!
こちらは年度ではなく、年(2020年➡2020年1月1日~2020年12月31日まで)を取得します。

StatusContoller.php

$years = Status::selectRaw('year(`date`) `yyyy`')->distinct()->groupBy('date')->pluck('yyyy');

dd($years);

プルダウンに年度を表示させたい場合

index.blade.php
    <select name="year">
        @foreach($years as $key => $name)
        <option value="{{ $name }}"{{old('year', $year) == $name ? 'selected' : ''}}>{{ $name }}</option>
        @endforeach
    </select>

ひとまずこれで年度を取得し配列に入れて表示する、までは完成です。

次は年度からデータを取得する場合

例えば年度の絞り込みがあったときです。
Statusテーブルのdateカラムから、(任意)年の4月1日~翌年3月31日のデータを取得します。

StatusContoller.php

$year = $request->input('year');
$status = Status::query();

if (!empty($year)) {
     $startAt = CarbonImmutable::createMidnightDate($year, 4, 1);
     $endAt = $startDate->day(1)->addMonths(11)->endOfMonth();
     $status->whereBetween('date', [$startAt, $endAt]);
 }

$year2015が入ってきた場合、$startAt$endAtは以下となります。

dd($startAt);
image.png

dd($endAt);
image.png

参考文献

この記事は以下の情報を参考にしました。

5
4
3

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
5
4