指定した年の日付に祝日と旧暦データを合わせ、Laravelで年間カレンダーを表示する流れ

Laravelでカレンダーを作るには、日付を並べる処理と、画面へ表示する処理を分けると組み立てやすくなります。
この記事では、PHPの基本を知っているLaravel初学者に向けて、12か月を表示する考え方と、祝日・六曜の加え方を説明します。
予定の登録やデータベースは使いません。

年を選び、12か月を表示する

年切替と、日付・六曜・祝日を表示する年間カレンダーの画面

完成例は1900〜2100年に対応し、日曜始まりです。PCでは横3か月・縦4段、幅1000px以下では1か月ずつ縦に並べます。
前年・翌年・年入力で切り替え、「今日」で今年の当日まで移動できます。

年間カレンダーを試す

年の受け取りと日付の組み立てを分ける

作る順序は、日付のデータを作るService、そのServiceを呼ぶController、表示するBlade、URLを受け付けるRouteです。
Serviceは日付の計算をまとめるPHPクラスで、HTMLから分けておくと表示を変えるときも計算処理を保てます。

編集先 担当する処理
app/Services/YearCalendar.php 1年分の日付・曜日・暦情報を作る
app/Http/Controllers/CalendarController.php 年を検証してBladeへ渡す
resources/views/tools/calendar.blade.php 年切替と12か月の表を表示する
routes/web.php /calendarをControllerへつなぐ

月ごとの表は、月初の曜日に合わせて空欄を置き、日付を足して7個ずつ区切ります。
次はService内で1か月の配置を作る部分です。

$first = new DateTimeImmutable(sprintf('%04d-%02d-01', $year, $month));
$cells = array_fill(0, (int) $first->format('w'), null);

for ($day = 1; $day <= (int) $first->format('t'); $day++) {
    $cells[] = $day;
}

$weeks = array_chunk(array_pad($cells, 42, null), 7);

wは曜日(日曜が0)、tはその月の日数です。2月の日数も日付処理に任せられます。
42マスにそろえると、すべての月を6週間分の同じ高さにできます。
実際のServiceでは、日付の数字に加えて祝日名や六曜も各マスへ持たせています。

RouteからControllerを呼び、ControllerがServiceの結果をBladeへ渡します。

// routes/web.php
Route::get('/calendar', CalendarController::class)->name('calendar');

// CalendarController内(年の入力検証後)
return view('tools.calendar', $calendar->build($year));

表示年は/calendar?year=2026のようにGETで渡します。
入力欄の制限だけに頼らず、Controllerでも1900〜2100の整数か検証します。

祝日と六曜を日付に重ねる

祝日は振替休日や年ごとの移動があるため、月日を固定した計算で補わず、内閣府の公表データを使います。
UTF-8のCSVを次の形式で用意し、日付をキーにすると、各マスへ祝日名を追加できます。

date,name
2026-01-01,元日
2026-01-12,成人の日

完成例の収録範囲は1955〜2027年です。範囲外は「未収録」と表示し、祝日がない年と区別します。
自分のアプリへ取り込む場合も、データの対象年と更新日を管理してください。

六曜は新暦を6日周期で回すのではなく、旧暦の月日から求めます。
ここではMITライセンスのkyureki-jsonを使い、1931年2月17日〜2100年2月8日の範囲を参考表示にしています。
国立天文台の解説にもあるように、旧暦の定め方には曖昧さがあるためです。データを同梱する際はライセンス文も残します。

Bladeで並べ、今日へ移動できるようにする

BladeはServiceから受け取った月・週・日を順に繰り返し、空欄を含めて表にします。
12か月を囲む要素にCSS Gridを指定すると、表示幅に合わせて列数を変えられます。

.year-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
}
@media (max-width: 1000px) {
    .year-grid { grid-template-columns: 1fr; }
}

「今日」はPHPで日本時間の日付を求め、該当するセルへid="day-2026-11-04"のような目印を付けます。
今年を表示するURLの末尾へそのIDを付ければ、JavaScriptを使わず当日まで移動できます。

<a href="{{ route('calendar') }}#day-{{ $today }}">今日</a>

元号は改元年に「平成31年/令和元年」のように両方を表示します。未来年の元号は現行元号での換算と分かるように添えます。

まとめ

年間カレンダーは、Serviceで日付と暦情報を作り、Bladeで並べる構成にすると整理しやすくなります。
まず日付と年切替を作り、祝日・六曜・元号を順に加えていきましょう。暦データの収録範囲を明示すれば、過去や未来の年も誤解なく表示できます。