AddinBox(Title_Logo)

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

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

      VBA用コードは純粋にVB構文だけ(エクセル独自の機能は使ってません)で作って
    ありますので、エクセルだけでなくアクセスや、その他のVBAを使うアプリケーション
    でも利用できます。
  ※ 重要 ※
    [ シルバーウィーク(10月) ] という 5年前に一度潰えた祝日構想が
    再び持ち上がっています(H24/5/12)。

    [ 主権回復記念日 ] という新たな祝日構想が持ち上がっています(H23/9/10)。

    祝日分散化&ハッピーマンデー廃止法案 の動向にご注意ください( H22/2/14 )。
    上記法案成立時に必要となる 祝日ロジック修正の検討 を始めました( H22/3/11 )。
 
 
  ※ 訂正案内 2011/3/20 ※
    JavaScript の コード において、[FireFox TraceMonkey バグ] 対応の修正を行ないました。

  ※ 訂正案内 2011/3/15 ※
    Perl の コード において、エポック秒を取得する為の timelocal を使用する際の注意事項
    を記載しました。なお、祝日判定スクリプトコード自体に変更はありません。スクリプトを呼び
    出す側での注意事項です(祝日判定スクリプト利用時に限らず timelocal の一般的な注意
    事項となります)。
    利用されている方は注意事項の解説を良く読んで対応してください。
 

※VBA以外に移植したコードも紹介しています※
 下記の コード には 「昭和の日」 改正に伴う 修正 を施してあります。 ( 2005/5/20 )
--言語-- -- 移 植 -- -公開日- -頁-
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
       
      自由に各自のプログラムに組み込んで利用して下さい。なお、フリー/シェアソフト
    開発での利用も可(フリー/シェアでの利用の場合、事後で結構ですので一言
    お知らせください)です。ただし、引用に当たっては、マクロの先頭に記述してある
        コメント(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 用祝日判定コード 】  2006/8/1 追記 , [昭和の日] 改正 対応済
      VBAコードのロジックを、そのまま[Transact-SQL ]用に書き直したものです。
    シリコンブレス「有方 公一」さんによる編集です。この祝日機能を搭載したHP向け
    カレンダーツール の提供もされてます。

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

    下記コードは「昭和の日」改正に対応しています。対応方法の考え方については こちら を参照。

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


CREATE Procedure usp_GetHolidayName
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
--_/
--_/ CopyRight(C) K.Tsunoda(AddinBox) 2001     All     Rights Reserved.
--_/ ( http://www.h3.dion.ne.jp/~sakatsu/index.htm     )
--_/
--_/  この祝日マクロは『kt関数アドイン』で使用しているVBAマクロ
--_/  を[Transact-SQL]に移植したものです。
--_/  このロジックは、レスポンスを第一義として、可能な限り少ない
--_/ 【条件判定の実行】で結果を出せるように設計してあります。
--_/  この関数では、2007年施行の改正祝日法(昭和の日)までを
--_/ サポートしています(9月の国民の休日を含む)。
--_/
--_/ (*1)このマクロを引用するに当たっては、必ずこのコメントも
--_/   一緒に引用する事とします。
--_/ (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
--_/   【 http://www.h3.dion.ne.jp/~sakatsu/holiday_logic.htm 】
--_/   へのリンクによる紹介で対応して下さい。
--_/ (*3)[ktHolidayName]という関数名そのものは、各自の環境に
--_/   おける命名規則に沿って変更しても構いません。
--_/
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

--【機能】休日名を取得する
--【引数】@prmTargetDate  対象日付
--【戻値】休日名
--【備考】usp_GetHolidayStringで祝日を取得し、
--    このストアドで振替休日判定をおこなう

        @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
        
        if(@HolidayName = '')
                begin
                if(DATEPART(weekday,@prmTargetDate)     = 2)
                        begin
                        -- 月曜以外は振替休日判定不要
                        -- 5/6(火,水)の判定は[usp_GetHolidayString]で処理済
                        -- 5/6(月)はここで判定する
                        if(@prmTargetDate >= @FrSiko)
                                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)
        set @intDay     = Day(@prmTargetDate)

        set @HolidayString =    ''
        
        /*----- 祝日法施行以前 -----*/
        if(@prmTargetDate <     @HoSiko)
                return
        
        else
        /*----- 祝日判定 -----*/
        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')    --第二月曜日Monday:2
                                        set @HolidayString =    '成人の日'
                                
                                end
                                
                        else
                                begin
                                if(@intDay = 15)
                                        set @HolidayString =    '成人の日'
                                end
                        end
                end
        
        else
        if(@intMonth = 2)
                begin
                if(@intDay = 11)
                        begin
                        if(@intYear     >= 1967)
                                set @HolidayString =    '建国記念の日'
                        end
                else
                        begin
                        if(@prmTargetDate =     @Taiso)
                                set @HolidayString =    '昭和天皇の大喪の礼'
                        end
                end
                
        else
        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
        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)
                                set @HolidayString =    '皇太子明仁親王の結婚の儀'
                        end
                end
                
        else
        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) --月曜以降
                                                        --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)     = 2 or DATEPART(weekday,@prmTargetDate) = 3) 
                                                                begin
                                                                --火曜日または水曜日[5/3,5/4が日曜]ケースのみ
                                                                set @HolidayString =    '振替休日'
                                                                end
                                                        end
                                                end
                                        end
                                end
                        end
                end
                
        else
        if(@intMonth = 6)
                begin
                if(@prmTargetDate =     @Norihito)
                        set @HolidayString =    '皇太子徳仁親王の結婚の儀'
                end
                
        else
        if(@intMonth = 7)
                begin
                if(@intYear     >= 2003)
                        begin
                        set @Youbi =    CONVERT(varchar,((@intDay -     1) / 7) + 1) + CONVERT(varchar,DATEPART(weekday,@prmTargetDate))
                        if(@Youbi =     '32')   --第三月曜日Monday:2
                                set @HolidayString =    '海の日'
                        end
                else
                        begin
                        if(@intYear     >= 1996)
                                if(@intDay = 20)
                                        set @HolidayString =    '海の日'
                        end
                end
                
        else
        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')    --第三月曜日Monday:2
                                         set    @HolidayString = '敬老の日'
                                else
                                        begin
                                        if(DATEPART(weekday,@prmTargetDate)     = 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
        if(@intMonth = 10)
                begin
                if(@intYear     >= 2000)
                        begin
                        set @Youbi =    CONVERT(varchar,((@intDay -     1) / 7) + 1) + CONVERT(varchar,DATEPART(weekday,@prmTargetDate))
                        if(@Youbi =     '22')   --第二月曜日Monday:2
                                set @HolidayString =    '体育の日'
                        end
                        
                else
                        begin
                        if(@intYear     >= 1966)
                                begin
                                if(@intDay = 10)
                                        set @HolidayString =    '体育の日'
                                end
                        end
                end
                
        else
        if(@intMonth = 11)
                begin
                if(@intDay = 3)
                        set @HolidayString =    '文化の日'
                else
                        begin
                        if(@intDay = 23)
                                set @HolidayString =    '勤労感謝の日'
                        else
                                begin
                                if(@prmTargetDate =     @Sokui)
                                        set @HolidayString =    '即位礼正殿の儀'
                                end
                        end
                end
                
        else
        if(@intMonth = 12)
                begin
                if(@intDay = 23)
                        begin
                        if(@intYear     >= 1989)
                                set @HolidayString =    '天皇誕生日'
                        end
                end
        
        return







Oracle PL/SQL 用祝日判定コード 】  2006/12/1 追記  [昭和の日]改正 対応済み
      VBAコードのロジックを、そのまま[PL/SQL(Oracle9i) ]用に書き直したものです。
    「菅 康明」さんによる編集です。
    土日なども一緒に判定するなど条件を付加する場合は、こちらの解説を参考にして下さい。
    『祝日について

    下記コードは「昭和の日」対応済みです。昭和の日に関する処理については こちら を参照。



CREATE OR REPLACE PACKAGE ktHolidayName IS
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
--_/
--_/ CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
--_/ ( http://www.h3.dion.ne.jp/~sakatsu/index.htm )
--_/
--_/  この祝日マクロは『kt関数アドイン』で使用しているものです。
--_/  このロジックは、レスポンスを第一義として、可能な限り少ない
--_/   【条件判定の実行】で結果を出せるように設計してあります。
--_/  この関数では、2007年施行の改正祝日法(昭和の日)までを
--_/   サポートしています(9月の国民の休日を含む)。
--_/
--_/ (*1)このマクロを引用するに当たっては、必ずこのコメントも
--_/   一緒に引用する事とします。
--_/ (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
--_/   【 http://www.h3.dion.ne.jp/~sakatsu/holiday_logic.htm 】
--_/   へのリンクによる紹介で対応して下さい。
--_/ (*3)[ktHolidayName]という関数名そのものは、各自の環境に
--_/   おける命名規則に沿って変更しても構いません。
--_/ 
--_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

-- =============================================================================
-- ==【PL/SQL用祝日判定コード 】 2006/11/29(Wed) 追記
-- ==VBAコードのロジックを、そのまま[PL/SQL]用に書き直したものです。
-- ==
-- ==■環境依存
-- ==・TO_CHAR(日時)関数の戻り値について
-- ==
-- ==曜日取得の際に使用しているTO_CHAR(日時)の'D'の戻り値については、
-- ==環境に依存します。
-- ==もし、月曜=1となる場合は、パッケージ定数vbMonday〜vbWednesdayと
-- ==成人の日/海の日/敬老の日/体育の日の判定における
-- ==     If (str第N曜日 = '22') Then  --Monday:2  または
-- ==     If (str第N曜日 = '32') Then  --Monday:2
-- ==で各々[21][31]に修正する必要があります。
-- ==
-- ==※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定数が無いもの)
        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日付);
        If (str祝日名 IS NULL) Then
                If (TO_CHAR(dtm日付,'D') = vbMonday) Then
                        -- 月曜以外は振替休日判定不要
                        -- 5/6(火,水)の判定は[prv祝日]で処理済
                        -- 5/6(月)はここで判定する
                        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月
        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  --Monday:2
                                        RETURN '成人の日';
                                END IF;
                        Else
                                If (int日 = 15) Then
                                        RETURN '成人の日';
                                END IF;
                        END IF;
                END IF;
        WHEN 2 THEN
                If (int日 = 11) Then
                        If (int年 >= 1967) Then
                                RETURN '建国記念の日';
                        END IF;
                ELSIF (日付 = cst昭和天皇の大喪の礼) Then
                        RETURN '昭和天皇の大喪の礼';
                END IF;
        WHEN 3 THEN
                If (int日 = prv春分日(int年)) Then      -- 1948〜2150以外は[99]
                        RETURN '春分の日';                              -- が返るので、必ず≠になる
                END IF;
        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;
        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;
        WHEN 6 THEN
                If (日付 = cst徳仁親王の結婚の儀) Then
                        RETURN '皇太子徳仁親王の結婚の儀';
                END IF;
        WHEN 7 THEN
                If (int年 >= 2003) Then
                        str第N曜日      :=      TO_CHAR(TRUNC((int日 - 1) / 7) + 1,'FM0')
                                                ||      TO_CHAR(日付,'D');
                        If (str第N曜日 = '32') Then  --Monday:2
                                RETURN '海の日';
                        END IF;
                ELSIF (int年 >= 1996) Then
                        If (int日 = 20) Then
                                RETURN '海の日';
                        END IF;
                END IF;
        WHEN 8 THEN
                NULL;           --祝日無し
        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  --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;
        WHEN 10 THEN
                If (int年 >= 2000) Then
                                str第N曜日      :=      TO_CHAR(TRUNC((int日 - 1) / 7) + 1,'FM0')
                                                        ||      TO_CHAR(日付,'D');
                        If (str第N曜日 = '22') Then  --Monday:2
                                RETURN '体育の日';
                        END IF;
                ELSIF (int年 >= 1966) Then
                        If (int日 = 10) Then
                                RETURN '体育の日';
                        END IF;
                END IF;
        WHEN 11 THEN
                If (int日 = 3) Then
                        RETURN '文化の日';
                ELSIF (int日 = 23) Then
                        RETURN '勤労感謝の日';
                ELSIF (日付 = cst即位礼正殿の儀) Then
                        RETURN '即位礼正殿の儀';
                END IF;
        WHEN 12 THEN
                If (int日 = 23) Then
                        If (int年 >= 1989) 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 用祝日判定コード 】  2007/5/28 追記  [昭和の日]改正 対応済み
                                                      2009/1/8 一部修正 , 2010/5/8 一部修正
                                                      2010/9/21 一部修正

      VBAコードのロジックを、そのまま[ Python ]用に書き直したものです。
    瀬戸口光宏」さんによる編集です。
    土日なども一緒に判定するなど条件を付加する場合は、こちらの解説を参考にして下さい。
    『祝日について

    下記コードは「昭和の日」対応済みです。昭和の日に関する処理については こちら を参照。

   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変換を行なう処理を追加しています)。



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

"""
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/
//_/  CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
//_/  ( http://www.h3.dion.ne.jp/~sakatsu/index.htm )
//_/
//_/    この祝日判定コードは『Excel:kt関数アドイン』で使用しているものです。
//_/    この関数では、2007年施行の改正祝日法(昭和の日)までを
//_/   サポートしています(9月の国民の休日を含む)。
//_/
//_/  (*1)このコードを引用するに当たっては、必ずこのコメントも
//_/      一緒に引用する事とします。
//_/  (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
//_/      【 http://www.h3.dion.ne.jp/~sakatsu/holiday_logic.htm 】
//_/      へのリンクによる紹介で対応して下さい。
//_/  (*3)[ktHolidayName]という関数名そのものは、各自の環境に
//_/      おける命名規則に沿って変更しても構いません。
//_/  
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

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

 * 2007/May/26
 このスクリプトは JavaScript 用判定コード
  http://www.h3.dion.ne.jp/~sakatsu/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 を返します。


サンプル

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

MONDAY, TUESDAY, WEDNESDAY = 0, 1, 2

def _vernal_equinox(y):
    """整数で年を与えると、その年の春分の日が3月の何日であるかを返す
"""
    if y <= 1947:
        d = 0
    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 = 0

    return d

def _autumn_equinox(y):
    """整数で年を与えると、その年の秋分の日が9月の何日であるかを返す
"""
    if y <= 1947:
        d = 0
    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 = 0

    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 を返します。
"""

    if date == None:
        date = datetime.date(year, month, day)

    if date < datetime.date(1948, 7, 20):
        return None
    else:
        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:
                    name = '成人の日'
            else:
                if date.day == 15:
                    name = '成人の日'
    # 2月
    elif date.month == 2:
        if date.day == 11 and date.year >= 1967:
            name = '建国記念の日'
        elif (date.year, date.month, date.day) == (1989, 2, 24):
            name = '昭和天皇の大喪の礼'
    # 3月
    elif date.month == 3:
        if date.day == _vernal_equinox(date.year):
            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() != MONDAY:
                name = '国民の休日'
        elif date.day == 5:
            name = 'こどもの日'
        elif date.day == 6:
            if date.year >= 2007 and date.weekday() in (TUESDAY, WEDNESDAY):
                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 >= 2003:
            if int((date.day - 1) / 7) == 2 and date.weekday() == MONDAY:
                name = '海の日'
        elif date.year >= 1996 and date.day == 20:
            name = '海の日'
    # 8月 (祝日なし)
    # 9月
    elif date.month == 9:
        autumn_equinox = _autumn_equinox(date.year)
        if date.day == autumn_equinox:
            name = '秋分の日'
        else:
            if date.year >= 2003:
                if int((date.day - 1) / 7) == 2 and date.weekday() == 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 >= 2000:
            if int((date.day - 1) / 7) == 1 and date.weekday() == MONDAY:
                name = '体育の日'
        elif date.year >= 1966 and 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:
            name = '天皇誕生日'

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

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

    return name


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






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