【祝日付き】カレンダーの作成【プログラムの練習】

日常パソコン部
この記事は約19分で読めます。
スポンサーリンク

祝日付きのカレンダーの作成

「code for fun」というサイトを参考に、カレンダーを作成し、祝日表示機能を追加してみました

参考サイト:「code for fun」

まずは、こちらのサイトで基本となることが押さえられているので、参考にしてください。僕は、ほぼほぼこちらのサイトを参考にカレンダーを作り、追加機能として祝日機能を入れました。祝日機能を入れたソースは次に紹介します。

ファイル名:calender.php
<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""><?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></pre>

祝日が日曜のときは、振替休日を作らなければなりません。そのための処理を次で行っています。

※抜粋
<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 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>';</pre>

ここの部分がちょっと複雑になっているので、見やすくしたいのですが、今の僕の技術ではこれが限界です。良い案があれば、コメントでアイデアをいただければと思っていたりします。関数化できそうでできないんですよね、このソース。

ファイル名:holiday_require.php
<pre class="EnlighterJSRAW" data-enlighter-language="php" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""><?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' => '勤労感謝の日',
];
</pre>

code for fum」さんのサイトでは、CSVを用いて祝日対応をさせているそうですが、僕は配列で処理しました。案外、祝日って少ないもんですね。今後、祝日が追加変更削除された場合も、ここのファイルを変えるだけで対応することができます。

¥3,740 (2024/01/03 01:18時点 | Amazon調べ)

コメント

タイトルとURLをコピーしました