AddinBox(Title_Logo)

  -- Page 5 --

      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 5 ) ]
--言語-- -- 移  植 -- -公開日- -頁-
  ・ 祝日判定マクロ の 設計方針について
  ・ 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祝日には手を加えずに、その外側にプロシ
ジャーを用意して、そこで機能追加を施すようにして下さい。




[ この場所へのリンク ]


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


    VBAコードのロジックを、そのまま[Transact-SQL ]用に書き直したものです。
    シリコンブレス「有方 公一」さんによる編集です。この祝日機能を搭載したHP向け
    カレンダーツール の提供もされてます。

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

    『祝日について

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

  --- 修正内容の説明 --------------------------------------
  2018/6/21    : 修正前ソースコード ( Internet Archive )
        5月6日が [水曜, 憲法記念日(5/3) の振替休日] の判定が抜けていました。
        [2009/5/6(水), 2015/5/6(水), 2020/5/6(水), … ] が「平日」と判定されていました。
    if(@intDay = 6)
        begin
        if(@intYear >= 2007)
            begin
            if(DATEPART(weekday,@prmTargetDate) = 2 or DATEPART(weekday,@prmTargetDate) = 3)
                begin
                --火曜日または水曜日[5/3,5/4が日曜]ケースのみ
                set @HolidayString = '振替休日'
                end
            end
        火曜(3) / 水曜(4) ですので以下のように修正します。
            if(DATEPART(weekday,@prmTargetDate) = 3 or DATEPART(weekday,@prmTargetDate) = 4)  -- Tuesday(3), Wednesday(4)

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

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

        (補) Transact-SQL では、環境設定によって、曜日値の並びが変わります ( [ 月(1), 火(2), … 日(7) ] 等 )。
              このプログラムは曜日値 ( DATEPART(weekday, 日付) ) が [ 日(1), 月(2) ... 土(7) ] である前提で作成しています
              したがって、SET DATEFIRST は省略 (or 7(標準/USA) を指定) してください




  usp_GetHolidayStringは、他のストアドから使用できるように、返値用変数を引数にとります。
  このため、単独では使用できません。
----------------------------------------------------------------------------------------

CREATE Procedure usp_GetHolidayName
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
--_/
--_/  --- Transact-SQL 移植版 ---
--_/
--_/  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関数アドイン』で使用しているVBAマクロ
--_/  を[Transact-SQL]に移植したものです。
--_/  このロジックは、レスポンスを第一義として、可能な限り少ない
--_/  【条件判定の実行】で結果を出せるように設計してあります。
--_/
--_/  この関数では以下の祝日変更までサポートしています。
--_/  ・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]という関数名そのものは、各自の環境に
--_/      おける命名規則に沿って変更しても構いません。
--_/
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
--
-- 2014/5/29 [山の日]改正の修正
-- 2018/2/15 [天皇誕生日の変更]改正の修正
-- 2018/6/21 5月6日(水曜, 憲法記念日(5/3)の振替休日)の判定が抜けていたのを修正
-- 2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正
--
--
--【機能】休日名を取得する
--【引数】@prmTargetDate  対象日付
--【戻値】休日名
--【備考】usp_GetHolidayStringで祝日を取得し、
--        このストアドで振替休日判定をおこなう
--
-- ※ 注意事項 ※
-- このプログラムは曜日値( DATEPART(weekday,日付) )が「日(1), 月(2) ... 土(7)」である前提で作成しています
-- したがって、SET DATEFIRST は省略 (or 7(標準/USA) を指定) してください
-- それ以外の設定では正しく動作しません(プログラムの修正が必要になります)


        @prmTargetDate  datetime
  ,@HolidayName        varchar(20)    OUTPUT
       
As
       
        set  nocount on
       
        declare @FrSiko datetime    --振替休日施行日
        set @FrSiko = CONVERT(datetime,'1973/04/12')
       
        set @HolidayName  = ''
       
        ----- 祝日名を取得 -----
        exec usp_GetHolidayString @prmTargetDate,@HolidayName OUTPUT
       
        -- ----- 振替休日の判定 (振替休日施行日:1973/4/12) -----
        -- [ 対象日≠祝日/休日 & 対象日=月曜日 ]のみ、前日(=日曜日)を祝日判定する。
        -- 前日(=日曜日)が祝日の場合は”振替休日”となる。
        -- 尚、5月6日の扱いを
        --     「火曜 or 水曜(みどりの日(5/4) or 憲法記念日(5/3)の振替休日)」⇒5月ブロック内で判定済
        --     「月曜(こどもの日(5/5)の振替休日」⇒ここの判定処理で判定
        -- とする事により、ここでの判定対象は『対象日が月曜日』のみ となります。

        if(@HolidayName = '')
            begin
            if(DATEPART(weekday,@prmTargetDate) = 2)    -- Monday(2)
                begin
                if(@prmTargetDate >= @FrSiko)    -- (1973/04/12)
                    begin
                    --前日の祝日名を取得
                    set @prmTargetDate=DATEADD(day,-1,@prmTargetDate)
                    exec usp_GetHolidayString @prmTargetDate,@HolidayName OUTPUT
                    if(@HolidayName <> '')
                        set @HolidayName = '振替休日'
                    end
                end
            end


CREATE Procedure usp_GetHolidayString

--【機能】祝日名の取得
--【引数】@prmTargetDate  対象日付
--【戻値】祝日名
--【備考】usp_GetHolidayNameから使用する


        @prmTargetDate    datetime
  ,@HolidayString        varchar(20) OUTPUT
       
As
       
        set    nocount on

        declare @HoSiko         datetime        --祝日法施行
        declare @Taiso          datetime        --昭和天皇大喪の礼
        declare @Akihito        datetime        --明仁親王の結婚の儀
        declare @Norihito       datetime        --徳仁親王の結婚の儀
        declare @Sokui          datetime        --即位礼正殿の儀(平成天皇)
       
        declare @Syunbun        int             --春分の日
        declare @Syuubun        int             --秋分の日
        declare @intYear        int
        declare @intMonth       int
        declare @intDay         int
       
        declare @Youbi          varchar(10)
       
        --時刻データ(小数部)は取り除いてあるので、下記の@prmTargetDateとの比較はOK
        set @HoSiko    = CONVERT(datetime,'1948/07/20')        --祝日法施行
        set @Taiso     = CONVERT(datetime,'1989/02/24')        --昭和天皇の大喪の礼
        set @Akihito   = CONVERT(datetime,'1959/04/10')        --明仁親王の結婚の儀
        set @Norihito  = CONVERT(datetime,'1993/06/09')        --徳仁親王の結婚の儀
        set @Sokui     = CONVERT(datetime,'1990/11/12')        --即位礼正殿の儀(平成天皇)
       

        set @intYear    = Year(@prmTargetDate)
        set @intMonth   = Month(@prmTargetDate)    -- 月(1〜12)
        set @intDay     = Day(@prmTargetDate)

        set @HolidayString = ''
       
        -- 祝日法施行以前 --
        if(@prmTargetDate < @HoSiko)
            return
        else

        ---- 祝日の判定 ----
        -- 1月 --
        if(@intMonth = 1)
            begin
            if(@intDay = 1)
                set @HolidayString = '元日'
            else
                begin
                if(@intYear >= 2000)
                    begin
                    set @Youbi = CONVERT(varchar,((@intDay - 1) / 7) + 1) 
                                  + CONVERT(varchar,DATEPART(weekday,@prmTargetDate))
                    if(@Youbi = '22')    -- 2nd Monday(2)
                        set @HolidayString = '成人の日'
                    end
                else
                    begin
                    if(@intDay = 15)
                        set @HolidayString = '成人の日'
                    end
                end
            end
        else

        -- 2月 --
        if(@intMonth = 2)
            begin
            if(@intDay = 11)
                begin
                if(@intYear >= 1967)
                    set @HolidayString = '建国記念の日'
                end
            else
                begin
                if(@intDay = 23)
                    begin
                    if(@intYear >= 2020)
                        set @HolidayString = '天皇誕生日'
                    end
                else
                    begin
                    if(@prmTargetDate = @Taiso)    -- (1989/2/24)
                        set @HolidayString = '昭和天皇の大喪の礼'
                    end
                end
            end
        else

        -- 3月 --
        if(@intMonth = 3)
            begin
            --  春分/秋分日の略算式は
            --    『海上保安庁水路部 暦計算研究会編 新こよみ便利帳』
            --  で紹介されている式です。

            if(@intYear <= 1947)
                set @Syunbun = 99    --祝日法施行前
            else
                begin
                if(@intYear <= 1979)
                    set @Syunbun = CONVERT(int,20.8357 + (0.242194 * (@intYear - 1980)) - CONVERT(int,(@intYear - 1980) / 4))
                else
                    begin
                    if(@intYear <= 2099)
                        set @Syunbun = CONVERT(int,20.8431 + (0.242194 * (@intYear - 1980)) - CONVERT(int,(@intYear - 1980) / 4))
                    else
                        begin
                        if(@intYear <= 2150)
                            set @Syunbun = CONVERT(int,20.851 + (0.242194 * (@intYear - 1980)) - CONVERT(int,(@intYear - 1980) / 4))
                        else
                            set @Syunbun = 99    --2151年以降は略算式が無いので不明
                        end
                    end
                end
                   
            if(@intDay = @Syunbun)              -- 1948〜2150以外は[99]が返るので、必ず≠になる
                set @HolidayString = '春分の日'

            end
        else

        -- 4月 --
        if(@intMonth = 4)
            begin
            if(@intDay = 29)
                begin
                if(@intYear >= 2007)
                    set @HolidayString = '昭和の日'
                else
                    begin
                    if(@intYear >= 1989)
                        set @HolidayString = 'みどりの日'
                    else
                        set @HolidayString = '天皇誕生日--昭和天皇
                    end
                end
            else
                begin
                if(@prmTargetDate = @Akihito)    -- (1959/4/10)
                    set @HolidayString = '皇太子明仁親王の結婚の儀'
                end
            end
        else

        -- 5月 --
        if(@intMonth = 5)
            begin
            if(@intDay = 3)
                set @HolidayString = '憲法記念日'
            else
                begin
                if(@intDay = 4)
                    begin
                    if(@intYear >= 2007)
                        set @HolidayString = 'みどりの日'
                    else
                        begin
                        if(@intYear >= 1986)
                            begin
                            if(DATEPART(weekday,@prmTargetDate) > 2)    -- Monday(2) , 火曜 以降(火〜土)
                                --5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』
                                set @HolidayString = '国民の休日'
                            end
                        end
                    end
                else
                    begin
                    if(@intDay = 5)
                        set @HolidayString = 'こどもの日'
                    else
                        begin
                        if(@intDay = 6)
                            begin
                            if(@intYear >= 2007)
                                begin
                                if(DATEPART(weekday,@prmTargetDate) = 3 
                                        or DATEPART(weekday,@prmTargetDate) = 4) -- Tuesday(3), Wednesday(4)
                                    begin
                                    -- 火曜日または水曜日[5/3,5/4が日曜]ケースのみ
                                    set @HolidayString = '振替休日'
                                    end
                                end
                            end
                        end
                    end
                end
            end
        else

        -- 6月 --
        if(@intMonth = 6)
            begin
            if(@prmTargetDate = @Norihito)    -- (1993/6/9)
                set @HolidayString = '皇太子徳仁親王の結婚の儀'
            end
        else

        -- 7月 --
        if(@intMonth = 7)
            begin
            set @Youbi = CONVERT(varchar,((@intDay - 1) / 7) + 1) 
                          + CONVERT(varchar,DATEPART(weekday,@prmTargetDate))
            if(@intYear >= 2021)
                begin
                if(@Youbi = '32')  -- 3rd Monday(2)
                    set @HolidayString = '海の日'
                end
            else
                begin
                if(@intYear = 2020)
                    begin
                    -- 2020年はオリンピック特措法により
                    --「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
                    if(@intDay = 23)
                        set @HolidayString = '海の日'
                    else
                        begin
                        if(@intDay = 24)
                            set @HolidayString = 'スポーツの日'
                        end
                    end
                else
                    begin
                    if(@intYear >= 2003)
                        begin
                        if(@Youbi = '32')  -- 3rd Monday(2)
                            set @HolidayString = '海の日'
                        end
                    else
                        begin
                        if(@intYear >= 1996)
                            if(@intDay = 20)
                                set @HolidayString = '海の日'
                        end
                    end
                end
            end
        else

        -- 8月 --
        if(@intMonth = 8)
            begin
            if(@intYear >= 2021)
                begin
                if(@intDay = 11)
                    set @HolidayString = '山の日'
                end
            else
                begin
                if(@intYear = 2020)
                    begin
                    -- 2020年はオリンピック特措法により「山の日」が 8/10 に移動
                    if(@intDay = 10)
                        set @HolidayString = '山の日'
                    end
                else
                    begin
                    if(@intYear >= 2016)
                        begin
                        if(@intDay = 11)
                            set @HolidayString = '山の日'
                        end
                    end
                end
            end
        else

        -- 9月 --
        if(@intMonth = 9)
            begin
            --第3月曜日(15〜21)と秋分日(22〜24)が重なる事はない
            --  春分/秋分日の略算式は
            --    『海上保安庁水路部 暦計算研究会編 新こよみ便利帳』
            --  で紹介されている式です。

            if(@intYear <= 1947)
                set @Syuubun = 99    --祝日法施行前
            else
                begin
                if(@intYear <= 1979)
                    set @Syuubun = CONVERT(int,23.2588 + (0.242194 * (@intYear - 1980)) - CONVERT(int,(@intYear - 1980) / 4))
                else
                    begin
                    if(@intYear <= 2099)
                         set @Syuubun = CONVERT(int,23.2488 + (0.242194 * (@intYear - 1980)) - CONVERT(int,(@intYear - 1980) / 4))
                    else
                        begin
                        if(@intYear <= 2150)
                            set @Syuubun = CONVERT(int,24.2488 + (0.242194 * (@intYear - 1980)) - CONVERT(int,(@intYear - 1980) / 4))
                        else
                            set @Syuubun = 99    --2151年以降は略算式が無いので不明
                        end
                    end
                end

            if(@intDay = @Syuubun)      -- 1948〜2150以外は[99]が返るので、必ず≠になる
                set @HolidayString = '秋分の日'
            else
                begin
                if(@intYear >= 2003)
                    begin
                    set @Youbi = CONVERT(varchar,((@intDay - 1) / 7) + 1) 
                                  + CONVERT(varchar,DATEPART(weekday,@prmTargetDate))
                    if(@Youbi = '32')    -- 3rd Monday(2)
                        set @HolidayString = '敬老の日'
                    else
                        begin
                        if(DATEPART(weekday,@prmTargetDate) = 3) -- Tuesday(3)
                            begin
                            if(@intDay = (@Syuubun - 1))
                                set @HolidayString = '国民の休日-- 火曜日&[秋分日の前日]
                            end
                        end
                    end
                else
                    begin
                    if(@intYear >= 1966)
                        begin
                        if(@intDay = 15)
                            set @HolidayString = '敬老の日'
                        end
                    end
                end
            end
        else

        -- 10月 --
        if(@intMonth = 10)
            begin
            set @Youbi = CONVERT(varchar,((@intDay - 1) / 7) + 1) 
                          + CONVERT(varchar,DATEPART(weekday,@prmTargetDate))
            if(@intYear >= 2021)
                begin
                if(@Youbi = '22')  -- 2nd Monday(2)
                    set @HolidayString = 'スポーツの日'    -- 2020年より改名
                end
            else
                begin
                if(@intYear = 2020)
                    begin
                    -- 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
                    end
                else
                    begin
                    if(@intYear >= 2000)
                        begin
                        if(@Youbi = '22')  -- 2nd Monday(2)
                            set @HolidayString = '体育の日'
                        end
                    else
                        begin
                        if(@intYear >= 1966)
                            begin
                            if(@intDay = 10)
                                set @HolidayString = '体育の日'
                            end
                        end
                    end
                end
            end
        else

        -- 11月 --
        if(@intMonth = 11)
            begin
            if(@intDay = 3)
                set @HolidayString = '文化の日'
            else
                begin
                if(@intDay = 23)
                    set @HolidayString = '勤労感謝の日'
                else
                    begin
                    if(@prmTargetDate = @Sokui)    -- (1990/11/12)
                        set @HolidayString = '即位礼正殿の儀'    -- 平成天皇
                    end
                end
            end
        else

        -- 12月 --
        if(@intMonth = 12)
            begin
            if(@intDay = 23)
                begin
                if((@intYear >= 1989) AND (@intYear <= 2018))
                    set @HolidayString = '天皇誕生日--平成天皇
                end
            end
       
        return





[ この場所へのリンク ]


Oracle PL/SQL 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]
  2006/12/1 追記 ( [昭和の日]改正 対応済み )
  2014/5/29 [山の日]改正の修正
  2018/2/15 [天皇誕生日の変更]改正の修正
  2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正


    VBAコードのロジックを、そのまま[PL/SQL(Oracle9i) ]用に書き直したものです。
    「菅 康明」さんによる編集です。

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

    『祝日について

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


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

        (補) PL/SQL では、環境設定によって、曜日値の並びが変わります ( [ 月(1), 火(2), … 日(7) ] 等 )。
              このプログラムは曜日値 ( TO_CHAR(日付,'D') ) が [ 日(1), 月(2) ... 土(7) ] である前提で作成しています


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

CREATE OR REPLACE PACKAGE ktHolidayName IS
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
--_/
--_/  --- PL/SQL 移植版 ---
--_/
--_/  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]という関数名そのものは、各自の環境に
--_/      おける命名規則に沿って変更しても構いません。
--_/ 
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
--
-- 2014/5/29 [山の日]改正の修正
-- 2018/2/15 [天皇誕生日の変更]改正の修正
-- 2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正
--
-- =============================================================================
-- ==【PL/SQL用祝日判定コード 】  2006/11/29(Wed) 追記
-- ==VBAコードのロジックを、そのまま[PL/SQL]用に書き直したものです。
-- ==
-- ==■環境依存
-- ==・TO_CHAR(日時)関数の戻り値について
-- ==
-- ==曜日取得の際に使用している TO_CHAR(日時)の'D'の戻り値については [ 日(1),月(2) ... 土(7) ]
-- ==として扱っていますが、この値は環境に依存します。
-- ==もし、[ 月(1) ... 土(6),日(7)]となる場合は以下の修正が必要となります。
-- == (1) パッケージ定数 vbMonday 〜 vbWednesday の値変更
-- == (2) 成人の日/海の日/敬老の日/体育の日の判定における
-- ==      If (str第N曜日 = '22') Then  -- 2nd Monday(2)  および
-- ==      If (str第N曜日 = '32') Then  -- 3rd Monday(2)
-- ==    で各々[21][31]に修正する必要があります。
-- == (3) 5月4日の判定における
-- ==      If (TO_CHAR(日付,'D') > vbMonday) Then  -- 火曜 以降(火〜土)
-- ==    を修正する必要があります。
-- ==
-- ==※Oracle9i SQLリファレンス リリース2(9.2)2003 年2月  部品番号: J06261-02
-- ==  より抜粋
-- ==日時書式要素D は、曜日の数(1 〜 7)を戻します。この数が1 である曜日は、
-- ==初期化パラメータNLS_TERRITORY によって暗黙的に指定されます。
-- ==
-- ==・CASE文について
-- ==CASE文 Oracle9i にて採用された構文です。
-- ==Oracle9i 以前のDBMSを使用している場合は、IF-ELSIFに置き換えてください。
-- ==
-- ==・データ型
-- ==VBA版はIntegerを使っているが、PL/SQL版はNUMBERを使用。
-- ==
-- =============================================================================


    FUNCTION ktHolidayName( 日付 IN DATE ) RETURN VARCHAR2;

END ktHolidayName;
/
-- ****************************************************************************
-- ***  Package Body Start
-- ****************************************************************************

CREATE OR REPLACE PACKAGE BODY ktHolidayName IS

    --グローバル変数定義(vb定数が無いもの) [ 日(1),月(2) ... 土(7) ]
    vbMonday       CONSTANT NUMBER := 2;
    vbTuesday      CONSTANT NUMBER := 3;
    vbWednesday    CONSTANT NUMBER := 4;

    -- プログラム内部使用関数プロトタイプ宣言
    FUNCTION prv祝日    ( 日付  IN   DATE ) RETURN VARCHAR2;
    FUNCTION prv春分日  ( 年    IN   NUMBER ) RETURN NUMBER;
    FUNCTION prv秋分日  ( 年    IN   NUMBER ) RETURN NUMBER;

-- ****************************************************************************
-- ***  Main Function
-- ****************************************************************************

Function ktHolidayName( 日付 IN DATE )
RETURN VARCHAR2 IS

    --変数定義
    dtm日付 DATE;
    str祝日名 VARCHAR2(30);

    --定数定義
    cst振替休日施行日 Constant Date := TO_DATE('19730412','YYYYMMDD');

BEGIN
    --時刻/時刻誤差の削除(SYSDATE関数などへの対応)
    dtm日付 := TO_DATE( TO_CHAR(日付,'YYYY') || TO_CHAR(日付,'MM') || TO_CHAR(日付,'DD') , 'YYYYMMDD');

    str祝日名 := prv祝日(dtm日付);

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

    If (str祝日名 IS NULL) Then
        If (TO_CHAR(dtm日付,'D') = vbMonday) Then
            If (dtm日付 >= cst振替休日施行日) Then
                str祝日名 := prv祝日(dtm日付 - 1);
                If (str祝日名 IS NOT NULL) Then
                    RETURN '振替休日';
                Else
                    RETURN NULL;
                End If;
            Else
                RETURN NULL;
            End If;
        Else
            RETURN NULL;
        End If;
    Else
        RETURN str祝日名;
    End If;
End ktHolidayName;

-- ****************************************************************************
-- ***  Sub Function    prv祝日
-- ****************************************************************************

Function prv祝日(日付 IN Date)
RETURN VARCHAR2 IS

    --変数定義
    int年          NUMBER;
    int月          NUMBER;
    int日          NUMBER;
    int秋分日      NUMBER;
    str第N曜日     VARCHAR2(2);

    --定数定義
    -- 時刻データ(小数部)は取り除いてあるので、下記の日付との比較はOK
    cst祝日法施行          Constant    Date := TO_DATE('19480720','YYYYMMDD');
    cst昭和天皇の大喪の礼  Constant    Date := TO_DATE('19890224','YYYYMMDD');
    cst明仁親王の結婚の儀  Constant    Date := TO_DATE('19590410','YYYYMMDD');
    cst徳仁親王の結婚の儀  Constant    Date := TO_DATE('19930609','YYYYMMDD');
    cst即位礼正殿の儀      Constant    Date := TO_DATE('19901112','YYYYMMDD');    -- 平成天皇

BEGIN

    int年 := TO_NUMBER(TO_CHAR(日付,'YYYY'));
    int月 := TO_NUMBER(TO_CHAR(日付,'MM'));
    int日 := TO_NUMBER(TO_CHAR(日付,'DD'));

    If (日付 < cst祝日法施行) Then
        RETURN NULL;    -- 祝日法施行以前
    End If;

    Case int月
    -- 1月 --
    WHEN 1 THEN
        If (int日 = 1) Then
            RETURN '元日';
        Else
            If (int年 >= 2000) Then
                str第N曜日 := TO_CHAR(TRUNC((int日 - 1) / 7) + 1,'FM0') || TO_CHAR(日付,'D');
                If (str第N曜日 = '22') Then  -- 2nd Monday(2)
                    RETURN '成人の日';
                END IF;
            Else
                If (int日 = 15) Then
                    RETURN '成人の日';
                END IF;
            END IF;
        END IF;

    -- 2月 --
    WHEN 2 THEN
        If (int日 = 11) Then
            If (int年 >= 1967) Then
                RETURN '建国記念の日';
            END IF;
        ELSIf (int日 = 23) Then
            If (int年 >= 2020) Then
                RETURN '天皇誕生日';
            END IF;
        ELSIF (日付 = cst昭和天皇の大喪の礼) Then
            RETURN '昭和天皇の大喪の礼';
        END IF;

    -- 3月 --
    WHEN 3 THEN
        If (int日 = prv春分日(int年)) Then    -- 1948〜2150以外は[99]が返るので、必ず≠になる
            RETURN '春分の日';
        END IF;

    -- 4月 --
    WHEN 4 THEN
        If (int日 = 29) Then
            If (int年 >= 2007) Then
                RETURN '昭和の日';
            ELSIF  (int年 >= 1989) Then
                RETURN 'みどりの日';
            Else
                RETURN '天皇誕生日';  -- 昭和天皇
            END IF;
        ELSIF (日付 = cst明仁親王の結婚の儀) Then
            RETURN '皇太子明仁親王の結婚の儀';
        END IF;

    -- 5月 --
    WHEN 5 THEN
        If (int日 = 3) Then
            RETURN '憲法記念日';
        ELSIF (int日 = 4) Then
            If (int年 >= 2007) Then
                RETURN 'みどりの日';
            ELSIF (int年 >= 1986) Then
                -- 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年)
                If (TO_CHAR(日付,'D') > vbMonday) Then    -- 火曜 以降(火〜土)
                    RETURN '国民の休日';
                END IF;
            END IF;
        ELSIF (int日 = 5) Then
            RETURN 'こどもの日';
        ELSIF (int日 = 6) Then
            If (int年 >= 2007) Then
                IF ( TO_CHAR(日付,'D') in ( vbTuesday, vbWednesday )) THEN
                    RETURN '振替休日';    -- 火曜日または水曜日 [5/3,5/4が日曜]ケースのみ、ここで判定
                End IF;
            END IF;
        END IF;

    -- 6月 --
    WHEN 6 THEN
        If (日付 = cst徳仁親王の結婚の儀) Then
            RETURN '皇太子徳仁親王の結婚の儀';
        END IF;

    -- 7月 --
    WHEN 7 THEN
        str第N曜日 := TO_CHAR(TRUNC((int日 - 1) / 7) + 1,'FM0') || TO_CHAR(日付,'D');
        If (int年 >= 2021) Then
            If (str第N曜日 = '32') Then  -- 3rd Monday(2)
                RETURN '海の日';
            END IF;
        ELSIF (int年 = 2020) Then
            -- 2020年はオリンピック特措法により
            --「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
            If (int日 = 23) Then
                RETURN '海の日';
            ELSIF (int日 = 24) Then
                RETURN 'スポーツの日';
            END IF;
        ELSIF (int年 >= 2003) Then
            If (str第N曜日 = '32') Then  -- 3rd Monday(2)
                RETURN '海の日';
            END IF;
        ELSIF (int年 >= 1996) Then
            If (int日 = 20) Then
                RETURN '海の日';
            END IF;
        END IF;

    -- 8月 --
    WHEN 8 THEN
        If (int年 >= 2021) Then
            If (int日 = 11) Then
                RETURN '山の日';
            END IF;
        ELSIF (int年 = 2020) Then
            -- 2020年はオリンピック特措法により「山の日」が 8/10 に移動
            If (int日 = 10) Then
                RETURN '山の日';
            END IF;
        ELSIF (int年 >= 2016) Then
            If (int日 = 11) Then
                RETURN '山の日';
            END IF;
        END IF;

    -- 9月 --
    WHEN 9 THEN
        --第3月曜日(15〜21)と秋分日(22〜24)が重なる事はない
        int秋分日 := prv秋分日(int年);
        If (int日 = int秋分日) Then    -- 1948〜2150以外は[99]が返るので、必ず≠になる
            RETURN '秋分の日';
        Else
            If (int年 >= 2003) Then
                str第N曜日 := TO_CHAR(TRUNC((int日 - 1) / 7) + 1,'FM0') || TO_CHAR(日付,'D');
                If (str第N曜日 = '32') Then    -- 3rd Monday(2)
                    RETURN '敬老の日';
                ELSIF (TO_CHAR(日付,'D') = vbTuesday) Then
                    If (int日 = (int秋分日 - 1)) Then
                        RETURN '国民の休日';    -- 火曜日&[秋分日の前日]
                    END IF;
                END IF;
            ELSIF (int年 >= 1966) Then
                If (int日 = 15) Then
                    RETURN '敬老の日';
                END IF;
            END IF;
        END IF;

    -- 10月 --
    WHEN 10 THEN
        str第N曜日 := TO_CHAR(TRUNC((int日 - 1) / 7) + 1,'FM0') || TO_CHAR(日付,'D');
        If (int年 >= 2021) Then
            If (str第N曜日 = '22') Then    -- 2nd Monday(2)
                RETURN 'スポーツの日';     -- 2020年より改名
            END IF;
        ELSIF (int年 = 2020) Then
            -- 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
            NULL;
        ELSIF (int年 >= 2000) Then
            If (str第N曜日 = '22') Then  -- 2nd Monday(2)
                RETURN '体育の日';
            END IF;
        ELSIF (int年 >= 1966) Then
            If (int日 = 10) Then
                RETURN '体育の日';
            END IF;
        END IF;

    -- 11月 --
    WHEN 11 THEN
        If (int日 = 3) Then
            RETURN '文化の日';
        ELSIF (int日 = 23) Then
            RETURN '勤労感謝の日';
        ELSIF (日付 = cst即位礼正殿の儀) Then
            RETURN '即位礼正殿の儀';  -- 平成天皇
        END IF;

    -- 12月 --
    WHEN 12 THEN
        If (int日 = 23) Then
            If ((int年 >= 1989) AND (int年 <= 2018)) Then
                RETURN '天皇誕生日';  -- 平成天皇
            END IF;
        END IF;
    End CASE;

    --この時点で戻り値の無いものは、平日
    RETURN NULL;
End prv祝日;

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

Function prv春分日( 年  IN  NUMBER ) RETURN NUMBER
IS
BEGIN
    If (年 <= 1947) Then
        RETURN 99;                --祝日法施行前
    ELSIF (年 <= 1979) Then
        RETURN TRUNC( 20.8357 + (0.242194 * (年 - 1980)) - TRUNC((年 - 1983) / 4));
    ELSIF (年 <= 2099) Then
        RETURN TRUNC( 20.8431 + (0.242194 * (年 - 1980)) - TRUNC((年 - 1980) / 4));
    ELSIF (年 <= 2150) Then
        RETURN TRUNC( 21.851  + (0.242194 * (年 - 1980)) - TRUNC((年 - 1980) / 4));
    Else
        RETURN 99;                --2151年以降は略算式が無いので不明
    END IF;
End prv春分日;

-- ****************************************************************************
-- ***  Sub Function    prv秋分日
-- ****************************************************************************

Function prv秋分日( 年  IN  NUMBER ) RETURN NUMBER
IS
BEGIN
    If (年 <= 1947) Then
        RETURN 99;                --祝日法施行前
    ELSIF (年 <= 1979) Then
        RETURN TRUNC(23.2588 + (0.242194 * (年 - 1980)) - TRUNC((年 - 1983) / 4));
    ELSIF (年 <= 2099) Then
        RETURN TRUNC(23.2488 + (0.242194 * (年 - 1980)) - TRUNC((年 - 1980) / 4));
    ELSIF (年 <= 2150) Then
        RETURN TRUNC(24.2488 + (0.242194 * (年 - 1980)) - TRUNC((年 - 1980) / 4));
    Else
        RETURN 99;                --2151年以降は略算式が無いので不明
    END IF;
End prv秋分日;

END ktHolidayName;
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
--_/  CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

/





[ この場所へのリンク ]


Python 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]
  2007/ 5/28   追記 ( [昭和の日] 改正 対応済み )
  2009/ 1/ 8   不具合修正( 下記参照 )
  2010/ 5/ 8   不具合修正( 下記参照 )
  2010/ 9/21   一部修正( 下記参照 )
  2014/ 5/29   [山の日] 改正の修正
  2015/11/30   一部修正( 下記参照 )
  2018/ 2/15   [天皇誕生日の変更] 改正の修正
  2018/ 6/21   5月4日 及び 振替休日の不具合修正( 下記参照 )
  2018/ 6/21   [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正
  2018/ 7/20   一部修正( 下記参照 )


    VBAコードのロジックを、そのまま[ Python ]用に書き直したものです。
    瀬戸口光宏」さんによる編集です。

    Python ではプログラムのブロック構造を「インデント」で表現します ( Python とインデント )。
    下記コードでは「空白4文字」でインデントしてあります。

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

    『祝日について

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

  --- 修正内容の説明 --------------------------------------
   2009/1/8
        秋分日判定( _autumn_equinox ) で4つ目の日付条件が間違っていました。
        1979 となっていたのを 2150 に修正しました。

   2010/5/8 1:30
        春分/秋分判定で、[〜1979年] の場合の式が間違っていました(基本式)。
        Python の int 関数は C/FortranのInt , VBAのFix と同じで
        小数部の単純な切り落としです( int(8.4)→8 , int(-8.4)→ -8 )。
        int((y - 1980) / 4)    →    int((y - 1983) / 4)

   2010/5/8 14:00 再修正
        Python 2.x と 3.x で整数同士の除算 ( / ) の結果が異なる点が問題でした。
        Python2.x ( 整数同士の除算結果は切捨除算 ( その値を超えない最大の整数 ) )
             30 / 4 = 7  ,  int(30 / 4) = 7                     ,  math.floor(30 / 4) = 7
             -30 / 4 = -8 ,  int(-30 / 4) = -8               ,  math.floor(-30 / 4) = -8
        Python3.x ( 整数同士の除算結果は実数 )
             30 / 4 = 7.5   ,  int(30 / 4) = 7                 ,  math.floor(30 / 4) = 7
             -30 / 4 = -7.5  ,  int(-30 / 4) = -7 (NG)   ,  math.floor(-30 / 4) = -8
        負数の場合、Python2.x では [ int((y - 1980) / 4) ] でも大丈夫でしたが、Python3.x では [ int((y - 1983) / 4) ] に
        する必要があります。共通して同じ結果が得られる math.floor に変更します ( Python2.2 から切捨除算演算子 ( // ) が
        サポートされているが、Python2.0/2.1 でエラーになるので math.floor で統一します)。
            int((y - 1980) / 4)  →  math.floor((y - 1980) / 4)

   2010/9/21
        (1) holiday_name() の引数で、[年,月,日] による指定方法の他に、datetime.date オブジェクトによる指定方法を
            加えました(月ごとの判定処理部分にあった year,month,day は date引数の要素として date.xxx の記述に
            変わっています)。
        (2) 文字列の扱いに関する Python 2.x/3.x 間の変更に対応しました。
            Python 2.x 系以前の場合には Unicode 文字列で、Python 3.x 系以降の場合には文字列で祝日名を
            返します(祝日名(文字列リテラル)の記述が u'XXX' から 'XXX' に変わっています。なお、Python2.x 系
            以前の場合に unicode変換を行なう処理を追加しています)。

  2015/11/30
        [ import math ] の記述をコードの先頭に追記。

  2018/6/21    : 修正前ソースコード ( Internet Archive )
        5月4日 ( 国民の休日:1986〜2006年 ) の判定処理に誤りがありました。
        elif date.day == 4:
            if date.year >= 2007:
                name = 'みどりの日'
            elif date.year >= 1986 and date.weekday() != MONDAY:
                name = '国民の休日'
        この [ date.weekday() != MONDAY ] が間違っていました。 ここでの判定式の本来の意味は、
                [ 曜日値が 『 日, 月, 火 〜 土 』 の並びで、曜日値 > 月曜日 ]
        です。つまり、火曜〜土曜の範囲が対象です。
        Python では曜日値が 『 月(0), 火(1) 〜 土(5), 日(6) 』 の並びであり、しかも、上記では月曜日しか除外していません。
        その結果 1986/5/4(日), 1997/5/4(日), 2003/5/4(日) が「国民の休日」と判定されていました。この日付での正解は
        『 只の日曜日 ( ≠ 祝日/休日 ) 』 です。  以下のように修正します。
        誤)   MONDAY, TUESDAY, WEDNESDAY = 0, 1, 2
              elif date.year >= 1986 and date.weekday() != MONDAY:
        正)   MONDAY, TUESDAY, WEDNESDAY, SUNDAY = 0, 1, 2, 6
              elif date.year >= 1986 and date.weekday() not in (MONDAY, SUNDAY):


        振替休日の判定処理に誤りがありました(振替休日の施行日判定が抜けている)。
        if not name and date.weekday() == MONDAY:
            prev = date + datetime.timedelta(days = -1)
            if holiday_name(prev.year, prev.month, prev.day):
                name = '振替休日'

        下記に修正します。
        if (not name) and (date.weekday() == MONDAY) and (date >= datetime.date(1973, 4, 12)):

  2018/7/20
        [ import sys ] の記述が抜けていましたので追記しました。

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

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


----------------------------------------------------------------------------------------
※※ Tab インデントの ファイル( Python_Holiday.txt ) を用意してありますのでダウンロードして使って下さい※※


#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
// ※※ このコードは「空白4文字」でインデントしてあります ※※
//
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/
//_/  --- Python 移植版 ---
//_/
//_/  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 )
//_/
//_/  この祝日判定コードは『Excel: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]という関数名そのものは、各自の環境に
//_/      おける命名規則に沿って変更しても構いません。
//_/ 
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

  追記 SETOGUCHI Mitsuhiro      http://straitmouth.jp/

  * 2007/May/26
  このスクリプトは JavaScript 用判定コード
    http://addinbox.sakura.ne.jp/holiday_logic.htm#JS
  を元に、Python 向けに移植したものです。

  holiday_name() は、年、月、日の3つの整数の引数を取ります。
  不適切な値を与えると、 ValueError が発生します。
  与えた日付が日本において何らかの祝日であれば、その名前が Unicode で返ります。
  祝日でない場合は None が返ります。

  * 2010/Sep/21
  holiday_name() にキーワード引数として datetime.date のオブジェクトも取れる
  ようにしました。これを指定する際は年、月、日は指定する必要がなく、指定しても
  無視されます。これにより、 jholiday モジュールを使用するスクリプトがすでに
  datetime.date のオブジェクトがある場合の効率が若干良くなります。

  holiday_name() は、指定した日が祝日であれば
    Python 2.x 以前の場合は Unicode 文字列を、
    Python 3.x 以降の場合は文字列を
  返します。指定した日が祝日でなければ、 Python のバージョンによらず None を返します。

  * 2014/May/29
  [山の日]改正の修正

  * 2015/Nov/30
  [ import math ]の記述をコードの先頭に追記

  * 2018/Feb/15
  [天皇誕生日の変更]改正の修正

  * 2018/June/21
  5月4日 ( 国民の休日:1986〜2006年 ) 及び 振替休日の判定処理に誤りがありましたので修正しました。

  * 2018/June/21
  [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動] 改正の修正

  * 2018/July/20
  [ import sys ]の記述が抜けていましたので追記しました


サンプル

Python 2.6.1 (r261:67515, Feb 11 2010, 15:47:53)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> import jholiday
>>> jholiday.holiday_name(2007, 4, 28)
None
>>> jholiday.holiday_name(2007, 4, 29)
u'\u662d\u548c\u306e\u65e5'
>>> print jholiday.holiday_name(2007, 4, 29).encode('euc-jp')
昭和の日
>>> import datetime
>>> date = datetime.date(2007, 4, 29)
>>> jholiday.holiday_name(date = date)
u'\u662d\u548c\u306e\u65e5'


Python 3.1.2 (r312:79360M, Mar 24 2010, 01:33:18)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import jholiday
>>> jholiday.holiday_name(2007, 4, 28)
>>> jholiday.holiday_name(2007, 4, 29)
'昭和の日'
>>> print(jholiday.holiday_name(2007, 4, 29))
昭和の日
>>> import datetime
>>> date = datetime.date(2007, 4, 29)
>>> jholiday.holiday_name(date = date)
'昭和の日'
"""



import datetime
import math
import sys

MONDAY, TUESDAY, WEDNESDAY, SUNDAY = 0, 1, 2, 6    # 月(0), 火(1), 水(2), 木(3), 金(4), 土(5), 日(6)

def _vernal_equinox(y):
    # 整数で年を与えると、その年の春分の日が3月の何日であるかを返す
    if y <= 1947:
        d = 99    # 祝日法施行前
    elif y <= 1979:
        d = math.floor(20.8357  +  0.242194 * (y - 1980)  -  math.floor((y - 1980) / 4))
    elif y <= 2099:
        d = math.floor(20.8431  +  0.242194 * (y - 1980)  -  math.floor((y - 1980) / 4))
    elif y <= 2150:
        d = math.floor(21.8510  +  0.242194 * (y - 1980)  -  math.floor((y - 1980) / 4))
    else:
        d = 99    # 2151年以降は略算式が無いので不明

    return d

def _autumn_equinox(y):
    # 整数で年を与えると、その年の秋分の日が9月の何日であるかを返す
    if y <= 1947:
        d = 99    # 祝日法施行前
    elif y <= 1979:
        d = math.floor(23.2588  +  0.242194 * (y - 1980)  -  math.floor((y - 1980) / 4))
    elif y <= 2099:
        d = math.floor(23.2488  +  0.242194 * (y - 1980)  -  math.floor((y - 1980) / 4))
    elif y <= 2150:
        d = math.floor(24.2488  +  0.242194 * (y - 1980)  -  math.floor((y - 1980) / 4))
    else:
        d = 99    # 2151年以降は略算式が無いので不明

    return d

def holiday_name(year = None, month = None, day = None, date = None):
    # holiday_name() の呼び出し方法は2通りあります。
    #
    # 1つ目の方法は、3つの引数 year, month, day に整数を渡す方法です。
    # もうひとつの方法は前述のキーワード引数 date に datetime.date のオブジェクトを渡す方法です。
    # この場合は year, month, day を渡す必要はなく、また、渡したとしても無視されます。
    #
    # holiday_name() は、その日が祝日であれば
    #     Python 2.x 系以前の場合には Unicode 文字列で
    #     Python 3.x 系以降の場合には文字列で
    # 祝日名を返します。
    # 指定した日が祝日でなければ、 Python のバージョンによらず None を返します。


    # [ date ]引数が省略された場合は [ year, month, day ]引数で日付を作成し [ date ]引数を差し替える。
    if date == None:
        date = datetime.date(year, month, day)

    if date < datetime.date(1948, 7, 20):
        return None    # 祝日法施行前: None で返す
    else:
        name = None    # name の初期値は None


    #-- 1月--
    if date.month == 1:
        if date.day == 1:
            name = '元日'
        else:
            if date.year >= 2000:
                if int((date.day - 1) / 7) == 1 and date.weekday() == MONDAY:    # 2nd Monday
                    name = '成人の日'
            else:
                if date.day == 15:
                    name = '成人の日'
    #-- 2月 --
    elif date.month == 2:
        if date.day == 11 and date.year >= 1967:
            name = '建国記念の日'
        elif date.day == 23 and date.year >= 2020:
            name = '天皇誕生日'
        elif (date.year, date.month, date.day) == (1989, 2, 24):
            name = '昭和天皇の大喪の礼'
    #-- 3月 --
    elif date.month == 3:
        if date.day == _vernal_equinox(date.year):    # 1948〜2150以外は[99]が返るので、必ず≠になる
            name = '春分の日'
    #-- 4月 --
    elif date.month == 4:
        if date.day == 29:
            if date.year >= 2007:
                name = '昭和の日'
            elif date.year >= 1989:
                name = 'みどりの日'
            else:
                name = '天皇誕生日# 昭和天皇
        elif (date.year, date.month, date.day) == (1959, 4, 10):
            name = '皇太子明仁親王の結婚の儀'
    #-- 5月 --
    elif date.month == 5:
        if date.day == 3:
            name = '憲法記念日'
        elif date.day == 4:
            if date.year >= 2007:
                name = 'みどりの日'
            elif (date.year >= 1986) and date.weekday() not in (MONDAY, SUNDAY):  # 火曜 以降(火〜土)
                # 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年)
                name = '国民の休日'
        elif date.day == 5:
            name = 'こどもの日'
        elif date.day == 6:
            if date.year >= 2007 and date.weekday() in (TUESDAY, WEDNESDAY):  # [5/3,5/4が日曜]ケースのみ、ここで判定
                name = '振替休日'
    #-- 6月 --
    elif date.month == 6:
        if (date.year, date.month, date.day) == (1993, 6, 9):
            name = '皇太子徳仁親王の結婚の儀'
    #-- 7月 --
    elif date.month == 7:
        if date.year >= 2021:
            if int((date.day - 1) / 7) == 2 and date.weekday() == MONDAY:    # 3rd Monday
                name = '海の日'
        elif date.year == 2020:
            # 2020年はオリンピック特措法により
            # 「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
            if date.day == 23:
                name = '海の日'
            elif date.day == 24:
                name = 'スポーツの日'
        elif date.year >= 2003:
            if int((date.day - 1) / 7) == 2 and date.weekday() == MONDAY:    # 3rd Monday
                name = '海の日'
        elif date.year >= 1996:
            if date.day == 20:
                name = '海の日'
    #-- 8月 --
    elif date.month == 8:
        if date.year >= 2021:
            if date.day == 11:
                name = '山の日'
        elif date.year == 2020:
            # 2020年はオリンピック特措法により「山の日」が 8/10 に移動
            if date.day == 10:
                name = '山の日'
        elif date.year >= 2016:
            if date.day == 11:
                name = '山の日'
    #-- 9月 --
    elif date.month == 9:
        autumn_equinox = _autumn_equinox(date.year)
        if date.day == autumn_equinox:    # 1948〜2150以外は[99]が返るので、必ず≠になる
            name = '秋分の日'
        else:
            if date.year >= 2003:
                if int((date.day - 1) / 7) == 2 and date.weekday() == MONDAY:    # 3rd Monday
                    name = '敬老の日'
                elif date.weekday() == TUESDAY and date.day == autumn_equinox - 1:
                    name = '国民の休日'    # 火曜日&[秋分日の前日]
            elif date.year >= 1966 and date.day == 15:
                name = '敬老の日'
    #-- 10月 --
    elif date.month == 10:
        if date.year >= 2021:
            if int((date.day - 1) / 7) == 1 and date.weekday() == MONDAY:    # 2nd Monday
                name = 'スポーツの日'    # 2020年より改名
        elif date.year == 2020:
            # 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
            pass
        elif date.year >= 2000:
            if int((date.day - 1) / 7) == 1 and date.weekday() == MONDAY:    # 2nd Monday
                name = '体育の日'
        elif date.year >= 1966:
            if date.day == 10:
                name = '体育の日'
    #-- 11月 --
    elif date.month == 11:
        if date.day == 3:
            name = '文化の日'
        elif date.day == 23:
            name = '勤労感謝の日'
        elif (date.year, date.month, date.day) == (1990, 11, 12):
            name = '即位礼正殿の儀'
    #-- 12月 --
    elif date.month == 12:
        if date.day == 23 and date.year >= 1989 and date.year <= 2018:
            name = '天皇誕生日# 平成天皇


    # ----- 振替休日の判定 (振替休日施行日:1973/4/12) -----
    # [ 対象日≠祝日/休日 & 対象日=月曜日 ]のみ、前日(=日曜日)を祝日判定する。
    # 前日(=日曜日)が祝日の場合は”振替休日”となる。
    # 尚、5月6日の扱いを
    #     「火曜 or 水曜(みどりの日(5/4) or 憲法記念日(5/3)の振替休日)」⇒5月ブロック内で判定済
    #     「月曜(こどもの日(5/5)の振替休日」⇒ここの判定処理で判定
    # とする事により、ここでの判定対象は『対象日が月曜日』のみ となります。
    #
    # name は祝日名 or None (初期値, 祝日ではない場合の値)です。
    # 論理演算では「空文字以外の文字列⇒true, 空文字⇒false, None⇒false 」と扱われます。
    # [ not name ] は、祝日名が得られた⇒false , 祝日が得られない⇒true となります。

    if (not name) and (date.weekday() == MONDAY) and (date >= datetime.date(1973, 4, 12)):
        prev = date + datetime.timedelta(days = -1)
        if holiday_name(prev.year, prev.month, prev.day):
            name = '振替休日'


    # holiday_name() は 指定した日が祝日であれば
    #     Python 2.x 以前の場合は Unicode 文字列を、
    #     Python 3.x 以降の場合は文字列を
    # 返します。指定した日が祝日でなければ Python のバージョンによらず None を返します。

    if name and sys.version_info[0] < 3:
        name = unicode(name, 'utf-8')

    return name    # [祝日]等:その名称 , 祝日ではない:None


"""
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/ CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
"""







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