
-- 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. //_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ """
![]()