2022/06/14

目次
祝日付きのカレンダーの作成
「code for fun」というサイトを参考に、カレンダーを作成し、祝日表示機能を追加してみました
参考サイト:「code for fun」
まずは、こちらのサイトで基本となることが押さえられているので、参考にしてください。僕は、ほぼほぼこちらのサイトを参考にカレンダーを作り、追加機能として祝日機能を入れました。祝日機能を入れたソースは次に紹介します。
ファイル名:calender.php
<?php // 祝日の読み込み require_once __DIR__ . '/holiday_require.php'; // タイムゾーンの設定 date_default_timezone_set('Asia/Tokyo'); if (isset($_GET['ym'])) { $ym = $_GET['ym']; } else { // 今月の年月を表示 $ym = date('Y-m'); } // タイムスタンプを作成して、フォーマットをチェックする $timestamp = strtotime($ym . '-01'); if ($timestamp === false) { $ym = date('Y-m'); $timestamp = strtotime($ym . '-01'); } // 今月の月を表示 $data = explode('-', $ym); $m = $data[1]; // 今日の日付フォーマット 例)2022-04-1 $today = date('Y-m-j'); // カレンダーのタイトルを作成 例)2022年4月 $html_title = date('Y年n月', $timestamp); // 前月・次月の年月を取得 // strtotimeを使う $prev = date('Y-m', strtotime('-1 month', $timestamp)); $next = date('Y-m', strtotime('+1 month', $timestamp)); // 該当月の日数を取得 $day_count = date('t', $timestamp); // 1日が何曜日か 0:日 1:月 2:火 ... 6:土 $youbi = date('w', $timestamp); // カレンダー作成の準備 $weeks = []; $week = ''; $holiday_count = false; // 祝日用カウンター 例)0:日曜以外 1:日曜 // 第1週目:空のセルを追加 // 例)1日が火曜日だった場合、日・月曜日の2つ分の空セルを追加する $week .= str_repeat('<td></td>', $youbi); for ($day = 1; $day <= $day_count; $day++, $youbi++) { // 2022-04-1 $date = $ym . '-' . $day; // 04-1 $date2 = $m . '-' . $day; if ($today == $date) { // 祝日が日曜の場合 if ($youbi % 7 == 0 && isset($holiday[$date2])) { $week .= '<td class="today"><p title="' . $holiday[$date2] . '">' . $day . "</p>"; $holiday_count = true; } elseif (isset($holiday[$date2])) { // 祝日の場合は、<font color="red"> ~ </font>で囲む $week .= '<td class="today"><font color="red"><p title="' . $holiday[$date2] . '">' . $day . "</p></font>"; } elseif ($youbi % 7 == 1 && $holiday_count == true) { // 祝日が日曜の場合、振替休日を設ける // 振替休日は、<font color="red"> ~ </font>で囲む $week .= '<td class="today"><font color="red"><p title="振替休日">' . $day . "</p></font>"; $holiday_count = false; } else { $week .= '<td class="today">' . $day; } } else { // 祝日が日曜の場合 if ($youbi % 7 == 0 && isset($holiday[$date2])) { $week .= '<td><p title="' . $holiday[$date2] . '">' . $day . "</p>"; $holiday_count = true; } elseif (isset($holiday[$date2])) { // 祝日の場合は、<font color="red"> ~ </font>で囲む $week .= '<td><font color="red"><p title="' . $holiday[$date2] . '">' . $day . "</p></font>"; } elseif ($youbi % 7 == 1 && $holiday_count == true) { // 祝日が日曜の場合、振替休日を設ける // 振替休日は、<font color="red"> ~ </font>で囲む $week .= '<td><font color="red"><p title="振替休日">' . $day . "</p></font>"; $holiday_count = false; } else { $week .= '<td>' . $day; } } $week .= '</td>'; // 週終わり、または、月終わりの場合 if ($youbi % 7 == 6 || $day == $day_count) { if ($day == $day_count) { // 月の最終日の場合、空セルを追加 $week .= str_repeat('<td></td>', 6 - $youbi % 7); } // weeks配列にtrと$weekを追加する $weeks[] = '<tr>' . $week . '</tr>'; // weekをリセット $week = ''; } } ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>完美世界~ぱたぱたままの小屋~`</title> <link rel="icon" href="img/favicon.ico"> <link rel="stylesheet" href="css/style.css"> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap" rel="stylesheet"> <style> .container { font-family: 'Noto Sans Jp', sans-serif; margin-top: 80px; } h3 { margin-bottom: 30px; } th { height: 30px; text-align: center; } td { height: 100px; } .today { background-color: orange !important; } th:nth-of-type(1), td:nth-of-type(1) { color: red; } th:nth-of-type(7), td:nth-of-type(7) { color: blue; } </style> </head> <body> <div class="container"> <h3 class="mb-5"><a href="?ym=<?= $prev; ?>"><</a> <?= $html_title; ?> <a href="?ym=<?= $next; ?>">></a></h3> <table class="table tabule-bordered"> <tr> <th>日</th> <th>月</th> <th>火</th> <th>水</th> <th>木</th> <th>金</th> <th>土</th> </tr> <?php foreach ($weeks as $week) { echo $week . PHP_EOL; } ?> </table> <table class="table tabule-bordered"> <tr> <th> <form method="post" action="index.html"> <input type="submit" value="戻る"> </form> </th> </tr> </table> </div> </body> </html>
祝日が日曜のときは、振替休日を作らなければなりません。そのための処理を次で行っています。
※抜粋
// 04-1 $date2 = $m . '-' . $day; if ($today == $date) { // 祝日が日曜の場合 if ($youbi % 7 == 0 && isset($holiday[$date2])) { $week .= '<td class="today"><p title="' . $holiday[$date2] . '">' . $day . "</p>"; $holiday_count = true; } elseif (isset($holiday[$date2])) { // 祝日の場合は、<font color="red"> ~ </font>で囲む $week .= '<td class="today"><font color="red"><p title="' . $holiday[$date2] . '">' . $day . "</p></font>"; } elseif ($youbi % 7 == 1 && $holiday_count == true) { // 祝日が日曜の場合、振替休日を設ける // 振替休日は、<font color="red"> ~ </font>で囲む $week .= '<td class="today"><font color="red"><p title="振替休日">' . $day . "</p></font>"; $holiday_count = false; } else { $week .= '<td class="today">' . $day; } } else { // 祝日が日曜の場合 if ($youbi % 7 == 0 && isset($holiday[$date2])) { $week .= '<td><p title="' . $holiday[$date2] . '">' . $day . "</p>"; $holiday_count = true; } elseif (isset($holiday[$date2])) { // 祝日の場合は、<font color="red"> ~ </font>で囲む $week .= '<td><font color="red"><p title="' . $holiday[$date2] . '">' . $day . "</p></font>"; } elseif ($youbi % 7 == 1 && $holiday_count == true) { // 祝日が日曜の場合、振替休日を設ける // 振替休日は、<font color="red"> ~ </font>で囲む $week .= '<td><font color="red"><p title="振替休日">' . $day . "</p></font>"; $holiday_count = false; } else { $week .= '<td>' . $day; } } $week .= '</td>';
ここの部分がちょっと複雑になっているので、見やすくしたいのですが、今の僕の技術ではこれが限界です。良い案があれば、コメントでアイデアをいただければと思っていたりします。関数化できそうでできないんですよね、このソース。
ファイル名:holiday_require.php
<?php // 祝日を配列化 $holiday = [ '01-1' => '元旦', '01-10' => '成人の日', '02-11' => '建国記念の日', '02-23' => '天皇誕生日', '03-21' => '春分の日', '04-29' => '昭和の日', '05-3' => '憲法記念日', '05-4' => 'みどりの日', '05-5' => 'こどもの日', '07-18' => '海の日', '08-11' => '山の日', '09-19' => '敬老の日', '09-23' => '秋分の日', '10-10' => 'スポーツの日', '11-3' => '文化の日', '11-23' => '勤労感謝の日', ];
「code for fum」さんのサイトでは、CSVを用いて祝日対応をさせているそうですが、僕は配列で処理しました。案外、祝日って少ないもんですね。今後、祝日が追加変更削除された場合も、ここのファイルを変えるだけで対応することができます。
