AddinBox(Title_Logo)

  -- Page 3 --

      VBAおよびVB用の祝日判定用マクロ[関数](『kt関数アドイン/kt祝日名取得』の
  ロジックと同じものです)を公開しています。また、VBA用の祝日判定用マクロ[関数]を
  基にして、他言語向けに編集移植したコードを頂きましたので、併せて、このページで
  公開します。

      なお、祝日に関する詳細情報こちらのページをご覧下さい。

      VBA用コードは純粋にVB構文だけ(エクセル独自の機能は使ってません)で作って
    ありますので、エクセルだけでなくアクセスや、その他のVBAを使うアプリケーション
    でも利用できます。
  ※ 重要 ※
    ・ [ 東京五輪 臨時祝日 / 体育の日 改名 ]
      「体育の日」が2020年から「スポーツの日」に改名となります。
      東京五輪特措法により2020年の「海の日/山の日/スポーツの日」が移動となります。
      (2018/6/21)

    ・ [ 生前退位/皇位継承 ]
      平成31年 ( 2019年 ) 4月30日 退位 / 翌5月1日 即位 で決定しました。
      天皇誕生日が [ 12/23 ⇒ 2/3 ] へ変わります(2019年に 天皇誕生日はありません)。
      また、[ 即位礼 正殿の儀 ] は10月22日です。
      (2018/2/15)

 
  ※ 訂正案内 2018/6/21 ※
    下記の言語で 「振替休日の判定」等に誤り がありましたので修正しました。

            [ C , C# , Perl , AWK , Transact-SQL , Python , Go ]

    修正箇所の説明は各言語版の項に記してあります。



※VBA以外に移植したコードも紹介しています※
 ・ 「東京五輪 臨時祝日/体育の日 改名」 改正への対応済みです。 (2018/6/21)
 ・ 「天皇誕生日の変更」 改正への対応済みです。 (2018/2/15)

   [ 旧サイト ( DIONサーバー ) の Internet Archive ( Page 3 ) ]
--言語-- -- 移  植 -- -公開日- -頁-
  ・ 祝日判定マクロ の 設計方針について
  ・ And / Or 演算子 : 完全評価( Complete )型 と 短絡評価( Short-circuit )型
  ・ オーソドックス な 「表引き」 手法との比較
  ・ 祝日判定の拡張 ( 土日も含める 等 ) について
  ・ 拡張マクロ : 銀行休日の判定
  ・ 5月6日 ( 振替休日 ) の判定方法について
 
1
VB/VBA AddinBox(角田) 2002/ 3/16 1
Delphi AddinBox(角田) 2002/11/22
JavaScript AddinBox(角田) 2003/ 5/ 9
OOoBasic AddinBox(角田) 2005/ 4/15

VB2005 Fukuchi  さん 2006/ 7/ 4 2
VBS 立野 徹 さん 2003/ 3/ 2
PHP 代理店どっとこむ「中野」 さん 2003/ 5/ 6

C こほろぎ AsaPi! さん 2003/ 3/ 2 3
C# 小山  隆史 さん 2005/12/17
Perl 富士ソフトサービスビューロ(株)
    BS部 「稲葉」 さん
2003/ 6/ 9
AWK 富士ソフトサービスビューロ(株)
    BS部 「稲葉」 さん
2003/ 6/11

Apollo たけ(tk) さん 2003/ 9/24 4
Ruby たけ(tk) さん 2005/ 4/15
JAVA 阿蛭 栄一 さん 2003/12/21

Transact-SQL シリコンブレス  有方 公一 さん 2006/ 8/ 1 5
PL/SQL 菅 康明 さん 2006/12/ 1
Python 瀬戸口 光宏 さん 2007/ 5/28

ActionScript 3 stocksrc.com  2010/ 3/23 6
Go 言語 杉田 臣輔 さん 2015/ 1/ 6
       
      自由に各自のプログラムに組み込んで利用して下さい。なお、フリー/シェアソフト
    開発での利用も可(フリー/シェアでの利用の場合、事後で結構ですので一言
    お知らせください)です。ただし、引用に当たっては、マクロの先頭に記述してある
        コメント(CopyRight )を必ず一緒に引用する事

    を条件とします。

      なお、他サイト上で本コードを直接引用する事は、ご遠慮願います。本ページへの
    リンクによる紹介で対応して下さい。

      [ktHolidayName]という関数名そのものは、各自の環境における命名規則に沿って
    変更しても構いません
      VBA(VB含む)で利用する場合はマクロのコード構成を一切変更しないでください。
    VBAというレスポンス的に不利な言語でも出来る限りレスポンスを良くする事を前提に
    設計してある為、コード内容を変更するとレスポンスが低下する可能性があります

      VBA以外の言語に移植する場合は、その言語の特性に合わせたベストなコード構成
    変更しても構いません。

    また、出来上がったものをご連絡頂ければ、このページにて紹介させて貰います。

    尚、移植に際しては、And/Orによる条件演算、および[春分の日/秋分の日]算出式の
    INT演算について各言語特性に留意して下さい。また、表引き手法を採らない理由
    御一読ください。



[ Note ]
  Access などで、[Null値]を受け取る/返すといった必要がある場合には、下記のように
『ktHolidayName 』の外側に、もうひとつ関数を被せるようにする事で『ktHolidayName 』
自体は変更せずに利用する事ができます(この場合には、ktHolidayName は'Private'に
して下さい)。尚、下記はVBA(VB)コードによる例です。

Public Function 祝日名(ByVal 日付 As Variant) As Variant
  If IsDate(日付) Then
        祝日名 = ktHolidayName(CDate(日付))
    Else
        祝日名 = Null
    End If
End Function

  その他に「銀行休日」で「土日休み」部分も一緒にフォローしたいといった場合でも
同様の方法で対応できます。

Public Function 祝日_土日(ByVal 日付 As Date) As String
    祝日_土日 = ktHolidayName(日付)
    If (祝日_土日 = "") Then
        Select Case Weekday(日付)
            Case vbSunday: 祝日_土日 = "日"
            Case vbSaturday: 祝日_土日 = "土"
            Case Else
        End Select
    End If
End Function

  このようにする事で[ktHolidayName]のロジック自体を変更せずに、様々な条件を付け加える
事が可能です。引用する際には[ktHolidayName]そのものには手を加えずに、コメントを含めて
丸々コピーするようにしてください。
  ktHolidayName/prv祝日 の内部に処理を追加してしまうと、将来再び祝日法が変更された
場合に、新しいktHolidayName/prv祝日上書き修正により、追加した処理が消えてしま
います。そうならない為にも、ktHolidayName/prv祝日には手を加えずに、その外側にプロシ
ジャーを用意して、そこで機能追加を施すようにして下さい。




[ この場所へのリンク ]


C 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]
  2003/3/2 追記
  2005/5/20 [昭和の日]改正の修正
  2014/5/29 [山の日]改正の修正
  2018/2/15 [天皇誕生日の変更]改正の修正
  2018/6/21 一部修正(下記参照)
  2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正
  2018/6/24 一部修正(下記参照)


      VBAコードのロジックを、そのまま [C ]用に書き直したものです。
    こほろぎ AsaPi!」さんによる編集です(祝日名ではなくフラグを返す仕様です)。

    土日なども一緒に判定するなど条件を付加する場合は、こちらの解説を参考にして下さい。

    『祝日について

    「昭和の日」に伴う「振替休日(5月6日)」改正への修正方針もお読みください。

  --- 修正内容の説明 --------------------------------------
  2018/6/21    : 修正前ソースコード ( Internet Archive )
        振替休日の判定処理に誤りがありました。
            if ((r <= 3) && (ww == 1)){
              [ r : 平日=0, 土曜=1, 日曜=2, 休日=3, 振休=4、, 祝日=5 ]
        [ 休日=3 ] を含まず [ if ((r <= 2) && (ww == 1)){ ] が正しい条件です。

        対象に 3:国民の休日(5月4日:1986〜2006年 , 9月21日(火) or 22日(火):2009年〜 時々)を
        含めた結果、「1987/5/4 (月), 1992/5/4 (月), 1998/5/4 (月)」を「憲法記念日(5/3)の振替休日」と
        誤判定していました(正解は「国民の休日」です)。
        尚、「9月の国民の休日」は常に火曜日となりますので、そこに影響はありません。

        また、併せて コードの整形(インンデント および 演算子前後に空白)を行ないました。

  2018/6/24
        下記の部分で「閉じる括弧 } 」が抜けていました。 6/21のコード整形時に誤って消してしまったようです。
        r = 0;
        if (ww == 6) {
            r = 1;    /* 土曜 */
        } else if (ww == 0) {
            r = 2;    /* 日曜 */
        }
        ← この括弧が抜けていた

  -----------------------------------------------------------


    ----------- C における 曜日値について -----------
        曜日の値は [ 日(0), 月(1), 火(2), 水(3), 木(4), 金(5), 土(6) ] です。
        システム定数は用意されていません。


----------------------------------------------------------------------------------------


#include<stdio.h>
#include<time.h>

/* 土日祝日かどうかを返す関数 
        返り値:平日=0、土曜=1、日曜=2、休日=3、振休=4、祝日=5 */
/*  この関数(含むint Syunbun()、int Syubun())は、
    http://addinbox.sakura.ne.jp/
  の祝日判定ロジック(VBA版)を利用して作ったものです。*/


/*
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/
_/  --- C 言語 移植版 ---
_/
_/  CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
_/  ( AddinBox http://addinbox.sakura.ne.jp/index.htm )
_/  (   旧サイト http://www.h3.dion.ne.jp/~sakatsu/index.htm )
_/
_/  この祝日マクロは『kt関数アドイン』で使用しているものです。
_/  このロジックは、レスポンスを第一義として、可能な限り少ない
_/  【条件判定の実行】で結果を出せるように設計してあります。
_/
_/  この関数では以下の祝日変更までサポートしています。
_/  ・2019年施行の「天皇誕生日の変更」 12/23⇒2/23 (補:2019年には[天皇誕生日]はありません)
_/  ・2020年施行の「体育の日の改名」⇒スポーツの日
_/  ・五輪特措法による2020年の「祝日移動」
_/      海の日:7/20(3rd Mon)⇒7/23, スポーツの日:10/12(2nd Mon)⇒7/24, 山の日:8/11⇒8/10
_/
_/  下記2つについては未だ法整備自体が行なわれていませんので未対応です。
_/  ・2019年の退位日(4/30)/即位日(5/1)
_/  ・2019年の「即位の礼 正殿の儀 (10/22) 」
_/
_/  (*1)このマクロを引用するに当たっては、必ずこのコメントも
_/      一緒に引用する事とします。
_/  (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
_/      【 http://addinbox.sakura.ne.jp/holiday_logic.htm 】
_/      へのリンクによる紹介で対応して下さい。
_/  (*3)[ktHolidayName]という関数名そのものは、各自の環境に
_/      おける命名規則に沿って変更しても構いません。
_/ 
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
*/


int Syunbun(int yy); /* 春分の日を返す関数 */
int Syubun(int yy); /* 秋分の日を返す関数 */

int Holiday(const time_t t) {
    int yy;
    int mm;
    int dd;
    int ww;
    int r;
    struct tm *Hizuke;
    const time_t SYUKUJITSU=-676976400;   /* 祝日法施行 1948年7月20日 */
    const time_t FURIKAE=103388400;   /* 振替休日施行 1973年04月12日 */

    Hizuke = localtime(&t);

    yy = Hizuke->tm_year + 1900;    /* 4桁 西暦年 */
    mm = Hizuke->tm_mon + 1;    /* 月:1〜12 */
    dd = Hizuke->tm_mday;
    ww = Hizuke->tm_wday;    /* 日(0), 月(1) ... 土(6) */

    r = 0;
    if (ww == 6) {
        r = 1;    /* 土曜 */
    } else if (ww == 0) {
        r = 2;    /* 日曜 */
    }

    if (t < SYUKUJITSU) {
        return r;     /* 祝日法施行 以前 */
    }

    switch (mm) {
    /* 1月 */
    case 1:
        if (dd == 1) {
            r = 5;   /* 元日 */
        } else {
            if (yy >= 2000) {
                if (((int)((dd - 1) / 7) == 1) && (ww == 1)) {     /* 2nd Monday */
                    r = 5;   /* 成人の日 */
                }
            } else {
                if (dd == 15) {
                    r = 5;   /* 成人の日 */
                }
            }
        }
        break;

    /* 2月 */
    case 2:
        if (dd == 11) {
            if (yy >= 1967) {
                r = 5;   /* 建国記念の 日*/
            }
        } else if (dd == 23) {
            if (yy >= 2020) {
                r = 5;   /* 天皇誕生日 */
            }
        } else if ((yy == 1989) && (dd == 24)) {
            r = 5;   /* 昭和天皇の大喪の礼 */
        }
        break;

    /* 3月 */
    case 3:
        if (dd == Syunbun(yy)) {
            r = 5;   /* 春分の日 */
        }
        break;

    /* 4月 */
    case 4:
        if (dd == 29) {
            if (yy >= 2007) {
                r = 5;   /* 昭和の日 */
            } else if (yy >= 1989) {
                r = 5;   /* みどりの日 */
            } else {
                r = 5;   /* 天皇誕生日 (昭和天皇) */
            }
        } else if ((yy == 1959) && (dd == 10)) {
            r = 5;   /* 皇太子明仁親王の結婚の儀 */
        }
        break;

    /* 5月 */
    case 5:
        if (dd == 3) {
            r = 5;   /* 憲法記念日 */
        } else if (dd == 4) {
            if (yy >= 2007) {
                r = 5;   /* みどりの日 */
            } else if (yy >= 1986) {
                /* 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年) */
                if (ww > 1) {   /* 火曜日 以降(火〜土) */
                    r = 3;   /* 国民の休日 */
                }
            }
        } else if (dd == 5) {
            r = 5;   /* こどもの日 */
        } else if (dd == 6) {
            /* [5/3,5/4が日曜]ケースのみ、ここで判定 */
            if ((yy >= 2007) && ((ww == 2) || (ww == 3))) {
                r = 4;   /* 振替休日 */
            }
        }
        break;

    /* 6月 */
    case 6:
        if ((yy == 1993) && (dd == 9)) {
            r = 5;   /* 皇太子徳仁親王の結婚の儀 */
        }
        break;

    /* 7月 */
    case 7:
        if (yy >= 2021) {
            if (((int)((dd - 1) / 7) == 2) && (ww == 1)) {    /* 3rd Monday */
                r = 5;   /* 海の日 */
            }
        } else if (yy == 2020) {
            /* 2020年はオリンピック特措法により */
            /*「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動 */
            if (dd == 23) {
                r = 5;   /* 海の日 */
            } else if (dd == 24) {
                r = 5;   /* スポーツの日 */
            }
        } else if (yy >= 2003) {
            if (((int)((dd - 1) / 7) == 2) && (ww == 1)) {    /* 3rd Monday */
                r = 5;   /* 海の日 */
            }
        } else if (yy >= 1996) {
            if (dd == 20) {
                r = 5;   /* 海の日 */
            }
        }
        break;

    /* 8月 */
    case 8:
        if (yy >= 2021) {
            if (dd == 11) {
                r = 5;   /* 山の日 */
            }
        } else if (yy == 2020) {
            /* 2020年はオリンピック特措法により「山の日」が 8/10 に移動 */
            if (dd == 10) {
                r = 5;   /* 山の日 */
            }
        } else if (yy >= 2016){
            if (dd == 11){
                r = 5;   /* 山の日 */
            }
        }
        break;

    /* 9月 */
    case 9:
        if (dd == Syubun(yy)) {
            r = 5;   /* 秋分の日 */
        } else {
            if (yy >= 2003) {
                if (((int)((dd - 1) / 7) == 2) && (ww == 1)) {     /* 3rd Monday */
                    r = 5;   /* 敬老の日 */
                } else if (ww == 2) {   /* 火曜日 */
                    if (dd == Syubun(yy) - 1) {
                        r = 3;   /* 国民の休日 , 火曜日&[秋分日の前日]*/
                    }
                }
            } else if (yy >= 1966) {
                if (dd == 15) {
                    r = 5;   /* 敬老の日 */
                }
            }
        }
        break;

    /* 10月 */
    case 10:
        if (yy >= 2021) {
            if (((int)((dd - 1) / 7) == 1) && (ww == 1)) {    /* 2nd Monday */
                r = 5;   /* スポーツの日 , 2020年より改名 */
            }
        } else if (yy == 2020) {
            /* 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動 */
        } else if (yy >= 2000) {
            if (((int)((dd - 1) / 7) == 1) && (ww == 1)) {    /* 2nd Monday */
                r = 5;   /* 体育の日 */
            }
        } else if (yy >= 1966) {
            if (dd == 10) {
              r = 5;   /* 体育の日 */
            }
        }
        break;

    /* 11月 */
    case 11:
        if (dd == 3) {
            r = 5;   /* 文化の 日*/
        } else if (dd == 23) {
            r = 5;   /* 勤労感謝の日 */
        } else if ((yy == 1990) && (dd == 12)) {
            r = 5;   /* 即位礼正殿の儀 (平成天皇) */
        }
        break;

    /* 12月 */
    case 12:
        if (dd == 23) {
            if ((yy >= 1989) && (yy <= 2018)) {
                r = 5;   /* 天皇誕生日 (平成天皇) */
            }
        }
    }

    /* ----- 振替休日の判定 (振替休日施行日:1973/4/12) -----
    [ 対象日≠祝日/休日 & 対象日=月曜日 ]のみ、前日(=日曜日)を祝日判定する。
    前日(=日曜日)が祝日の場合は”振替休日”となる。
    尚、5月6日の扱いを
        「火曜 or 水曜(みどりの日(5/4) or 憲法記念日(5/3)の振替休日)」⇒5月ブロック内で判定済
        「月曜(こどもの日(5/5)の振替休日」⇒ここの判定処理で判定
    とする事により、ここでの判定対象は『対象日が月曜日』のみ となります。*/


    if ((r <= 2) && (ww == 1)) {    /* [r : 平日=0, 土曜=1, 日曜=2, 休日=3, 振休=4、, 祝日=5] [ww : 1(月)] */
        if (t >= FURIKAE) {
            if (Holiday(t - 86400) == 5) {    /* 再帰呼出 */
                r = 4;    /* 振替休日 */
            }
        }
    }
    return r;
}

/* 春分/秋分日の略算式は
    『海上保安庁水路部 暦計算研究会編 新こよみ便利帳』
  で紹介されている式です。 */


/* 春分の日を返す関数 */
int Syunbun(int yy) {
    int dd;
    if (yy <= 1947) {
        dd = 99;  /* 祝日法施行前 */
    } else if (yy <= 1979) {
        dd = (int)(20.8357 + (0.242194 * (yy - 1980)) - (int)((yy - 1983) / 4));
    } else if (yy <= 2099) {
        dd = (int)(20.8431 + (0.242194 * (yy - 1980)) - (int)((yy - 1980) / 4));
    } else if (yy <= 2150) {
        dd = (int)(21.851 + (0.242194 * (yy - 1980)) - (int)((yy - 1980) / 4));
    } else {
        dd = 99;  /* 2151年以降は略算式が無いので不明 */
    }
    return dd;
}

/* 秋分の日を返す関数 */
int Syubun(int yy){
    int dd;
    if (yy <= 1947) {
        dd = 99;  /* 祝日法施行前 */
    } else if (yy <= 1979) {
        dd = (int)(23.2588 + (0.242194 * (yy - 1980)) - (int)((yy - 1983) / 4));
    } else if (yy <= 2099) {
        dd = (int)(23.2488 + (0.242194 * (yy - 1980)) - (int)((yy - 1980) / 4));
    } else if (yy <= 2150) {
        dd = (int)(24.2488 + (0.242194 * (yy - 1980)) - (int)((yy - 1980) / 4));
    } else {
        dd = 99;  /* 2151年以降は略算式が無いので不明 */
    }
    return dd;
}




[ この場所へのリンク ]


C# 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]
  2005/12/17 追記 ( [昭和の日]改正対応済 )
  2007/ 5/28  不具合修正(下記参照)
  2007/11/21  不具合修正(下記参照)
  2014/ 5/29  [山の日]改正の修正
  2018/ 2/15  [天皇誕生日の変更]改正の修正
  2018/ 6/21  一部修正(下記参照)
  2018/ 6/21  [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正


    VBAコードのロジックを、そのまま[C# ]用に書き直したものです。
    小山  隆史さん 」による編集です。

    土日なども一緒に判定するなど条件を付加する場合は、こちらの解説を参考にして下さい。

    『祝日について

    「昭和の日」に伴う「振替休日(5月6日)」改正への修正方針もお読みください。

  --- 修正内容の説明 --------------------------------------
  2007/5/28
        祝日名が '元' になっていたのを '元日' に修正しました。

  2007/11/21
        5月6日の判定処理で [ Tuesday or Wednesday ] とするべきところが [ Wednesday or Thursday ] に
        なっていましたので修正しました

  2018/6/21    : 修正前ソースコード ( Internet Archive )
        振替休日の判定処理に誤りがありました。
        if ((result.holiday == HolidayInfo.HOLIDAY.WEEKDAY
                || result.holiday == HolidayInfo.HOLIDAY.HOLIDAY) && 
            (ww == DayOfWeek.Monday)) {

        [ HolidayInfo.HOLIDAY.HOLIDAY ] 判定が余計です。正しい条件は下記です。
              if ((result.holiday == HolidayInfo.HOLIDAY.WEEKDAY) && (ww == DayOfWeek.Monday)) {
              または  if (string.IsNullOrEmpty(result.name) && (ww == DayOfWeek.Monday)) {
        string.IsNullOrEmpty の方で修正します。

        対象に国民の休日(5月4日:1986〜2006年 , 9月21日(火) or 22日(火):2009年〜 時々)を
        含めた結果、「1987/5/4 (月), 1992/5/4 (月), 1998/5/4 (月)」を「憲法記念日(5/3)の振替休日」と
        誤判定していました(正解は「国民の休日」です)。
        尚、「9月の国民の休日」は常に火曜日となりますので、そこに影響はありません。

        また、併せて コードの整形(インンデント および 演算子前後に空白)を行ないました。

  ---------------------------------------------------------------------------------

    ----------- C# における 曜日値について -----------
        曜日の値は [ 日(0), 月(1), 火(2), 水(3), 木(4), 金(5), 土(6) ] です。
        システム定数の [ DayOfWeek.Sunday, DayOfWeek.Monday, … DayOfWeek.Saturday ] が利用できます。



----------------------------------------------------------------------------------------

/*
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/
_/  --- C# 移植版 ---
_/
_/  CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
_/  ( AddinBox  http://addinbox.sakura.ne.jp/index.htm )
_/  (    旧サイト  http://www.h3.dion.ne.jp/~sakatsu/index.htm )
_/
_/  この祝日マクロは『kt関数アドイン』で使用しているものです。
_/  このロジックは、レスポンスを第一義として、可能な限り少ない
_/  【条件判定の実行】で結果を出せるように設計してあります。
_/
_/  この関数では以下の祝日変更までサポートしています。
_/  ・2019年施行の「天皇誕生日の変更」 12/23⇒2/23 (補:2019年には[天皇誕生日]はありません)
_/  ・2020年施行の「体育の日の改名」⇒スポーツの日
_/  ・五輪特措法による2020年の「祝日移動」
_/      海の日:7/20(3rd Mon)⇒7/23, スポーツの日:10/12(2nd Mon)⇒7/24, 山の日:8/11⇒8/10
_/
_/  下記2つについては未だ法整備自体が行なわれていませんので未対応です。
_/  ・2019年の退位日(4/30)/即位日(5/1)
_/  ・2019年の「即位の礼 正殿の儀 (10/22) 」
_/
_/  (*1)このマクロを引用するに当たっては、必ずこのコメントも
_/      一緒に引用する事とします。
_/  (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
_/      【 http://addinbox.sakura.ne.jp/holiday_logic.htm 】
_/      へのリンクによる紹介で対応して下さい。
_/  (*3)[ktHolidayName]という関数名そのものは、各自の環境に
_/      おける命名規則に沿って変更しても構いません。
_/
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
*/

/*  VBA用コードを書き直した「こほろぎ AsaPi! さん編集 [C ]用コード」を
    更に[ C# ]用に書き直したものです。「小山 隆史さん」さんによる編集です。 */

/*  2005/12/03 C# 2.0 Version by Takashi Oyama (lepton@hmsoft.co.jp)
    1.判定メソッドを HolidayChecker のメンバーメソッドとした。
        メソッド名はそのままとした。
    2.祝日判定メソッドの戻り値を、曜日と祝日と名称を含むクラスとした。
    注;名前空間は適当に変更して使ってください。  */


using System;
using System.Collections.Generic;
using System.Text;

namespace GenCalendar
{
    static class HolidayChecker
    {
        // 春分の日を返すメソッド
        public  static int Syunbun(int yy) {
            int dd;
            if (yy <= 1947) {
                dd = 99;  // 祝日法施行前
            } else if (yy <= 1979) {
                dd = (int)(20.8357 + (0.242194 * (yy - 1980)) - (int)((yy - 1983) / 4));
            } else if (yy <= 2099) {
                dd = (int)(20.8431 + (0.242194 * (yy - 1980)) - (int)((yy - 1980) / 4));
            } else if (yy <= 2150) {
                dd = (int)(21.851 + (0.242194 * (yy - 1980)) - (int)((yy - 1980) / 4));
            } else {
                dd = 99;  // 2151年以降は略算式が無いので不明
            }
            return dd;
        }

        // 秋分の日を返すメソッド
        public  static int Syubun(int yy) {
            int dd;
            if (yy <= 1947) {
                dd = 99;  // 祝日法施行前
            } else if (yy <= 1979) {
                dd = (int)(23.2588 + (0.242194 * (yy - 1980)) - (int)((yy - 1983) / 4));
            } else if (yy <= 2099) {
                dd = (int)(23.2488 + (0.242194 * (yy - 1980)) - (int)((yy - 1980) / 4));
            } else if (yy <= 2150) {
                dd = (int)(24.2488 + (0.242194 * (yy - 1980)) - (int)((yy - 1980) / 4));
            } else {
                dd = 99;  // 2151年以降は略算式が無いので不明
            }
            return dd;
        }

        // 祝日情報(戻り値)
        public  struct HolidayInfo {
            public enum HOLIDAY {
                WEEKDAY=0,  // 平日
                HOLIDAY=1,  // 休日
                C_HOLIDAY=2,  // 振休
                SYUKUJITSU=3,  // 祝日
            };
            public HOLIDAY holiday;  // その日の種類
            public DayOfWeek week;  // その日の曜日
            public String name;  // その日に名前が付いている場合はその名前。
        };

        private static readonly DateTime SYUKUJITSU = new DateTime(1948, 7, 20);  // 祝日法施行日
        private static readonly DateTime FURIKAE = new DateTime(1973, 07, 12);  // 振替休日制度の開始日

        // その日が何かを調べるメソッド
        public  static HolidayInfo Holiday(DateTime t) {
            int yy = t.Year;
            int mm = t.Month;   // 月(1〜12)
            int dd = t.Day;
            DayOfWeek ww = t.DayOfWeek;   // 日(0), 月(1) ... 土(6)

            HolidayInfo result = new HolidayInfo();
            result.week = ww;
            result.holiday = HolidayInfo.HOLIDAY.WEEKDAY;

            // 祝日法施行以前
            if (t < SYUKUJITSU) return result;

            switch (mm) {
            // 1月 //
            case 1:
                if (dd == 1) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="元日";
                } else {
                    if (yy >= 2000) {
                        if (((int)((dd - 1) / 7) == 1) && (ww == DayOfWeek.Monday)) {   // 2nd Monday
                            result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                            result.name="成人の日";
                        }
                    } else {
                        if (dd == 15) {
                            result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                            result.name="成人の日";
                        }
                    }
                }
                break;

            // 2月 //
            case 2:
                if (dd == 11) {
                    if (yy >= 1967) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="建国記念の日";
                    }
                } else if (dd == 23) {
                    if (yy >= 2020) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="天皇誕生日";
                    }
                } else if ((yy == 1989) && (dd == 24)) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="昭和天皇の大喪の礼";
                }
                break;

            // 3月 //
            case 3:
                if (dd == Syunbun(yy)) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="春分の日";
                }
                break;

            // 4月 //
            case 4:
                if (dd == 29) {
                    if (yy >= 2007) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="昭和の日";
                    } else if (yy >= 1989) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="みどりの日";
                    } else {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="天皇誕生日";  // 昭和天皇
                    }
                } else if ((yy == 1959) && (dd == 10)) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="皇太子明仁親王の結婚の儀";
                }
                break;

            // 5月 //
            case 5:
                if (dd == 3) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="憲法記念日";
                } else if (dd == 4) {
                    if (yy >= 2007) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="みどりの日";
                    } else if (yy >= 1986) {
                        // 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年)
                        if (ww > DayOfWeek.Monday) {  // 火曜 以降(火〜土)
                            result.holiday=HolidayInfo.HOLIDAY.HOLIDAY;
                            result.name="国民の休日";
                        }
                    }
                } else if (dd == 5) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="こどもの日";
                } else if (dd == 6) {
                    // [5/3,5/4が日曜]ケースのみ、ここで判定
                    if ((yy >= 2007) && ((ww == DayOfWeek.Tuesday) || (ww == DayOfWeek.Wednesday))) {
                        result.holiday=HolidayInfo.HOLIDAY.C_HOLIDAY;
                        result.name="振替休日";
                    }
                }
                break;

            // 6月 //
            case 6:
                if ((yy == 1993) && (dd == 9)) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="皇太子徳仁親王の結婚の儀";
                }
                break;

            // 7月 //
            case 7:
                if (yy >= 2021) {
                    if (((int)((dd - 1) / 7) == 2) && (ww == DayOfWeek.Monday)) {  // 3rd Monday
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="海の日";
                    }
                } else if (yy == 2020) {
                    // 2020年はオリンピック特措法により
                    //「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
                    if (dd == 23) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="海の日";
                    } else if (dd == 24) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="スポーツの日";
                    }
                } else if (yy >= 2003){
                    if (((int)((dd - 1) / 7) == 2) && (ww == DayOfWeek.Monday)) {  // 3rd Monday
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="海の日";
                    }
                } else if (yy >= 1996) {
                    if (dd == 20) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="海の日";
                    }
                }
                break;

            // 8月 //
            case 8:
                if (yy >= 2021) {
                    if (dd == 11) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="山の日";
                    }
                } else if (yy == 2020) {
                    // 2020年はオリンピック特措法により「山の日」が 8/10 に移動
                    if (dd == 10) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="山の日";
                    }
                } else if (yy >= 2016) {
                    if (dd == 11) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="山の日";
                    }
                }
                break;

            // 9月 //
            case 9:
                if (dd == Syubun(yy)) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="秋分の日";
                } else {
                    if (yy >= 2003) {
                        if (((int)((dd - 1) / 7) == 2) && (ww == DayOfWeek.Monday)) {   // 3rd Monday
                            result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                            result.name="敬老の日";
                        } else if (ww == DayOfWeek.Tuesday) {
                            if (dd == (Syubun(yy) - 1)) {
                                result.holiday=HolidayInfo.HOLIDAY.HOLIDAY;
                                result.name="国民の休日";  // 火曜日&[秋分日の前日]
                            }
                        }
                    } else if (yy >= 1966) {
                        if (dd == 15) {
                            result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                            result.name="敬老の日";
                        }
                    }
                }
                break;

            // 10月 //
            case 10:
                if (yy >= 2021) {
                    if (((int)((dd - 1) / 7) == 1) && (ww == DayOfWeek.Monday)) {  // 2nd Monday
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="スポーツの日";    // 2020年より改名
                    }
                } else if (yy == 2020) {
                    // 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
                } else if (yy >= 2000) {
                    if (((int)((dd - 1) / 7) == 1) && (ww == DayOfWeek.Monday)) {  // 2nd Monday
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="体育の日";
                    }
                } else if (yy >= 1966) {
                    if (dd == 10) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="体育の日";
                    }
                }
                break;

            // 11月 //
            case 11:
                if (dd == 3) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="文化の日";
                } else if (dd == 23) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="勤労感謝の日";
                } else if ((yy == 1990) && (dd == 12)) {
                    result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                    result.name="即位礼正殿の儀";  // 平成天皇
                }
                break;

            // 12月 //
            case 12:
                if (dd == 23) {
                    if ((yy >= 1989) && (yy <= 2018)) {
                        result.holiday=HolidayInfo.HOLIDAY.SYUKUJITSU;
                        result.name="天皇誕生日";  // 平成天皇
                    }
                }
                break;

            default:
                break;
            }

            // ----- 振替休日の判定 (振替休日施行日:1973/4/12) -----
            // [ 対象日≠祝日/休日 & 対象日=月曜日 ]のみ、前日(=日曜日)を祝日判定する。
            // 前日(=日曜日)が祝日の場合は”振替休日”となる。
            // 尚、5月6日の扱いを
            //     「火曜 or 水曜(みどりの日(5/4) or 憲法記念日(5/3)の振替休日)」⇒5月ブロック内で判定済
            //     「月曜(こどもの日(5/5)の振替休日」⇒ここの判定処理で判定
            // とする事により、ここでの判定対象は『対象日が月曜日』のみ となります。

            if (string.IsNullOrEmpty(result.name) && (ww == DayOfWeek.Monday)) {
                if (t >= FURIKAE) {    // 振替休日施行以降
                    if (Holiday( t.AddDays(-1) ).holiday == HolidayInfo.HOLIDAY.SYUKUJITSU) {    // 再帰呼出
                        result.holiday = HolidayInfo.HOLIDAY.C_HOLIDAY;
                        result.name="振替休日";
                    }
                }
            }

            return result;
        }
    }
}



[ この場所へのリンク ]


Perl 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]
  2003/6/9 追記
  2005/5/20 [昭和の日]改正の修正
  2011/3/15 注意事項を記載
  2011/5/12 [祝日名]も取得可能に修正
  2014/5/29 [山の日]改正の修正
  2018/2/15 [天皇誕生日の変更]改正の修正
  2018/6/21 一部修正(下記参照)
  2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正
  2018/6/24 一部修正(下記参照)


    VBAコードのロジックから移植した [ C 版 ] を [Perl ]用に書き直したものです。
    富士ソフトサービスビューロ(株) BS部「稲葉」さんによる編集です。

    土日なども一緒に判定するなど条件を付加する場合は、こちらの解説を参考にして下さい。

    『祝日について

    「昭和の日」に伴う「振替休日(5月6日)」改正への修正方針もお読みください。

    〜 Perl版「祝日判定スクリプト」を利用する際の注意事項 〜 (2011/3/15 追記)
    Perl版「祝日判定スクリプト」の引数に指定するエポック秒を計算する為に timegm/timelocal を使用する際には、
    必ず『4桁西暦年』を使うようにしてください(尚、現在の祝日計算で1899年以前は対象外ですから、解説にある
    「マイナス オフセット年($year-1900)」の処理は必要ありません)。

    timegm/timelocal について、多くの解説書・解説HPが紹介している「1900を引く ( $year - 1900 )」という使い方
    (70 イコール 1970年 等という風に固定されているといった認識)は、timegm/time local 本来の仕様からすれば
    誤解を含んだ使い方です。Perl が世に出て以降、現在まで「偶々、その方法でも上手くいっていた」というだけです。
    この事に関する詳細な解説は下記を参照してください。
        〜 timegm/timelocal で、「年」引数の仕様の正しい理解と使い方について 〜
    この祝日判定スクリプトは 1900年代の日付 もカバーしていますので、timegm/timelocalで引数に渡すエポック秒
    を算出する際には「4桁西暦年」を使用してください。


  --- 修正内容の説明 --------------------------------------
  2018/6/21    : 修正前ソースコード ( Internet Archive )
        振替休日の判定処理に誤りがありました。
            if (($r[0] <= 3) && ($ww == 1)){
              [ $r[0] : 平日=0, 土曜=1, 日曜=2, 休日=3, 振休=4、, 祝日=5 ]
        [ 休日=3 ] を含まず [ if (($r[0] <= 2) && ($ww == 1)){ ] が正しい条件です。

        対象に 3:国民の休日(5月4日:1986〜2006年 , 9月21日(火) or 22日(火):2009年〜 時々)を
        含めた結果、「1987/5/4 (月), 1992/5/4 (月), 1998/5/4 (月)」を「憲法記念日(5/3)の振替休日」と
        誤判定していました(正解は「国民の休日」です)。
        尚、「9月の国民の休日」は常に火曜日となりますので、そこに影響はありません。

        また、併せて コードの整形(インンデント および 演算子前後に空白)を行ないました。

  2018/6/24
        下記の部分で「閉じる括弧 } 」が抜けていました。 6/21のコード整形時に誤って消してしまったようです。
        #-- 4月 --
        } elsif ($mm==4) {
  ← この括弧が抜けていた
  ---------------------------------------------------------------------------------

    ----------- Perl における 曜日値について -----------
        曜日の値は [ 日(0), 月(1), 火(2), 水(3), 木(4), 金(5), 土(6) ] です。
        システム定数は用意されていません。


    UTF8 で作成してあるファイルを用意しました。    [ JpnHoliday.pl ]
    "use utf8;" を有効にし、TeraPad を使って UTF-8N(UTF-8 BOM無)指定で作成してあります。
    Perl5.8 以降ではこのファイルをダウンロードしてご利用ください。

----------------------------------------------------------------------------------------

#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/  --- Perl 移植版 ---
#_/
#_/  CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
#_/  ( AddinBox  http://addinbox.sakura.ne.jp/index.htm )
#_/  (  旧サイト  http://www.h3.dion.ne.jp/~sakatsu/index.htm )
#_/
#_/  この祝日マクロは『kt関数アドイン』で使用しているものです。
#_/  このロジックは、レスポンスを第一義として、可能な限り少ない
#_/  【条件判定の実行】で結果を出せるように設計してあります。
#_/
#_/  この関数では以下の祝日変更までサポートしています。
#_/  ・2019年施行の「天皇誕生日の変更」 12/23⇒2/23 (補:2019年には[天皇誕生日]はありません)
#_/  ・2020年施行の「体育の日の改名」⇒スポーツの日
#_/  ・五輪特措法による2020年の「祝日移動」
#_/      海の日:7/20(3rd Mon)⇒7/23, スポーツの日:10/12(2nd Mon)⇒7/24, 山の日:8/11⇒8/10
#_/
#_/  下記2つについては未だ法整備自体が行なわれていませんので未対応です。
#_/  ・2019年の退位日(4/30)/即位日(5/1)
#_/  ・2019年の「即位の礼 正殿の儀 (10/22) 」
#_/
#_/  (*1)このマクロを引用するに当たっては、必ずこのコメントも
#_/      一緒に引用する事とします。
#_/  (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
#_/      【 http://addinbox.sakura.ne.jp/holiday_logic.htm 】
#_/      へのリンクによる紹介で対応して下さい。
#_/  (*3)[ktHolidayName]という関数名そのものは、各自の環境に
#_/      おける命名規則に沿って変更しても構いません。
#_/ 
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#
# 2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正
#
# 2018/6/21 振替休日の判定処理に誤りがありましたので修正しました
#
# 2018/2/15 [天皇誕生日の変更]改正の修正
#
# 2014/5/29 [山の日]改正の修正
#
# 2011/5/12 機能追加(角田)
#  フラグ(平日=0、土曜=1、日曜=2、休日=3、振休=4、祝日=5)に加えて、
#  「祝日名」も取得できるように修正しました。
#  (a) Holiday    : フラグのみを返します(従来の機能)。
#  (b) HolidayName : [フラグ,祝日名]の配列を返します(フラグ=0〜2の場合、祝日名="")。
#  尚、Perl5.8以降では[ use utf8; ]を指定してください。
#
#
# 2011/3/15 追記
# 〜 Perl版「祝日判定スクリプト」を利用する際の注意事項 〜
#
# Perl版「祝日判定スクリプト」の引数に指定するエポック秒を計算する為に
# timegm/timelocalを使用する際には、必ず『4桁西暦年』を使うようにして
# ください(尚、現在の祝日計算で1899年以前は対象外ですから、解説にある
# 「マイナス オフセット年($year-1900)」の処理は必要ありません)。
#
# timegm/timelocal について、多くの解説書・解説HPが紹介している「1900
# を引く($year-1900)」という使い方(70 イコール 1970年, 100 イコール
# 2000年 等という風に固定されているといった認識)は、timegm/timelocal
# 本来の仕様からすれば誤解に基づく使い方です。Perl が世に出て以降、現在
# まで「偶々、その方法でも上手くいっていた」というだけです。
#
#この事に関する詳細な解説は下記を参照してください。
#  〜 timegm/timelocal で、「年」引数の指定方法に関する誤解について 〜
#  http://addinbox.sakura.ne.jp/Perl/Notes_Perl_timegm_timelocal.htm
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#
#【 Perl 用祝日判定コード 】  2003/6/9 追記 INABA Hitoshi
#    [C ]用のロジックを、そのまま[Perl ]用に書き直したものです。
#
#【 C 用祝日判定コード 】  2003/3/2 追記
#      VBAコードのロジックを、そのまま[C ]用に書き直したものです。
#    「こほろぎ AsaPi!」さんによる編集です(祝日名ではなくフラグを返す仕様です)。
#    土日なども一緒に判定するなど条件を付加する場合は、こちらの解説を参考にして下さい。
# 土日祝日かどうかを返す関数 
#        返り値:平日=0、土曜=1、日曜=2、休日=3、振休=4、祝日=5
#  この関数(含むsub Syunbun、sub Syubun)は、
#    http://addinbox.sakura.ne.jp/
#  の祝日判定ロジック(VBA版)を利用して作ったものです。
#

#----- JpnHoliday.pl -----#


# use utf8;    # Perl5.8以降では utf8 ファイルとする。
use strict;

sub Syunbun($); # 春分の日を返す関数
sub Syubun($); # 秋分の日を返す関数

sub Holiday($) {
    return (&HolidayName(@_))[0];  # フラグのみ
}

sub HolidayName($) {
    my($t) = @_;
    my @r;

    sub SYUKUJITSU { -676976400 }; # 祝日法 施行 1948年7月20日
    sub FURIKAE { 103388400 }; # 振替休日 施行 1973年04月12日

    my($yy,$mm,$dd,$ww) = (localtime($t))[5,4,3,6];
    $yy += 1900;    # $yy : 4桁 西暦年
    $mm += 1;       # $mm : 月(1〜12)
                    # $ww : 日(0),月(1) ... 土(6)

    @r = (0, "");
    if ($ww == 6) {
        @r = (1, "");    # 土曜
    } elsif ($ww == 0) {
        @r = (2, "");    # 日曜
    }

    if ($t < SYUKUJITSU) {
        return @r;    # 祝日法 施行以前
    }

    #-- 1月 --
    if ($mm == 1) {
        if ($dd == 1) {
            @r = (5, "元日");
        } else {
            if ($yy >= 2000) {
                if ((int(($dd - 1) / 7) == 1) && ($ww == 1)) {    # 2nd Monday
                    @r = (5, "成人の日");
                }
            } else {
                if ($dd == 15) {
                    @r = (5, "成人の日");
                }
            }
        }

    #-- 2月 --
    } elsif ($mm == 2) {
        if ($dd == 11) {
            if ($yy >= 1967) {
                @r = (5, "建国記念の日");
            }
        } elsif ($dd == 23) {
            if ($yy >= 2020) {
                @r = (5, "天皇誕生日");
            }
        } elsif (($yy == 1989) && ($dd == 24)) {
            @r = (5, "昭和天皇の大喪の礼");
        }

    #-- 3月 --
    } elsif ($mm == 3) {
        if ($dd == &Syunbun($yy)) {
            @r = (5, "春分の日");
        }

    #-- 4月 --
    } elsif ($mm==4) {
        if ($dd == 29) {
            if ($yy >= 2007) {
                @r = (5, "昭和の日");
            } elsif ($yy >= 1989) {
                @r = (5, "みどりの日");
            } else {
                @r = (5, "天皇誕生日");  # 昭和天皇
            }
        } elsif (($yy == 1959) && ($dd == 10)) {
            @r = (5, "皇太子明仁親王の結婚の儀");
        }

    #-- 5月 --
    } elsif ($mm==5) {
        if ($dd == 3) {
            @r = (5, "憲法記念日");
        } elsif ($dd == 4) {
            if ($yy >= 2007) {
                @r = (5, "みどりの日");
            } elsif ($yy >= 1986) {
                # 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年)
                if ($ww > 1) {   # 火曜日 以降(火〜土)
                    @r = (3, "国民の休日");
                }
            }
        } elsif ($dd == 5) {
            @r = (5, "こどもの日");
        } elsif ($dd == 6) {
            # [5/3,5/4が日曜]ケースのみ、ここで判定
            if (($yy >= 2007) && (($ww == 2) || ($ww == 3))) {
                @r = (4, "振替休日");
            }
        }

    #-- 6月 --
    } elsif ($mm == 6) {
        if (($yy == 1993) && ($dd == 9)) {
            @r = (5, "皇太子徳仁親王の結婚の儀");
        }

    #-- 7月 --
    } elsif ($mm == 7) {
        if ($yy >= 2021) {
            if ((int(($dd - 1) / 7) == 2) && ($ww == 1)) {   # 3rd Monday
                @r = (5, "海の日");
            }
        } elsif ($yy == 2020) {
            # 2020年はオリンピック特措法により
            #「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
            if ($dd == 23) {
                @r = (5, "海の日");
            } elsif ($dd == 24) {
                @r = (5, "スポーツの日");
            }
        } elsif ($yy >= 2003) {
            if ((int(($dd - 1) / 7) == 2) && ($ww == 1)) {   # 3rd Monday
                @r = (5, "海の日");
            }
        } elsif ($yy >= 1996) {
            if ($dd == 20) {
                @r = (5, "海の日");
            }
        }

    #-- 8月 --
    } elsif ($mm == 8) {
        if ($yy >= 2021) {
            if ($dd == 11) {
                @r = (5, "山の日");
            }
        } elsif ($yy == 2020) {
            # 2020年はオリンピック特措法により「山の日」が 8/10 に移動
            if ($dd == 10) {
                @r = (5, "山の日");
            }
        } elsif ($yy >= 2016) {
            if ($dd == 11) {
                @r = (5, "山の日");
            }
        }

    #-- 9月 --
    } elsif ($mm == 9) {
        if ($dd == &Syubun($yy)) {
            @r = (5, "秋分の日");
        } else {
            if ($yy >= 2003) {
                if ((int(($dd - 1) / 7) == 2) && ($ww == 1)) {    # 3rd Monday
                    @r = (5, "敬老の日");
                } elsif ($ww == 2) {
                    if ($dd == (&Syubun($yy) - 1)) {
                        @r = (3, "国民の休日");    # 火曜日&[秋分日の前日]
                    }
                }
            } elsif ($yy >= 1966) {
                if ($dd == 15) {
                    @r = (5, "敬老の日");
                }
            }
        }

    #-- 10月 --
    } elsif ($mm == 10) {
        if ($yy >= 2021) {
            if ((int(($dd - 1) / 7) == 1) && ($ww == 1)) {    # 2nd Monday
                @r = (5, "スポーツの日");       # 2020年より改名
            }
        } elsif ($yy == 2020) {
            # 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
        } elsif ($yy >= 2000) {
            if ((int(($dd - 1) / 7) == 1) && ($ww == 1)) {    # 2nd Monday
                @r = (5, "体育の日");
            }
        } elsif ($yy >= 1966) {
            if ($dd == 10) {
                @r = (5, "体育の日");
            }
        }

    #-- 11月 --
    } elsif ($mm == 11) {
        if ($dd == 3) {
            @r = (5, "文化の日");
        } elsif ($dd == 23) {
            @r = (5, "勤労感謝の日");
        } elsif (($yy == 1990) && ($dd == 12)) {
            @r = (5, "即位礼正殿の儀");  # 平成天皇
        }

    #-- 12月 --
    } elsif ($mm == 12) {
        if ($dd == 23) {
            if (($yy >= 1989) && ($yy <= 2018)) {
                @r = (5, "天皇誕生日");  # 平成天皇
            }
        }
    }

    # ----- 振替休日の判定 (振替休日施行日:1973/4/12) -----
    # [ 対象日≠祝日/休日 & 対象日=月曜日 ]のみ、前日(=日曜日)を祝日判定する。
    # 前日(=日曜日)が祝日の場合は”振替休日”となる。
    # 尚、5月6日の扱いを
    #     「火曜 or 水曜(みどりの日(5/4) or 憲法記念日(5/3)の振替休日)」⇒5月ブロック内で判定済
    #     「月曜(こどもの日(5/5)の振替休日」⇒ここの判定処理で判定
    # とする事により、ここでの判定対象は『対象日が月曜日』のみ となります。

    if (($r[0] <= 2) && ($ww == 1)) {  # [平日=0, 土曜=1, 日曜=2, 休日=3, 振休=4、, 祝日=5]
        if ($t >= FURIKAE) {
            if ((&HolidayName($t - 86400))[0] == 5) {  # 再帰呼出
                @r = (4, "振替休日");
            }
        }
    }

    return @r;
}

#  春分/秋分日の略算式は
#    『海上保安庁水路部 暦計算研究会編 新こよみ便利帳』
#  で紹介されている式です。

# 春分の日を返す関数

sub Syunbun($) {
    my($yy) = @_;
    my $dd;
    if ($yy <= 1947) {
        $dd = 99;  # 祝日法施行前
    } elsif ($yy <= 1979) {
        $dd = int(20.8357 + (0.242194 * ($yy - 1980)) - int(($yy - 1983) / 4));
    } elsif ($yy <= 2099) {
        $dd = int(20.8431 + (0.242194 * ($yy - 1980)) - int(($yy - 1980) / 4));
    } elsif ($yy <= 2150) {
        $dd = int(21.851 + (0.242194 * ($yy - 1980)) - int(($yy - 1980) / 4));
    } else {
        $dd = 99;  # 2151年以降は略算式が無いので不明
    }
    return $dd;
}

# 秋分の日を返す関数
sub Syubun($) {
    my($yy) = @_;
    my $dd;
    if ($yy <= 1947) {
        $dd = 99;  # 祝日法施行前
    } elsif ($yy <= 1979) {
        $dd = int(23.2588 + (0.242194 * ($yy - 1980)) - int(($yy - 1983) / 4));
    } elsif ($yy <= 2099) {
        $dd = int(23.2488 + (0.242194 * ($yy - 1980)) - int(($yy - 1980) / 4));
    } elsif ($yy <= 2150) {
        $dd = int(24.2488 + (0.242194 * ($yy - 1980)) - int(($yy - 1980) / 4));
    } else {
        $dd = 99;  # 2151年以降は略算式が無いので不明
    }
    return $dd;
}

1;

# #### Test Script for JpnHoliday.pl(Holiday , HolidayName) ###
#
# #!/usr/local/bin/perl
#
# use Time::Local;
# # use utf8;        # Perl5.8以降では utf8 ファイルとする。
#
# require 'JpnHoliday.pl';  #祝日判定スクリプト
#
# print "Content-type: text/html\n\n";
# print "<HTML><BODY>\n";
#
# my @wdays = ("日","月","火","水","木","金","土");
#
# my $SetYear = 2011;  #テストする年(西暦4桁)
#
# # 祝日の定義および検証データは下記サイトを参照
# # http://addinbox.sakura.ne.jp/holiday_topic.htm
#
# my $DateWK = timelocal(0,0,0,1,0,$SetYear);
# my $DateEnd = timelocal(0,0,0,1,0,$SetYear+1);
# my @HName;
# my $HFlg;
#
# while($DateWK < $DateEnd) {
#  $HFlg = Holiday($DateWK);
#  @HName = HolidayName($DateWK);
#  if ($HName[0] >= 3) {
#    my ($year,$month,$day,$wday) = (localtime($DateWK))[5,4,3,6];
#    $year += 1900;
#    $month += 1;
#    print "$year/$month/$day" . "(" . $wdays[$wday] . ") --> " . $HName[0] . ":" . $HName[1] . "  , " . $HFlg . "<BR>\n";
#  }
#  $DateWK += 86400;
# }
# print "</BODY></HTML>\n";
# exit;





[ この場所へのリンク ]


AWK 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]
  2003/6/11 追記
  2005/5/20 [昭和の日]改正の修正
  2014/5/29 [山の日]改正の修正
  2018/2/15 [天皇誕生日の変更]改正の修正
  2018/6/21 一部修正(下記参照)
  2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正


    VBAコードのロジックから移植した [ C 版 / Perl 版 ] を [AWK ]用に書き直したものです。
    富士ソフトサービスビューロ(株) BS部「稲葉」さんによる編集です。

    土日なども一緒に判定するなど条件を付加する場合は、こちらの解説を参考にして下さい。

    『祝日について

    「昭和の日」に伴う「振替休日(5月6日)」改正への修正方針もお読みください。

    --- AWK について補足 ---
      AWK とは、Perl と同様のパターン処理記述用の言語ですが、Perl に比べて非常にコンパクトに
      出来ており、UNIX や MS-DOS などで普及していたそうです。詳しくは下記のHPをご覧下さい。
          [ Daichi Mochihashi's Web Page ]内の[ Awkward Programming in awk ]

  --- 修正内容の説明 --------------------------------------
  2018/6/21    : 修正前ソースコード ( Internet Archive )
        振替休日の判定処理に誤りがありました。
            if ((r <= 3) && (ww == 1)){
              [ r : 平日=0, 土曜=1, 日曜=2, 休日=3, 振休=4、, 祝日=5 ]
        [ 休日=3 ] を含まず [ if ((r <= 2) && (ww == 1)){ ] が正しい条件です。

        対象に 3:国民の休日(5月4日:1986〜2006年 , 9月21日(火) or 22日(火):2009年〜 時々)を
        含めた結果、「1987/5/4 (月), 1992/5/4 (月), 1998/5/4 (月)」を「憲法記念日(5/3)の振替休日」と
        誤判定していました(正解は「国民の休日」です)。
        尚、「9月の国民の休日」は常に火曜日となりますので、そこに影響はありません。

        また、併せて コードの整形(インンデント および 演算子前後に空白)を行ないました。

  -----------------------------------------------------------

    ----------- AWK における 曜日値について -----------
        曜日の値は [ 日(0), 月(1), 火(2), 水(3), 木(4), 金(5), 土(6) ] です。
        システム定数は用意されていません。


----------------------------------------------------------------------------------------

#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/  --- AWK 移植版 ---
#_/
#_/  CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
#_/  ( AddinBox  http://addinbox.sakura.ne.jp/index.htm )
#_/  (  旧サイト  http://www.h3.dion.ne.jp/~sakatsu/index.htm )
#_/
#_/  この祝日マクロは『kt関数アドイン』で使用しているものです。
#_/  このロジックは、レスポンスを第一義として、可能な限り少ない
#_/  【条件判定の実行】で結果を出せるように設計してあります。
#_/
#_/  この関数では以下の祝日変更までサポートしています。
#_/  ・2019年施行の「天皇誕生日の変更」 12/23⇒2/23 (補:2019年には[天皇誕生日]はありません)
#_/  ・2020年施行の「体育の日の改名」⇒スポーツの日
#_/  ・五輪特措法による2020年の「祝日移動」
#_/      海の日:7/20(3rd Mon)⇒7/23, スポーツの日:10/12(2nd Mon)⇒7/24, 山の日:8/11⇒8/10
#_/
#_/  下記2つについては未だ法整備自体が行なわれていませんので未対応です。
#_/  ・2019年の退位日(4/30)/即位日(5/1)
#_/  ・2019年の「即位の礼 正殿の儀 (10/22) 」
#_/
#_/  (*1)このマクロを引用するに当たっては、必ずこのコメントも
#_/      一緒に引用する事とします。
#_/  (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
#_/      【 http://addinbox.sakura.ne.jp/holiday_logic.htm 】
#_/      へのリンクによる紹介で対応して下さい。
#_/  (*3)[ktHolidayName]という関数名そのものは、各自の環境に
#_/      おける命名規則に沿って変更しても構いません。
#_/ 
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#
# 2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正
#
# 2018/6/21 振替休日の判定処理に誤りがありましたので修正しました
#
# 2018/2/15 [天皇誕生日の変更]改正の修正
#
# 2014/5/29 [山の日]改正の修正
#
#【 awk 用祝日判定コード 】  2003/6/10 追記 INABA Hitoshi
#    [Perl ]用のロジックを、そのまま[awk ]用に書き直したものです。
#    関数 strftime を使っているので gawk 2.13 以上が必要です。

#【 Perl 用祝日判定コード 】  2003/6/9 追記 INABA Hitoshi
#    [C ]用のロジックを、そのまま[Perl ]用に書き直したものです。

#【 C 用祝日判定コード 】  2003/3/2 追記
#      VBAコードのロジックを、そのまま[C ]用に書き直したものです。
#    「こほろぎ AsaPi!」さんによる編集です(祝日名ではなくフラグを返す仕様です)。
#    土日なども一緒に判定するなど条件を付加する場合は、こちらの解説を参考にして下さい。

# 土日祝日かどうかを返す関数 
#        返り値:平日=0、土曜=1、日曜=2、休日=3、振休=4、祝日=5
#  この関数(含むfunction Syunbun、function Syubun)は、
#    http://addinbox.sakura.ne.jp/
#  の祝日判定ロジック(VBA版)を利用して作ったものです。
#


function SYUKUJITSU(){ return -676976400 }; # 祝日法 施行 1948年7月20日
function FURIKAE(){ return 103388400 }; # 振替休日 施行 1973年04月12日

function Holiday(t, yy,mm,dd,ww,r) {

    yy = strftime("%Y",t) + 0;     # 4桁 西暦年
    mm = strftime("%m",t) + 0;     # 月(1〜12)
    dd = strftime("%d",t) + 0;
    ww = strftime("%w",t) + 0;     # 日(0),月(1) ... 土(6)

    r = 0;
    if (ww == 6) {
        r = 1;     # 土曜
    } else if (ww == 0) {
        r = 2;     # 日曜
    }

    if (t < SYUKUJITSU()) {
      return r;     # 祝日法 施行以前
    }

    #-- 1月 --
    if (mm == 1) {
        if (dd == 1) {
            r = 5; # 元日
        } else {
            if (yy >= 2000) {
                if ((int((dd - 1) / 7) == 1) && (ww == 1)) {   # 2nd Monday
                    r = 5;   # 成人の日
                }
            } else {
                if (dd == 15) {
                    r = 5;   # 成人の日
                }
            }
        }

    #-- 2月 --
    } else if (mm == 2) {
        if (dd == 11) {
            if (yy >= 1967) {
                r = 5;   # 建国記念の日
            }
        } else if (dd == 23) {
            if (yy >= 2020) {
                r = 5;   # 天皇誕生日
            }
        } else if ((yy == 1989) && (dd == 24)) {
            r = 5;   # 昭和天皇の大喪の礼
        }

    #-- 3月 --
    } else if (mm == 3) {
        if (dd == Syunbun(yy)) {
            r = 5;   # 春分の日
        }

    #-- 4月 --
    } else if (mm == 4) {
        if (dd == 29) {
            if (yy >= 2007) {
                r = 5;   # 昭和の日
            } else if (yy >= 1989) {
                r = 5;   # みどりの日
            } else {
                r = 5;   # 天皇誕生日(昭和天皇)
            }
        } else if ((yy == 1959) && (dd == 10)) {
            r = 5;   # 皇太子明仁親王の結婚の儀
        }

    #-- 5月 --
    } else if (mm == 5) {
        if (dd == 3) {
            r = 5;   # 憲法記念日
        } else if (dd == 4) {
            if (yy >= 2007) {
                r = 5;   # みどりの日
            } else if (yy >= 1986) {
                # 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年)
                if (ww > 1) {   # 火曜日 以降(火〜土)
                    r = 3;   # 国民の休日
                }
            }
        } else if (dd == 5) {
            r = 5;   # こどもの日
        } else if (dd == 6) {
            # [5/3,5/4が日曜]ケースのみ、ここで判定
            if ((yy >= 2007) && ((ww == 2) || (ww == 3))) {
                r = 4;   # 振替休日
            }
        }

    #-- 6月 --
    } else if (mm == 6) {
        if ((yy == 1993) && (dd == 9)) {
            r = 5;   # 皇太子徳仁親王の結婚の儀
        }

    #-- 7月 --
    } else if (mm == 7) {
        if (yy >= 2021) {
            if ((int((dd - 1) / 7) == 2) && (ww == 1)) {    # 3rd Monday
                r = 5;   # 海の日
            }
        } else if (yy == 2020) {
            # 2020年はオリンピック特措法により
            #「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
            if (dd == 23) {
                r = 5;   # 海の日
            } else if (dd == 24) {
                r = 5;   # スポーツの日
            }
        } else if (yy >= 2003) {
            if ((int((dd - 1) / 7) == 2) && (ww == 1)) {    # 3rd Monday
                r = 5;   # 海の日
            }
        } else if (yy >= 1996) {
            if (dd == 20) {
                r = 5;   # 海の日
            }
        }

    #-- 8月 --
    } else if (mm == 8) {
        if (yy >= 2021) {
            if (dd == 11) {
                r = 5;   # 山の日
            }
        } else if (yy == 2020) {
            # 2020年はオリンピック特措法により「山の日」が 8/10 に移動
            if (dd == 10) {
                r = 5;   # 山の日
            }
        } else if (yy >= 2016) {
            if (dd == 11) {
                r = 5;   # 山の日
            }
        }

    #-- 9月 --
    } else if (mm == 9) {
        if (dd == Syubun(yy)) {
            r = 5;   # 秋分の日
        } else {
            if (yy >= 2003) {
                if ((int((dd - 1) / 7) == 2) && (ww == 1)) {   # 3rd Monday
                    r = 5;   # 敬老の日
                } else if (ww == 2) {
                    if (dd == (Syubun(yy) - 1)) {
                        r = 3;   # 国民の休日 , 火曜日&[秋分日の前日]
                    }
                }
            } else if (yy >= 1966) {
                if (dd == 15) {
                    r = 5;   # 敬老の日
                }
            }
        }

    #-- 10月 --
    } else if (mm == 10) {
        if (yy >= 2021) {
            if ((int((dd - 1) / 7) == 1) && (ww == 1)) {    # 2nd Monday
                r = 5;   # スポーツの日 , 2020年より改名
            }
        } else if (yy == 2020) {
            # 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
        } else if (yy >= 2000) {
            if ((int((dd - 1) / 7) == 1) && (ww == 1)) {    # 2nd Monday
                r = 5;   # 体育の日
            }
        } else if (yy >= 1966) {
            if (dd == 10) {
                r = 5;   # 体育の日
            }
        }

    #-- 11月 --
    } else if (mm == 11) {
        if (dd == 3) {
            r = 5;   # 文化の日
        } else if (dd == 23) {
            r = 5;   # 勤労感謝の日
        } else if ((yy == 1990) && (dd == 12)) {
            r = 5;   # 即位礼正殿の儀(平成天皇)
        }

    #-- 12月 --
    } else if (mm == 12) {
        if (dd == 23) {
            if ((yy >= 1989) && (yy <= 2018)) {
                r = 5;   # 天皇誕生日(平成天皇)
            }
        }
    }

    # ----- 振替休日の判定 (振替休日施行日:1973/4/12) -----
    # [ 対象日≠祝日/休日 & 対象日=月曜日 ]のみ、前日(=日曜日)を祝日判定する。
    # 前日(=日曜日)が祝日の場合は”振替休日”となる。
    # 尚、5月6日の扱いを
    #     「火曜 or 水曜(みどりの日(5/4) or 憲法記念日(5/3)の振替休日)」⇒5月ブロック内で判定済
    #     「月曜(こどもの日(5/5)の振替休日」⇒ここの判定処理で判定
    # とする事により、ここでの判定対象は『対象日が月曜日』のみ となります。

    if ((r <= 2) && (ww == 1)) {  # [平日=0, 土曜=1, 日曜=2, 休日=3, 振休=4、, 祝日=5]
        if (t >= FURIKAE()) {
            if (Holiday(t - 86400) == 5) {  # 再帰呼出
                r=4;  # 振替休日
            }
        }
    }

    return r;
}

#  春分/秋分日の略算式は
#    『海上保安庁水路部 暦計算研究会編 新こよみ便利帳』
#  で紹介されている式です。

# 春分の日を返す関数

function Syunbun(yy, dd) {
    if (yy <= 1947) {
        dd = 99;  # 祝日法施行前
    } else if (yy <= 1979) {
        dd = int(20.8357 + (0.242194 * (yy - 1980)) - int((yy - 1983) / 4));
    } else if (yy <= 2099) {
        dd = int(20.8431 + (0.242194 * (yy - 1980)) - int((yy - 1980) / 4));
    } else if (yy <= 2150) {
        dd = int(21.851 + (0.242194 * (yy - 1980)) - int((yy - 1980) / 4));
    } else {
        dd = 99;  # 2151年以降は略算式が無いので不明
    }
    return dd;
}

# 秋分の日を返す関数
function Syubun(yy, dd) {
    if (yy <= 1947) {
        dd = 99;  # 祝日法施行前
    } else if (yy <= 1979) {
        dd = int(23.2588 + (0.242194 * (yy - 1980)) - int((yy - 1983) / 4));
    } else if (yy <= 2099) {
        dd = int(23.2488 + (0.242194 * (yy - 1980)) - int((yy - 1980) / 4));
    } else if (yy <= 2150) {
        dd = int(24.2488 + (0.242194 * (yy - 1980)) - int((yy - 1980) / 4));
    } else {
        dd = 99;  # 2151年以降は略算式が無いので不明
    }
    return dd;
}





角田  桂一 Mail:addinbox@h4.dion.ne.jp CopyRight(C) 2001 Allrights Reserved.