PukiWiki/カレンダーに祝日を入れる

祝日付きカレンダー(2022-09-08)


Pukiwiki の plugin/calendar.inc.phpに手を加えて祝日を赤字で表示します。

…と言っても高度なことをするわけでは無く、あらかじめ休日は自力で調べて配列に書き込んでおいて、該当日を赤くするだけなんです。
どこかのDBから自動で祝日を取ってきたりはしません、年に一回くらいなら手で書けば良い、という程度で。

あと、プレミアムフライデーも表示します。

#calendar1b  (←作り方は後述)

を埋め込むと以下が表示されます。

2022.10 (令和4年 神無月)
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 P 29
30 31          

新しい方のカレンダー関数を使わずにあえて古い plugin/calendar.inc.php がベースなのは、単にリンクとかの機能は不要だったからです。
もし同じように祝日表示(とプレミムフライデー)を求めている方はアイデアのヒントとしてどうぞ。

手順

plugin/calendar.inc.php をコピーして calendar1b を作成します。

$ cp -pi plugin/calendar.inc.php plugin/calendar1b.inc.php

そして変更後のファイルに diff を取った結果が以下

--- plugin/calendar.inc.php     2020-03-05 00:51:13.000000000 +0900
+++ plugin/calendar1b.inc.php   2022-03-10 12:50:58.237577670 +0900
@@ -8,8 +8,45 @@
 //
 // Calendar plugin

-function plugin_calendar_convert()
+function plugin_calendar1b_convert()
 {
+
+$hol_days = array(
+'2022-1-1' => '元旦',
+'2022-1-10'=> '成人の日',
+'2022-2-11'=> '建国記念の日',
+'2022-2-23'=> '天皇誕生日',
+'2022-3-21'=> '春分の日',
+'2022-4-29'=> '昭和の日',
+'2022-5-3' => '憲法記念日',
+'2022-5-4' => 'みどりの日',
+'2022-5-5' => 'こどもの日',
+'2022-7-18'=> '海の日',
+'2022-8-11'=> '山の日',
+'2022-9-19'=> '敬老の日',
+'2022-9-23'=> '秋分の日',
+'2022-10-10'=>'スポーツの日',
+'2022-11-3' =>'文化の日',
+'2022-11-23'=>'勤労感謝の日',
+'2023-1-1'  =>'元旦',        // Fix
+'2023-1-2'  =>'振替休日',
+'2023-1-9'  =>'成人の日',
+'2023-2-11' =>'建国記念の日',// Fix
+'2023-2-23' =>'天皇誕生日',
+'2023-3-21' =>'春分の日',
+'2023-4-29' =>'昭和の日',
+'2023-5-3'  =>'憲法記念日',  // Fix
+'2023-5-4'  =>'みどりの日',  // Fix
+'2023-5-5'  =>'こどもの日',  // Fix
+'2023-7-17' =>'海の日',
+'2023-8-11' =>'山の日',      // Fix
+'2023-9-18' =>'敬老の日',
+'2023-9-23' =>'秋分の日',
+'2023-10-9' =>'スポーツの日',
+'2023-11-3' =>'文化の日',    // Fix
+'2023-11-23'=>'勤労感謝の日',// Fix
+'1999-3-10' =>'テスト'
+);
        global $weeklabels, $vars, $command;

        $script   = get_base_uri();
@@ -68,7 +105,24 @@
        $wday  = $f_today['wday'];
        $day   = 1;

-       $m_name = $year . '.' . $m_num . ' (' . $cmd . ')';
+        // calendar1b: 
+       //$m_name = $year . '.' . $m_num . ' (' . $cmd . ')';
+        $r_year = intval($year) - 2018;
+        switch($m_num){
+            case 1: $m_text = "睦月"; break;
+            case 2: $m_text = "如月"; break;
+            case 3: $m_text = "弥生"; break;
+            case 4: $m_text = "卯月"; break;
+            case 5: $m_text = "皐月"; break;
+            case 6: $m_text = "水無月"; break;
+            case 7: $m_text = "文月"; break;
+            case 8: $m_text = "葉月"; break;
+            case 9: $m_text = "長月"; break;
+            case 10: $m_text = "神無月"; break;
+            case 11: $m_text = "霜月"; break;
+            default: $m_text = "師走"; break;
+        }
+       $m_name = $year . '.' . $m_num . sprintf(' (令和%d年 %s)', $r_year, $m_text);

        $pre = strip_bracket($pre);
        $page_uri = get_page_uri($pre);
@@ -78,7 +132,6 @@
  <tr>
   <td class="style_td_caltop" colspan="7">
    <strong>$m_name</strong><br />
-   [<a href="$page_uri">$pre</a>]
   </td>
  </tr>
  <tr>
@@ -95,6 +148,11 @@
        for ($i = 0; $i < $wday; $i++)
                $ret .= '    <td class="style_td_blank">&nbsp;</td>' . "\n";

+        // calendar1b: get final day, and search final friday.
+        $final_day = intval((new DateTimeImmutable)->modify(sprintf('last day of %04d-%02d', $year, $m_num))->format('d'));
+        $is_premium_friday = 0;
+        $hol_detail = "";
+
        while(checkdate($m_num, $day, $year)) {
                $dt     = sprintf('%04d%02d%02d', $year, $m_num, $day);
                $name   = $prefix . $dt;
@@ -103,8 +161,26 @@

                $refer = ($cmd == 'edit') ? '&amp;refer=' . rawurlencode($page) : '';

+                $is_last_fri = 0;
+               if ($wday == 5 && $day > $final_day - 7) {
+                        // calendar1b: premium Fri!
+                        $is_last_fri = 1;
+                        if($day == $today['mday']) {
+                            $is_premium_friday = 1;
+                        }
+                }
                if ($cmd == 'read' && ! is_page($name)) {
-                       $link = '<strong>' . $day . '</strong>';
+                        // calendar1b: holiday or premium day
+                        $hol_key = sprintf("%d-%d-%d", $year, $m_num, $day);
+                        if(array_key_exists($hol_key, $hol_days)){
+                           $link = '<strong><font color="#ff0066">' . $day . '</font></strong>';
+                            if($day == $today['mday']){
+                                $hol_detail = $hol_days[$hol_key];
+                            }
+                        } else {
+                           $link = '<strong>' . ($is_last_fri > 0 ? 'P' : $day) . '</strong>';
+                           //$link = '<strong>' . ($is_last_fri > 0 ? '<img src=image/face/smile.png />' : $day) . '</strong>';
+                        }
                } else {
                        $link = '<a href="' . $script . '?cmd=' . $cmd .
                                '&amp;page=' . $r_page . $refer . '" title="' .
@@ -149,5 +225,13 @@
        $ret .= '  </tr>'  . "\n" .
                '</table>' . "\n";

+        // calendar1b:
+        if($is_premium_friday > 0){
+           $ret .= '  <b><font color="red">プレミアムフライデー!</font></b><br />'  . "\n";
+        }
+        else if(strlen($hol_detail)){
+           $ret .= '  <b><font color="red">' . $hol_detail . '</font></b><br />'  . "\n";
+        }
+
        return $ret;
 }

これをコピーした calendar1b.inc.php に対して patch -u コマンドで適用してください。
そしてカレンダーを埋め込みたい場所に「#calendar1b」で呼び出します。

祝日になった場合の表示は hol_days 配列最後のテスト日を今日の日付に変えたりずらしたりすることで、動作確認できます。
その hol_days のコメントで「Fix」って書いているように、祝日って固定日と年々変わる日があるから、自動計算のしようが無いんですよね~…

あとは誰かの誕生日とか肉の日(29日)とかの記念日を入れて、遊んでみてください。


プレミアムフライデー(=最終週の金曜日)の特定方法

月の日数も曜日の位置も変わるから難しい…と最初は思っていたのですが、ふと気づけば「最後の7日以内、かつ、金曜日」の日付が最終金曜日になります。

カレンダーが作れそうなプログラミング言語なら曜日やら月ごとの最終日やらを取得する関数ならありそうなので、カレンダーを1~最終日まで描画する間に上記の「最後の7以内、かつ、金曜日」の時だけ文字や色を変えて表示すればプレミアムになります。

同じように、「第二、第四月曜日」とかも「8~14日目か22~28日目に入っていて、かつ、月曜日」とかで探せます。


祝日も頑張れば自動化できるのかもしいれませんが、やっぱり年一くらいでまとめて直に書いた方が早そうです。
前述のスクリプト内にコメント書きしたように(Fixの部分)、固定の祝日って思ったより少ないんですよね。あと、わりと頻繁に位置が変わったり増減したりしている気がしますし、祝日って。