みやもとメモ

「Notion」「Google Apps Script」「ブログカスタマイズ」などについて書いていきます。

目次
目次

【Laravel】カレンダーを作ってみる(Controller側:前月・翌月部分をうまいこと取得する)

この記事をシェアする

今回はLaravelに関して書いていきます。

以前もLaravelに関する記事を書いています(以下リンク)。

miya-moto-memo.hatenablog.com

上記の記事で、CarbonPeriodを活用したカレンダーについて書いています。
プログラムも載せていますが、プログラムの具体的な説明はしませんでした。

今回の記事で、Controller側の実装について具体的に説明してみます。

それでは本題へ。

実行環境

実行環境は、

  • PHP 8.2.12
  • Laravel Framework 11.10.0
  • nesbot/carbon 3.5.0

です。

完成図

まずは完成図を載せておきます。
前回の記事でも載せましたが、改めて。

完成図:カレンダー

プログラム(Controller)

Controller側のプログラムは以下の通りです。
こちらも前回の記事で載せましたが、改めて。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Illuminate\Http\Request;

class CalendarController extends Controller
{
    public function __invoke(Request $request)
    {
        // 当月を取得
        $year = $request->input('year') ?? Carbon::today()->format('Y');
        $month = $request->input('month') ?? Carbon::today()->format('m');
        $thisMonth = Carbon::Create($year, $month, 01, 00, 00, 00);
        // 前月を取得
        $previousMonth = $thisMonth->copy()->subMonth();
        // 翌月を取得
        $nextMonth = $thisMonth->copy()->addMonth();

        // 当月の期間を取得
        $thisMonthPeriod = $this->getThisMonthPeriod($thisMonth);
        // 前月の期間を取得
        $previousMonthPeriod = $this->getPreviousMonthPeriod($thisMonth, $previousMonth);
        // 翌月の期間を取得
        $nextMonthPeriod = $this->getNextMonthPeriod($thisMonth, $nextMonth);

        return view('calendar')
            ->with('thisMonth', $thisMonth)
            ->with('previousMonth', $previousMonth)
            ->with('nextMonth', $nextMonth)
            ->with('thisMonthPeriod', $thisMonthPeriod)
            ->with('previousMonthPeriod', $previousMonthPeriod)
            ->with('nextMonthPeriod', $nextMonthPeriod)
        ;
    }

    /**
     * 当月の期間を取得
     */
    private function getThisMonthPeriod($thisMonth)
    {
        // 月初を取得
        $start = $thisMonth->copy()->startOfMonth();
        // 月末を取得
        $end = $thisMonth->copy()->endOfMonth();
        // 月初~月末の期間を取得
        return CarbonPeriod::create($start->toDateString(), $end->toDateString())->toArray();
    }

    /**
     * 前月の期間を取得
     */
    private function getPreviousMonthPeriod($thisMonth, $previousMonth)
    {
        // 当月の月初が日曜日ならArrayは空で
        if ($thisMonth->copy()->startOfMonth()->isSunday()) {
            return [];
        }
        // 前月の月末から始めて、日曜日になるまで日付を減らしていく
        $start = $previousMonth->copy()->endOfMonth();
        while (!$start->isSunday()) {
            $start->subDays();
        }
        // 前月の月末を取得
        $end = $previousMonth->copy()->endOfMonth();
        // 期間を取得
        return CarbonPeriod::create($start->toDateString(), $end->toDateString())->toArray();
    }

    /**
     * 翌月の期間を取得
     */
    private function getNextMonthPeriod($thisMonth, $nextMonth)
    {
        // 当月の月末が土曜日ならArrayは空で
        if ($thisMonth->copy()->endOfMonth()->isSaturday()) {
            return [];
        }
        // 翌月の月初を取得
        $start = $nextMonth->copy()->startOfMonth();
        // 翌月の月初から始めて、土曜日になるまで日付を増やしていく
        $end = $nextMonth->copy()->startOfMonth();
        while (!$end->isSaturday()) {
            $end->addDays();
        }
        // 期間を取得
        return CarbonPeriod::create($start->toDateString(), $end->toDateString())->toArray();
    }
}

「当月の期間」「前月の期間」「翌月の期間」の取得方法について、それぞれ詳しく書いてみます。

当月の期間

当月の期間を取得するプログラムは以下の通りです。

/**
 * 当月の期間を取得
 */
private function getThisMonthPeriod($thisMonth)
{
    // 月初を取得
    $start = $thisMonth->copy()->startOfMonth();
    // 月末を取得
    $end = $thisMonth->copy()->endOfMonth();
    // 月初~月末の期間を取得
    return CarbonPeriod::create($start->toDateString(), $end->toDateString())->toArray();
}
当月の期間を取得

月初と月末を取得して、その間の期間をCarbonPeriodで取得します。

前月の期間

前月の期間を取得するプログラムは以下の通りです。

/**
 * 前月の期間を取得
 */
private function getPreviousMonthPeriod($thisMonth, $previousMonth)
{
    // 当月の月初が日曜日ならArrayは空で
    if ($thisMonth->copy()->startOfMonth()->isSunday()) {
        return [];
    }
    // 前月の月末から始めて、日曜日になるまで日付を減らしていく
    $start = $previousMonth->copy()->endOfMonth();
    while (!$start->isSunday()) {
        $start->subDays();
    }
    // 前月の月末を取得
    $end = $previousMonth->copy()->endOfMonth();
    // 期間を取得
    return CarbonPeriod::create($start->toDateString(), $end->toDateString())->toArray();
}

「取得する/しない」の2パターンあります。

取得するパターン

取得するパターン

前月の月末から始めて、日曜日になるまで日付を減らしていきます。
当月が「2024年6月」の場合は”2024年5月26日~5月31日”が取得対象となります。
この期間をCarbonPeriodで取得します。

取得しないパターン

取得しないパターン

当月の月初が「日曜日」なら取得しません。

翌月の期間

翌月の期間を取得するプログラムは以下の通りです。

/**
 * 翌月の期間を取得
 */
private function getNextMonthPeriod($thisMonth, $nextMonth)
{
    // 当月の月末が土曜日ならArrayは空で
    if ($thisMonth->copy()->endOfMonth()->isSaturday()) {
        return [];
    }
    // 翌月の月初を取得
    $start = $nextMonth->copy()->startOfMonth();
    // 翌月の月初から始めて、土曜日になるまで日付を増やしていく
    $end = $nextMonth->copy()->startOfMonth();
    while (!$end->isSaturday()) {
        $end->addDays();
    }
    // 期間を取得
    return CarbonPeriod::create($start->toDateString(), $end->toDateString())->toArray();
}

「取得する/しない」の2パターンあります。

取得するパターン

取得するパターン

翌月の月初から始めて、土曜日になるまで日付を増やしていきます。
当月が「2024年6月」の場合は”2024年7月1日~7月6日”が取得対象となります。
この期間をCarbonPeriodで取得します。

取得しないパターン

取得しないパターン

当月の月末が「土曜日」なら取得しません。

おわりに

ということで、「【Laravel】カレンダーを作ってみる(Controller側:前月/翌月部分をうまいこと取得する)」に関してアレコレ書いてみました。

Controller側の実装を進めていきながら、自分の頭の中も整理された感じがありました。
前月と翌月の期間を良い感じに取得できたかなと思います。

現状は「日曜始まり」固定ですが、「月曜始まり」にも対応できそうな気がします。
フラグだけで「日曜始まり」「月曜始まり」を切り替える実装もしてみようかなと思います。

この記事が参考になれば幸いです。

関連記事

Laravelに関してはいくつか記事にしています。
気になる記事があればぜひ。

TOPへ戻る HOMEへ