AddinBox(Title_Logo)

  -- Page 4 --

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

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

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

 
  ※ 訂正案内 2021/6/13 ※
    Ruby および Apollo で 2020/2021年の「山の日」判定に誤りがありましたので修正しました。
    修正箇所の説明は各言語版の項に記してあります。



※VBA以外に移植したコードも紹介しています※
 ・ 「東京五輪 祝日移動(2021年)」 改正への対応済みです。 (2020/11/28)

   [ 旧サイト ( DIONサーバー ) の Internet Archive ( Page 4 ) ]
      -頁-
  ・ 祝日判定マクロ の 設計方針について
  ・ And / Or 演算子 : 完全評価( Complete )型 と 短絡評価( Short-circuit )型
  ・ オーソドックス な 「表引き」 手法との比較
  ・ 祝日判定の拡張 ( 土日も含める 等 ) について
  ・ 拡張マクロ : 銀行休日の判定
  ・ 5月6日 ( 振替休日 ) の判定方法について
  ・ 2019年GWの休日(4/30,5/1,5/2) の判定方法について
  ・ ( 番外 ) 新元号対応 日付変換関数 EraFormat / EraCDate
 
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
Scala gakuzzzz さん 2019/ 1/17
       
      自由に各自のプログラムに組み込んで利用して下さい。なお、フリー/シェアソフト
    開発での利用も可(フリー/シェアでの利用の場合、事後で結構ですので一言
    お知らせください)です。ただし、引用に当たっては、マクロの先頭に記述してある
        コメント(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祝日には手を加えずに、その外側にプロシ
ジャーを用意して、そこで機能追加を施すようにして下さい。




[ この場所へのリンク ]


Apollo 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]  [ 不具合報告 メール送信 ]
  2003/9/24 追記
  2005/5/20 [昭和の日]改正の修正
  2007/5/28 祝日名が '元' になっていたのを '元' に修正
  2014/5/29 [山の日]改正の修正
  2018/2/15 [天皇誕生日の変更]改正の修正
  2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動(2020年)] 改正の修正
  2018/12/8 [即位の日 および 4/30 & 5/2の国民の休日] [即位礼正殿の儀] 改正の修正
  2020/11/28 [五輪特措法による祝日移動(2021年)] 改正の修正
  2021/6/13 2020/2021年の「山の日」判定が誤っていたのを修正(下記参照)


    VBAコードのロジックを、そのまま[Apollo ]用に書き直したものです。
    たけ(tk)」さんによる編集です。

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

    『祝日について

    「昭和の日」に伴う「振替休日(5月6日)」改正への修正方針もお読みください。
    「即位の日(2019/5/1)」に伴う「祝日に挟まれた平日(4/30 & 5/2)の休日化」への修正方針もお読みください。

    --- Apollo について補足 ---
    Apollo とは『 Ruby 』と『 Delphi 』を結び付ける(Delphi からRuby の機能を呼び出したり、
    逆にRuby からDelphi VCL を利用したりする)インターフェース機構の総称です。詳しくは
    下記のHPを参照して下さい。
        [ Apollo - Delphi Ruby interface ]
    なお、下記のコードは以下のメーリングリストにも掲載されています。
        [ http://www.freeml.com/ctrl/html/MessageListForm/ap-ext@freeml.com / No.143 ]


  --- 修正内容の説明 --------------------------------------
  2021/6/13    : 「山の日」判定の組み立てが誤っており、2020年では [ 8/10 & 8/11 ]、2021年では [ 8/8 & 8/11 ] が
                         「山の日」 と判定されていました。
      ( 修正前の誤コード )
    when 8
      return '山の日' if ( year >= 2022 ) && ( day == 11 )
      return '山の日' if ( year == 2021 ) && ( day == 8 )
      return '山の日' if ( year == 2020 ) && ( day == 10 )
      return '山の日' if ( year >= 2016 ) && ( day == 11 )   この判定が 2020/2021年でも反応する為の誤判定

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

    ----------- Apollo における 曜日値について -----------
        曜日値を取得する関数が2つ ( cwday , wday ) あります。
        cwday の曜日の値は [ 月(1), 火(2), 水(3), 木(4), 金(5), 土(6), 日(7) ] です。
        wday の曜日の値は [ 日(0), 月(1), 火(2), 水(3), 木(4), 金(5), 土(6) ] です。
        どちらにもシステム定数は用意されていません。
        このプログラムでは [ 日, 月, … 土 ] 並びの wday を使っています。


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

 


#! ruby -Ks
#-- Shukujitu.rb
#-- Shukujitu.pi

# FROM http://addinbox.sakura.ne.jp/holiday_logic.htm

##_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
##_/
##_/  --- Apollo 移植版 ( Update: 2021/6/13 ) ---
##_/
##_/  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関数アドイン]で使用している
##_/  VBAマクロを[Apollo]に移植したものです。
##_/
##_/  この関数では以下の祝日変更までサポートしています。
##_/    (a) 2019年施行の「天皇誕生日の変更」 12/23⇒2/23 (補:2019年には[天皇誕生日]はありません)
##_/    (b) 2019年の徳仁親王の即位日(5/1) および
##_/       祝日に挟まれて「国民の休日」となる 4/30(平成天皇の退位日) & 5/2 の2休日
##_/    (c) 2019年の「即位の礼 正殿の儀 (10/22) 」
##_/    (d) 2020年施行の「体育の日の改名」⇒スポーツの日
##_/    (e) 五輪特措法による2020年の「祝日移動」
##_/       海の日:7/20(3rd Mon)⇒7/23, スポーツの日:10/12(2nd Mon)⇒7/24, 山の日:8/11⇒8/10
##_/    (f) 五輪特措法による2021年の「祝日移動」
##_/       海の日:7/19(3rd Mon)⇒7/22, スポーツの日:10/11(2nd Mon)⇒7/23, 山の日:8/11⇒8/8
##_/
##_/ (1) このコードを引用するに当たっては、必ずこのコメントも
##_/    一緒に引用する事とします。
##_/ (2) 他サイト上で本マクロを直接引用する事は、ご遠慮願います。
##_/      [ http://addinbox.sakura.ne.jp/holiday_logic.htm ]
##_/      へのリンクによる紹介で対応して下さい。
##_/ (3) [ktHolidayName]という関数名そのものは、各自の環境に
##_/      おける命名規則に沿って変更しても構いません。
##_/
##_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
##
## VBA以外の言語に移植する場合は、その言語の特性に合わせたベストな
## コード構成に変更しても構いません。
##
## また、出来上がったものをご連絡頂ければ、このページにて紹介させて貰います。
##
## 2003-09-21(日):…とのことなので imported by take_tk
##
## 2014/5/29 [山の日]改正の修正
##
## 2018/2/15 [天皇誕生日の変更]改正の修正
##
## 2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動(2020年)] 改正の修正
##
## 2018/12/8 [即位の日 および 4/30 & 5/2の国民の休日] [即位礼正殿の儀] 改正の修正
##
## 2020/11/28 [五輪特措法による祝日移動(2021年)] 改正の修正
##
## 2021/6/13  2020/2021年の「山の日」判定が誤っていたのを修正
##
##
## Apollo(ruby) の特徴
## (1) 条件判断では文字列は真、nilは偽の扱いになる。
## (2) returnがない場合には、最後の文の値が戻り値となる。
## (3) 論理演算は短絡評価型。「||」で左がtrueなら右は判断しない、「&&」で左がfalseなら右は判断しない。
##
##


require "phi"

module Shukujitu

  # wday メソッド : 日(0),月(1) ... 土(6)
  MONDAY = 1
  TUESDAY = 2
  WEDNESDAY = 3

  def self.shukujitu? date
    date = Phi::DateTime.new(date) unless date.is_a? Phi::DateTime
    kihon_shukujitu?(date) || hurikae_kyujitu?(date)
    # OR条件式(短絡評価型)なので、
    # kihon_shukujitu で祝日名が得られる( 文字列 ⇒ 論理値:true ) ... hurikae_kyujitu は処理されない
    # kihon_shukujitu で祝日名が得られない( nil ⇒ 論理値:false ) ... 続けて hurikae_kyujitu が処理される
  end

  D_1973_4_12 = Phi::DateTime.new("1973/4/12")   # 振替休日 施行日


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

  def self.hurikae_kyujitu? date
    if ( date.wday == MONDAY ) && ( date >= D_1973_4_12 ) && ( kihon_shukujitu? date.inc_day(-1) )
      # AND条件式(短絡評価型)なので、月曜日以外では kihon_shukujitu は処理されない
      # [ 対象日≠祝日/休日 ] の判定は上記の self.shukujitu で行われている
      # kihon_shukujitu で祝日名が得られる( 文字列 ⇒ 論理値:true )
      # kihon_shukujitu で祝日名が得られない( nil ⇒ 論理値:false )
      return '振替休日'
    end
  end

  D_1948_7_20 = Phi::DateTime.new("1948/7/20")   # 祝日法 施行日

  def self.kihon_shukujitu? date
    date  = Phi::DateTime.new(date) unless date.is_a? Phi::DateTime
    date  = date.date
    return if date < D_1948_7_20  # 祝日法施行前( nil で返す )

    year = date.year
    month = date.month   # 月(1〜12)
    day = date.day
    yobi = date.wday   # wday メソッド : 日(0),月(1) ... 土(6)
    shuu = ( day - 1 ) / 7 + 1   # for 2nd Monday/3rd Monday

    case month
    #-- 1月 --
    when 1
      return '元日' if ( day == 1 )
      if ( year >= 2000 )
        return '成人の日' if ( yobi == MONDAY ) && ( shuu == 2 )   # 2nd Monday
      else
        return '成人の日' if ( day == 15 )
      end

    #--2月 --
    when 2
      case day
        when 11 ; return '建国記念の日' if ( year >= 1967 )
        when 23 ; return '天皇誕生日' if ( year >= 2020 )
        when 24 ; return '昭和天皇の大喪の礼' if ( year == 1989 )
      end

    #-- 3月 --
    when 3
      return '春分の日' if ( day == shunbun_day(year) )

    #-- 4月 --
    when 4
      case day
        when 29
          case year
            when 2007..9999 ; return '昭和の日'
            when 1989..2006 ; return 'みどりの日'
            else ; return '天皇誕生日# 昭和天皇
          end
        when 30 ; return '国民の休日' if ( year == 2019 )  # 祝日に挟まれた国民の休日です(平成天皇の退位日)
        when 10 ; return '皇太子明仁親王の結婚の儀' if ( year == 1959 )
      end

    #-- 5月 --
    when 5
      case day
        when 3  ; return '憲法記念日'
        when 4
          case year
            when 2007..9999 ; return 'みどりの日'
            when 1986..2006 ; return '国民の休日' if ( yobi > MONDAY )    # 火曜 以降(火〜土)
                  # 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年)
          end
        when 5  ; return 'こどもの日'
        when 6  ; return '振替休日' if ( year >= 2007 ) && ( [TUESDAY,WEDNESDAY].include? yobi )
                    # [5/3,5/4が日曜]ケースのみ、ここで判定

        # 5/1 & 5/2 は2019年のみの臨時祝日なので最後に判定する
        when 1 ; return '即位の日' if ( year == 2019 )  # 徳仁親王
        when 2 ; return '国民の休日' if ( year == 2019 )  # 祝日に挟まれた国民の休日です
      end

    #-- 6月 --
    when 6
      return '皇太子徳仁親王の結婚の儀' if ( day == 9 ) && ( year == 1993 )

    #-- 7月 --
    when 7
      if ( year >= 2022 )
        return '海の日' if ( shuu == 3 ) && ( yobi == MONDAY )   # 3rd Monday
      elsif ( year == 2021 )
          # 2021年はオリンピック特措法により
          #「海の日」が 7/22 , 「スポーツの日」が 7/23 に移動
        return '海の日' if ( day == 22 )
        return 'スポーツの日' if ( day == 23 )
      elsif ( year == 2020 )
          # 2020年はオリンピック特措法により
          #「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
        return '海の日' if ( day == 23 )
        return 'スポーツの日' if ( day == 24 )
      elsif ( year >= 2003 )
        return '海の日' if ( shuu == 3 ) && ( yobi == MONDAY )   # 3rd Monday
      elsif ( year >= 1996 )
        return '海の日' if ( day == 20 )
      end

    #-- 8月 --
    when 8
      # 2021年はオリンピック特措法により「山の日」が 8/8 に移動
      # 2020年はオリンピック特措法により「山の日」が 8/10 に移動
      if ( year >= 2022 )
          return '山の日' if ( day == 11 )
      elsif ( year == 2021 )
          return '山の日' if ( day == 8 )
      elsif ( year == 2020 )
          return '山の日' if ( day == 10 )
      elsif ( year >= 2016 )
          return '山の日' if ( day == 11 )
      end

    #-- 9月 --
    when 9
      shuubun_day = shuubun_day(year)
      return '秋分の日' if ( shuubun_day == day )
      if ( year >= 2003 )
        return '敬老の日' if ( yobi == MONDAY ) && ( shuu == 3 )   # 3rd Monday
        return '国民の休日' if ( yobi == TUESDAY ) && ( day == shuubun_day - 1 )   # 火曜日&[秋分日の前日]
      elsif ( year >= 1966 )
        return '敬老の日' if ( day == 15 )
      end

    #-- 10月 --
    when 10
      if ( year >= 2022 )
        return 'スポーツの日' if ( yobi == MONDAY ) && ( shuu == 2 )   # 2nd Monday , 2020年より改名
      elsif ( year == 2020 ) || ( year == 2021 )
        # 2021年はオリンピック特措法により「スポーツの日」が 7/23 に移動
        # 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
        return nil
      elsif ( year >= 2000 )
        return '体育の日' if ( yobi == MONDAY ) && ( shuu == 2 )   # 2nd Monday
        return '即位礼正殿の儀' if ( year == 2019 ) && ( day == 22 )   # 徳仁親王
      elsif (year >= 1966)
        return '体育の日' if ( day == 10 )
      end

    #-- 11月 --
    when 11
      case day
        when  3 ; return '文化の日'
        when 23 ; return '勤労感謝の日'
        when 12 ; return '即位礼正殿の儀' if ( year == 1990 )   # 平成天皇
      end

    #-- 12月 --
    when 12
      return '天皇誕生日' if ( day == 23 ) && ( year >= 1989 ) && ( year <= 2018 )  # 平成天皇

    end

    return nil    # 祝日ではない場合 nil で返す
  end
 
  # 春分/秋分日の略算式は
  #    『海上保安庁水路部 暦計算研究会編 新こよみ便利帳』
  # で紹介されている式です。
  # ruby の (-5/4) は -2 を返すので 1980 を使用する。
  # http://addinbox.sakura.ne.jp/holiday_topic.htm#Note
  #


  #--- 春分日の略算式 ---
  def self.shunbun_day(year) # return day
    case year
      when 1948..1979 ; return (20.8357 + (0.242194 * (year - 1980)) - ((year - 1980) / 4)).to_i;
      when 1980..2099 ; return (20.8431 + (0.242194 * (year - 1980)) - ((year - 1980) / 4)).to_i;
      when 2100..2150 ; return (21.8510 + (0.242194 * (year - 1980)) - ((year - 1980) / 4)).to_i;
    end
    return 99 # 祝日法施行前および2151年以降は略算式が無いので不明
  end

  #--- 秋分日の略算式 ---
  def self.shuubun_day(year) # return day
    case year
      when 1948..1979 ; return (23.2588 + (0.242194 * (year - 1980)) - ((year - 1980) / 4)).to_i;
      when 1980..2099 ; return (23.2488 + (0.242194 * (year - 1980)) - ((year - 1980) / 4)).to_i;
      when 2100..2150 ; return (24.2488 + (0.242194 * (year - 1980)) - ((year - 1980) / 4)).to_i;
    end
    return 99 # 祝日法施行前および2151年以降は略算式が無いので不明
  end

end # of module

module Phi
class DateTime
  def shukujitu?
    Shukujitu.shukujitu?(self)
  end
end


---- 利用サンプル ----

--ruby
#! ruby -Ks
require "phi"
require "Shukujitu"

year = 2003
date = Phi::DateTime.new(year,1,1)
while date.year == year
  if shukujitu = date.shukujitu?
    print date,date.format("(ddd) "),shukujitu,"\n"
  end
  date = date.inc_day
end
--



[ この場所へのリンク ]


Ruby 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]  [ 不具合報告 メール送信 ]
  2005/4/15 追記
  2005/5/20 [昭和の日]改正の修正
  2007/5/28 祝日名が '元' になっていたのを '元' に修正
  2014/5/29 [山の日]改正の修正
  2018/2/15 [天皇誕生日の変更]改正の修正
  2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動(2020年)] 改正の修正
  2018/12/8 [即位の日 および 4/30 & 5/2の国民の休日] [即位礼正殿の儀] 改正の修正
  2020/11/28 [五輪特措法による祝日移動(2021年)] 改正の修正
  2021/6/13 2020/2021年の「山の日」判定が誤っていたのを修正(下記参照)


    VBAコードのロジックを、そのまま[Ruby ]用に書き直したものです。
    たけ(tk)」さんによる編集です。

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

    『祝日について

    「昭和の日」に伴う「振替休日(5月6日)」改正への修正方針もお読みください。
    「即位の日(2019/5/1)」に伴う「祝日に挟まれた平日(4/30 & 5/2)の休日化」への修正方針もお読みください。


  --- 修正内容の説明 --------------------------------------
  2021/6/13    : 「山の日」判定の組み立てが誤っており、2020年では [ 8/10 & 8/11 ]、2021年では [ 8/8 & 8/11 ] が
                         「山の日」 と判定されていました。
      ( 修正前の誤コード )
    when 8
      return '山の日' if ( year >= 2022 ) && ( day == 11 )
      return '山の日' if ( year == 2021 ) && ( day == 8 )
      return '山の日' if ( year == 2020 ) && ( day == 10 )
      return '山の日' if ( year >= 2016 ) && ( day == 11 )   この判定が 2020/2021年でも反応する為の誤判定

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


    ----------- Ruby における 曜日値について -----------
        曜日値を取得する関数が2つ ( cwday , wday ) あります。
        cwday の曜日の値は [ 月(1), 火(2), 水(3), 木(4), 金(5), 土(6), 日(7) ] です。
        wday の曜日の値は [ 日(0), 月(1), 火(2), 水(3), 木(4), 金(5), 土(6) ] です。
        どちらにもシステム定数は用意されていません。
        このプログラムでは [ 日, 月, … 土 ] 並びの wday を使っています。


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

 


#! ruby -Ks
#-- Shukujitu.rb
#-- Shukujitu.pi

# FROM http://addinbox.sakura.ne.jp/holiday_logic.htm

##_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
##_/
##_/  --- Ruby 移植版 ( Update: 2021/6/13 ) ---
##_/
##_/  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関数アドイン]で使用している
##_/  VBAマクロを[Ruby]に移植したものです。
##_/
##_/  この関数では以下の祝日変更までサポートしています。
##_/    (a) 2019年施行の「天皇誕生日の変更」 12/23⇒2/23 (補:2019年には[天皇誕生日]はありません)
##_/    (b) 2019年の徳仁親王の即位日(5/1) および
##_/       祝日に挟まれて「国民の休日」となる 4/30(平成天皇の退位日) & 5/2 の2休日
##_/    (c) 2019年の「即位の礼 正殿の儀 (10/22) 」
##_/    (d) 2020年施行の「体育の日の改名」⇒スポーツの日
##_/    (e) 五輪特措法による2020年の「祝日移動」
##_/       海の日:7/20(3rd Mon)⇒7/23, スポーツの日:10/12(2nd Mon)⇒7/24, 山の日:8/11⇒8/10
##_/    (f) 五輪特措法による2021年の「祝日移動」
##_/       海の日:7/19(3rd Mon)⇒7/22, スポーツの日:10/11(2nd Mon)⇒7/23, 山の日:8/11⇒8/8
##_/
##_/ (1) このコードを引用するに当たっては、必ずこのコメントも
##_/      一緒に引用する事とします。
##_/ (2) 他サイト上で本マクロを直接引用する事は、ご遠慮願います。
##_/      [ http://addinbox.sakura.ne.jp/holiday_logic.htm ]
##_/      へのリンクによる紹介で対応して下さい。
##_/ (3) [ktHolidayName]という関数名そのものは、各自の環境に
##_/      おける命名規則に沿って変更しても構いません。
##_/
##_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
##
##      VBA以外の言語に移植する場合は、その言語の特性に合わせたベストなコード構成に
##    変更しても構いません。
##
##    また、出来上がったものをご連絡頂ければ、このページにて紹介させて貰います。
##
## 2003-11-03(月) [ruby-list:38743]のご指摘で訂正2ヶ所。thanks Tadayoshi Funaba <tadf@rc5.so-net.ne.jp>
##                昭和の日法案成立用のスクリプトをコメントで不可。今回も不成立だったらしい。
## 2003-09-21(日):…とのことなので imported by take_tk
## 2003-09-21(日) [ap-ext:0128] Shukujitu.rb http://www.freeml.com/message/ap-ext@freeml.com/0000128
##
## 2005-04-14(木) Ruby 組込みクラスの Time クラスを使うもの。1970/1/1 以前はつかえない。
##
## 2014/5/29 [山の日]改正の修正
##
## 2018/2/15 [天皇誕生日の変更]改正の修正
##
## 2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動(2020年)] 改正の修正
##
## 2018/12/8 [即位の日 および 4/30 & 5/2の国民の休日] [即位礼正殿の儀] 改正の修正
##
## 2020/11/28 [五輪特措法による祝日移動(2021年)] 改正の修正
##
## 2021/6/13  2020/2021年の「山の日」判定が誤っていたのを修正
##
##
## ruby の特徴
## (1) 条件判断では文字列は真、nilは偽の扱いになる。
## (2) returnがない場合には、最後の文の値が戻り値となる。
## (3) 論理演算は短絡評価型。「||」で左がtrueなら右は判断しない、「&&」で左がfalseなら右は判断しない。
##


class Time
  def inc_day(n = 1)
    return self + (n * 24 * 60 * 60)
  end
end

module Shukujitu

  # wday メソッド : 日(0),月(1) ... 土(6)
  MONDAY = 1
  TUESDAY = 2
  WEDNESDAY = 3

  def self.shukujitu? date
    kihon_shukujitu?(date) || hurikae_kyujitu?(date)
    # OR条件式(短絡評価型)なので、
    # kihon_shukujitu で祝日名が得られる( 文字列 ⇒ 論理値:true ) ... hurikae_kyujitu は処理されない
    # kihon_shukujitu で祝日名が得られない( nil ⇒ 論理値:false ) ... 続けて hurikae_kyujitu が処理される
  end

  D_1973_4_12 = ::Time.local(1973,4,12)    # 振替休日 施行日

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

  def self.hurikae_kyujitu? date
    if ( date.wday == MONDAY ) && ( date >= D_1973_4_12 ) && ( kihon_shukujitu? date.inc_day(-1) )
      # AND条件式(短絡評価型)なので、月曜日以外では kihon_shukujitu は処理されない
      # [ 対象日≠祝日/休日 ] の判定は上記の self.shukujitu で行われている
      # kihon_shukujitu で祝日名が得られる( 文字列 ⇒ 論理値:true )
      # kihon_shukujitu で祝日名が得られない( nil ⇒ 論理値:false )
      return '振替休日'
    end
  end

  begin
    D_1948_7_20 = ::Time.local(1948,7,20)    # 祝日法 施行日
  rescue
    D_1948_7_20 = ::Time.at(0)  # Thu Jan 01 09:00:00 東京 (標準時) 1970
  end

  def self.kihon_shukujitu? date
    return if ( date < D_1948_7_20 )  # 祝日法施行前( nil で返す )

    year  = date.year
    month = date.month     # 月(1〜12)
    day  = date.day
    yobi  = date.wday   # wday メソッド : 日(0),月(1) ... 土(6)
    shuu  = ( day - 1 ) / 7 + 1   # for 2nd Monday/3rd Monday

    case month
    #-- 1月 --
    when 1
      return '元日' if ( day == 1 )
      if ( year >= 2000 )
        return '成人の日' if ( yobi == MONDAY ) && ( shuu == 2 )  # 2nd Monday Monday
      else
        return '成人の日' if ( day == 15 )
      end

    #-- 2月 --
    when 2
      case day
        when 11 ; return '建国記念の日'  if ( year >= 1967 )
        when 23 ; return '天皇誕生日'  if ( year >= 2020 )
        when 24 ; return '昭和天皇の大喪の礼'  if ( year == 1989 )
      end

    #-- 3月 --
    when 3
      return '春分の日'  if ( day == shunbun_day(year) )

    #-- 4月 --
    when 4
      case day
        when 29
          case year
            when 2007..9999 ; return '昭和の日'
            when 1989..2006 ; return 'みどりの日'
            else ; return '天皇誕生日# 昭和天皇
          end
        when 30 ; return '国民の休日' if ( year == 2019 )  # 祝日に挟まれた国民の休日です(平成天皇の退位日)
        when 10 ; return '皇太子明仁親王の結婚の儀' if ( year == 1959 )
      end

    #-- 5月 --
    when 5
      case day
        when 3 ; return '憲法記念日'
        when 4
          case year
            when 2007..9999 ; return 'みどりの日'
            when 1986..2006 ; return '国民の休日' if ( yobi > MONDAY )    # 火曜 以降(火〜土)
                    # 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年)
          end
        when 5 ; return 'こどもの日'
        when 6 ; return '振替休日' if ( year >= 2007 ) and ( [TUESDAY,WEDNESDAY].include? yobi )
                  # '[5/3,5/4が日曜]ケースのみ、ここで判定

        # 5/1 & 5/2 は2019年のみの臨時祝日なので最後に判定する
        when 1 ; return '即位の日' if ( year == 2019 )  # 徳仁親王
        when 2 ; return '国民の休日' if ( year == 2019 )  # 祝日に挟まれた国民の休日です
      end

    #-- 6月 --
    when 6
      return '皇太子徳仁親王の結婚の儀' if ( day == 9 ) && ( year == 1993 )

    #-- 7月 --
    when 7
      if ( year >= 2022 )
        return '海の日'  if ( shuu == 3 ) && ( yobi == MONDAY )   # 3rd Monday
      elsif (year == 2021)
         # 2021年はオリンピック特措法により
         #「海の日」が 7/22 , 「スポーツの日」が 7/23 に移動
        return '海の日'  if ( day == 22 )
        return 'スポーツの日'  if ( day == 23 )
      elsif (year == 2020)
         # 2020年はオリンピック特措法により
         #「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
        return '海の日'  if ( day == 23 )
        return 'スポーツの日'  if ( day == 24 )
      elsif ( year >= 2003 )
        return '海の日'  if ( shuu == 3 ) && ( yobi == MONDAY )   # 3rd Monday
      elsif ( year >= 1996 )
        return '海の日'  if ( day == 20 )
      end

    #-- 8月 --
    when 8
      # 2021年はオリンピック特措法により「山の日」が 8/8 に移動
      # 2020年はオリンピック特措法により「山の日」が 8/10 に移動
      if ( year >= 2022 )
          return '山の日' if ( day == 11 )
      elsif ( year == 2021 )
          return '山の日' if ( day == 8 )
      elsif ( year == 2020 )
          return '山の日' if ( day == 10 )
      elsif ( year >= 2016 )
          return '山の日' if ( day == 11 )
      end

    #-- 9月 --
    when 9
      shuubun_day = shuubun_day(year)
      return '秋分の日'  if ( shuubun_day == day )
      if ( year >= 2003 )
        return '敬老の日'  if ( yobi == MONDAY ) && ( shuu == 3 )  # 3rd Monday
        return '国民の休日'  if ( yobi == TUESDAY ) && ( day == shuubun_day - 1 )  # 火曜日&[秋分日の前日]
      elsif ( year >= 1966 )
        return '敬老の日'  if ( day == 15 )
      end

    #-- 10月 --
    when 10
      if ( year >= 2022 )
        return 'スポーツの日'  if ( yobi == MONDAY ) && ( shuu == 2 )   # 2nd Monday , 2020年より改名
      elsif ( year == 2020 ) || ( year == 2021 )
        # 2021年はオリンピック特措法により「スポーツの日」が 7/23 に移動
        # 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
        return nil
      elsif ( year >= 2000 )
        return '体育の日'  if ( yobi == MONDAY ) && ( shuu == 2 )   # 2nd Monday
        return '即位礼正殿の儀' if ( year == 2019 ) && ( day == 22 )   # 徳仁親王
      elsif ( year >= 1966 )
        return '体育の日'  if ( day == 10 )
      end

    #-- 11月 --
    when 11
      case day
        when  3 ; return '文化の日'
        when 23 ; return '勤労感謝の日'
        when 12 ; return '即位礼正殿の儀'  if ( year == 1990 )  # 平成天皇
      end

    #-- 12月 --
    when 12
      return '天皇誕生日'  if ( day == 23 ) && ( year >= 1989 ) && ( year <= 2018 )  # 平成天皇
    end

    return nil    # 祝日ではない場合 nil で返す
  end

  # 春分/秋分日の略算式は
  #    『海上保安庁水路部 暦計算研究会編 新こよみ便利帳』
  # で紹介されている式です。
  # ruby の (-5/4) は -2 を返すので 1980 を使用する。
  # http://addinbox.sakura.ne.jp/holiday_topic.htm#Note
  #


  #--- 春分日の略算式 ---
  def self.shunbun_day(year) # return day
    y1980 = year - 1980
    case year
      when 1948..1979 ; return (20.8357 + (0.242194 * y1980) - (y1980 / 4)).to_i;
      when 1980..2099 ; return (20.8431 + (0.242194 * y1980) - (y1980 / 4)).to_i;
      when 2100..2150 ; return (21.8510 + (0.242194 * y1980) - (y1980 / 4)).to_i;
    end
    return 99 # 祝日法施行前および2151年以降は略算式が無いので不明
  end

  #--- 秋分日の略算式 ---
  def self.shuubun_day(year) # return day
    y1980 = year - 1980
    case year
      when 1948..1979 ; return (23.2588 + (0.242194 * y1980) - (y1980 / 4)).to_i;
      when 1980..2099 ; return (23.2488 + (0.242194 * y1980) - (y1980 / 4)).to_i;
      when 2100..2150 ; return (24.2488 + (0.242194 * y1980) - (y1980 / 4)).to_i;
    end
    return 99 # 祝日法施行前および2151年以降は略算式が無いので不明
  end

end # of module

class Time
  def shukujitu?
    Shukujitu.shukujitu?(self)
  end
end





[ この場所へのリンク ]


JAVA 用祝日判定コード 】    [ 検証用データ ( 祝日一覧 ) は JavaScript 版による ツール で取得できます ]  [ 不具合報告 メール送信 ]
  2003/12/21 追記
  2004/3/17 一部修正( 下記参照 )
  2005/5/20 [昭和の日]改正の修正
  2009/4/30 [5月6日]の if ブロックで括弧不足を修正
  2014/5/29 [山の日]改正の修正
  2018/2/15 [天皇誕生日の変更]改正の修正
  2018/6/21 [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動(2020年)] 改正の修正
  2018/12/8 [即位の日 および 4/30 & 5/2の国民の休日] [即位礼正殿の儀] 改正の修正
  2020/11/28 [五輪特措法による祝日移動(2021年)] 改正の修正


      VBAコードのロジックを、そのまま[JAVA(J2SE1.4) ]用に書き直したものです。
    阿蛭 栄一」さんによる編集です。

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

    『祝日について

    「昭和の日」に伴う「振替休日(5月6日)」改正への修正方針もお読みください。
    「即位の日(2019/5/1)」に伴う「祝日に挟まれた平日(4/30 & 5/2)の休日化」への修正方針もお読みください。

  --- 修正内容の説明 --------------------------------------
  2004/3/17
        String比較 を [ = ] [ != ] で行なっていたのを [ equals メソッド ] に変更しました。
        [ = ] [ != ] では不都合な理由は、「Javaの道 / 比較演算子」の中程の解説を参照して下さい。

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


    ----------- JAVA における 曜日値について -----------
        曜日の値は [ 日(1), 月(2), 火(3), 水(4), 木(5), 金(6), 土(7) ] です。
        システム定数の [ Calendar.SUNDAY, Calendar.MONDAY, … Calendar.SATURDAY ] が利用できます。


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

 


/*
  この Java(J2SE1.4) 用祝日判定コードは、下記ウェブサイトで
  公開されているのVBA用のコードを元に、主にJavascript版と
  C言語版を参考にして
  阿蛭 栄一( http://www.age.ne.jp/x/abiru/index.html )が
  編集移植しました。
  << 改編履歴 >>
    Mar. 16 2004
        Stringの比較で = や != を使用していたのを、equalsメソッドに変更

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

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

    Jun. 21 2018
        [体育の日⇒スポーツの日 改名] & [五輪特措法による祝日移動(2020年)] 改正の修正

    Dec. 8 2018
        [即位の日 および 4/30 & 5/2の国民の休日] [即位礼正殿の儀] 改正の修正

    Nov. 28 2020
        [五輪特措法による祝日移動(2021年)] 改正の修正
*/

/*
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/
_/  --- JAVA 移植版 ( Update: 2020/11/28 ) ---
_/
_/  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関数アドイン』で使用しているものです。
_/  このロジックは、レスポンスを第一義として、可能な限り少ない
_/  【条件判定の実行】で結果を出せるように設計してあります。
_/
_/  この関数では以下の祝日変更までサポートしています。
_/    (a) 2019年施行の「天皇誕生日の変更」 12/23⇒2/23 (補:2019年には[天皇誕生日]はありません)
_/    (b) 2019年の徳仁親王の即位日(5/1) および
_/       祝日に挟まれて「国民の休日」となる 4/30(平成天皇の退位日) & 5/2 の2休日
_/    (c) 2019年の「即位の礼 正殿の儀 (10/22) 」
_/    (d) 2020年施行の「体育の日の改名」⇒スポーツの日
_/    (e) 五輪特措法による2020年の「祝日移動」
_/       海の日:7/20(3rd Mon)⇒7/23, スポーツの日:10/12(2nd Mon)⇒7/24, 山の日:8/11⇒8/10
_/    (f) 五輪特措法による2021年の「祝日移動」
_/       海の日:7/19(3rd Mon)⇒7/22, スポーツの日:10/11(2nd Mon)⇒7/23, 山の日:8/11⇒8/8
_/
_/  (*1)このマクロを引用するに当たっては、必ずこのコメントも
_/      一緒に引用する事とします。
_/  (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
_/      【 http://addinbox.sakura.ne.jp/holiday_logic.htm 】
_/      へのリンクによる紹介で対応して下さい。
_/  (*3)[ktHolidayName]という関数名そのものは、各自の環境に
_/      おける命名規則に沿って変更しても構いません。
_/ 
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
*/


import java.util.Calendar;
import java.util.GregorianCalendar;
import java.text.SimpleDateFormat;
import java.text.ParseException;

public class KtHoliday{

    private KtHoliday(){
    }

    private static final  Calendar cstImplementTheLawOfHoliday
        = new GregorianCalendar( 1948, Calendar.JULY, 20 );      // 祝日法施行
    private static final  Calendar cstImplementHolidayInLieu
        = new GregorianCalendar( 1973, Calendar.APRIL, 12 );    // 振替休日施行
    private static final  Calendar cstAkihitoKekkon
        = new GregorianCalendar( 1959, Calendar.APRIL, 10 );    // 明仁親王の結婚の儀
    private static final  Calendar cstShowaTaiso
        = new GregorianCalendar( 1989, Calendar.FEBRUARY, 24 );  // 昭和天皇大喪の礼
    private static final  Calendar cstNaruhitoKekkon
        = new GregorianCalendar( 1993, Calendar.JUNE, 9 );      // 徳仁親王の結婚の儀
    private static final  Calendar cstSokuireiSeiden
        = new GregorianCalendar( 1990, Calendar.NOVEMBER, 12 );  // 即位礼正殿の儀(平成天皇)

    private static final  Calendar cstTaii_Heisei
        = new GregorianCalendar( 2019, Calendar.APRIL, 30 );  // 祝日ではなく「国民の休日」です(平成天皇の退位日)
    private static final  Calendar cstSokui_Naruhito
        = new GregorianCalendar( 2019, Calendar.MAY, 1);  // 即位の日(徳仁親王)
    private static final  Calendar cst2019GW_May2nd
        = new GregorianCalendar( 2019, Calendar.MAY, 2 );  // 祝日ではなく「国民の休日」です
    private static final  Calendar cstSokuireiSeiden_Naruhito
        = new GregorianCalendar( 2019, Calendar.OCTOBER, 22 );  // 即位礼正殿の儀(徳仁親王)


    // [prmDate]には "yyyy/m/d"形式の日付文字列を渡す
    public static String getHolidayName( String prmDate ) throws ParseException
    {
        String HolidayName_ret = "";
        SimpleDateFormat formatter = new SimpleDateFormat ( "yyyy/MM/dd" );
        Calendar MyDate = Calendar.getInstance();
        MyDate.setTime( formatter.parse( prmDate ) );

        String HolidayName = prvHolidayChk( MyDate );

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

        if ( HolidayName.equals("") ) {
            if ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) {
                if ( MyDate.after( cstImplementHolidayInLieu ) || MyDate.equals( cstImplementHolidayInLieu ) ) {
                    Calendar YesterDay = (Calendar )MyDate.clone();
                    YesterDay.add( Calendar.DATE, -1 );
                    HolidayName = prvHolidayChk( YesterDay );
                    HolidayName_ret = "";
                    if ( !HolidayName.equals("") ) {
                        HolidayName_ret = "振替休日";
                    } else {
                        HolidayName_ret = "";
                    }
                } else {
                    HolidayName_ret = "";
                }
            } else {
                HolidayName_ret = "";
            }
        } else {
            HolidayName_ret = HolidayName;
        }
        return HolidayName_ret;
    }

    //===============================================================

    private static String prvHolidayChk( Calendar MyDate )
    {
        int NumberOfWeek;
        String Result;
        int MyYear = MyDate.get( Calendar.YEAR );
        int MyMonth = MyDate.get( Calendar.MONTH ) + 1;    // MyMonth:1〜12
        int MyDay = MyDate.get( Calendar.DATE );
        // Calendar.DAY_OF_WEEK : 日(1),月(2) ... 土(7)

        if ( MyDate.before( cstImplementTheLawOfHoliday ) ) {
            return "";  // 祝日法施行(1948/7/20 )以前
        } else;

        Result = "";
        switch ( MyMonth ) {

        // 1月 //
        case 1:
            if ( MyDay == 1 ) {
                Result = "元日";
            } else {
                if ( MyYear >= 2000 ) {
                    NumberOfWeek = ( (MyDay - 1 ) / 7 ) + 1;
                    if ( ( NumberOfWeek == 2 ) && ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) ) {
                        Result = "成人の日";  // 2nd Monday
                    } else;
                } else {
                    if ( MyDay == 15 ) {
                        Result = "成人の日";
                    } else;
                }
            }
            break;

        // 2月 //
        case 2:
            if ( MyDay == 11 ) {
                if ( MyYear >= 1967 ) {
                    Result = "建国記念の日";
                } else;
            } else if ( MyDay == 23 ) {
                if ( MyYear >= 2020 ) {
                    Result = "天皇誕生日";
                } else;
            } else if ( MyDate.equals( cstShowaTaiso ) ) {
                Result = "昭和天皇の大喪の礼";  // ( =1989/2/24 )
            } else;
            break;

        // 3月 //
        case 3:
            if ( MyDay == prvDayOfSpringEquinox( MyYear ) ) {    // 1948〜2150以外は[99]
                Result = "春分の日";                             // が返るので、必ず≠になる
            } else;
            break;

        // 4月 //
        case 4:
            if ( MyDay == 29 ) {
                if (MyYear >= 2007) {
                    Result = "昭和の日";
                } else if ( MyYear >= 1989 ) {
                    Result = "みどりの日";
                } else {
                    Result = "天皇誕生日";  // 昭和天皇
                }
            } else if ( MyDate.equals( cstTaii_Heisei ) ) {
                Result = "国民の休日";  // ( =2019/4/30 , 平成天皇の退位日 )
            } else if ( MyDate.equals( cstAkihitoKekkon ) ) {
                Result = "皇太子明仁親王の結婚の儀";  // ( =1959/4/10 )
            } else;
            break;

        // 5月 //
        case 5:
            switch ( MyDay ) {
              case 3// 5月3日
                  Result = "憲法記念日";
                  break;
              case 4// 5月4日
                  if (MyYear >= 2007) {
                      Result = "みどりの日";
                  } else if (MyYear >= 1986) {
                      if (MyDate.get( Calendar.DAY_OF_WEEK ) > Calendar.MONDAY) {    // 火曜 以降(火〜土)
                          // 5/4が日曜日は『只の日曜』、月曜日は『憲法記念日の振替休日』(〜2006年)
                          Result = "国民の休日";
                      } else;
                  } else;
                  break;
              case 5// 5月5日
                  Result = "こどもの日";
                  break;
              case 6// 5月6日
                  if (MyYear >= 2007) {
                      if ( (MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.TUESDAY)
                          || (MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.WEDNESDAY) ) {
                          Result = "振替休日";    // [5/3,5/4が日曜]ケースのみ、ここで判定
                      } else;
                  } else;
                  break;
              default:
                  if (MyYear == 2019) {
                      if (MyDate.equals( cstSokui_Naruhito )) {    // ( =2019/5/1 )
                          Result = "即位の日";    // 徳仁親王
                      } else if (MyDate.equals( cst2019GW_May2nd )) {    // ( =2019/5/2 )
                          Result = "国民の休日";    // 祝日に挟まれた国民の休日です
                      } else;
                  } else;
            }
            break;

        // 6月 //
        case 6:
            if ( MyDate.equals( cstNaruhitoKekkon ) ) {
                Result = "皇太子徳仁親王の結婚の儀";  // ( =1993/6/9 )
            } else;
            break;

        // 7月 //
        case 7:
            NumberOfWeek = ( (MyDay - 1 ) / 7 ) + 1;
            if ( MyYear >= 2022 ) {
                if ( ( NumberOfWeek == 3 ) && ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) ) {
                    Result = "海の日";    // 3rd Monday
                } else;
            } else if ( MyYear == 2021 ) {
                // 2021年はオリンピック特措法により
                //「海の日」が 7/22 , 「スポーツの日」が 7/23 に移動
                if ( MyDay == 22 ) {
                    Result = "海の日";
                } else if ( MyDay == 23 ) {
                    Result = "スポーツの日";
                } else;
            } else if ( MyYear == 2020 ) {
                // 2020年はオリンピック特措法により
                //「海の日」が 7/23 , 「スポーツの日」が 7/24 に移動
                if ( MyDay == 23 ) {
                    Result = "海の日";
                } else if ( MyDay == 24 ) {
                    Result = "スポーツの日";
                } else;
            } else if ( MyYear >= 2003 ) {
                if ( ( NumberOfWeek == 3 ) && ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) ) {
                    Result = "海の日";    // 3rd Monday
                } else;
            } else if ( MyYear >= 1996 ) {
                if ( MyDay == 20 ) {
                    Result = "海の日";
                } else;
            } else;
            break;

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

        // 9月 //
        case 9:
            //第3月曜日( 15〜21 )と秋分日(22〜24 )が重なる事はない
            int MyAutumnEquinox = prvDayOfAutumnEquinox( MyYear );
            if ( MyDay == MyAutumnEquinox ) {        // 1948〜2150以外は[99]
                Result = "秋分の日";                 // が返るので、必ず≠になる
            } else {
                if ( MyYear >= 2003 ) {
                    NumberOfWeek = ( (MyDay - 1 ) / 7 ) + 1;
                    if ( (NumberOfWeek == 3 ) && ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) ) {
                        Result = "敬老の日";  // 3rd Monday
                    } else {
                        if ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.TUESDAY ) {
                            if ( MyDay == ( MyAutumnEquinox - 1 ) ) {
                                Result = "国民の休日";  // 火曜日&[秋分日の前日]
                            } else;
                        } else;
                    }
                } else {
                    if ( MyYear >= 1966 ) {
                        if ( MyDay == 15 ) {
                            Result = "敬老の日";
                        } else;
                    } else;
                }
            }
            break;

        // 10月 //
        case 10:
            NumberOfWeek = ( ( MyDay - 1 ) / 7 ) + 1;
            if ( MyYear >= 2022 ) {
                if ( (NumberOfWeek == 2 ) && ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) ) {
                    Result = "スポーツの日";    // 2nd Monday , 2020年より改名
                } else;
            } else if ( ( MyYear == 2020 ) || ( MyYear == 2021 ) ) {
                // 2021年はオリンピック特措法により「スポーツの日」が 7/23 に移動
                // 2020年はオリンピック特措法により「スポーツの日」が 7/24 に移動
            } else if ( MyYear >= 2000 ) {
                if ( (NumberOfWeek == 2 ) && ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) ) {
                    Result = "体育の日";    // 2nd Monday
                } else if ( MyDate.equals( cstSokuireiSeiden_Naruhito ) ) {
                    Result = "即位礼正殿の儀";  // ( =2019/10/22 , 徳仁親王 )
                } else;
            } else if ( MyYear >= 1966 ) {
                if ( MyDay == 10 ) {
                    Result = "体育の日";
                } else;
            } else;
            break;

        // 11月 //
        case 11:
            if ( MyDay == 3 ) {
                Result = "文化の日";
            } else if ( MyDay == 23 ) {
                Result = "勤労感謝の日";
            } else if ( MyDate.equals( cstSokuireiSeiden ) ) {
                Result = "即位礼正殿の儀";  // ( =1990/11/12 , 平成天皇 )
            } else;
            break;

        // 12月 //
        case 12:
            if ( MyDay == 23 ) {
                if ( ( MyYear >= 1989 ) && ( MyYear <= 2018 ) ) {
                    Result = "天皇誕生日";  // 平成天皇
                } else;
            } else;
            break;
        }
        return Result;
    }

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

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

    //=====================================================================
    private static int prvDayOfAutumnEquinox( int MyYear )
    {
        int AutumnEquinox_ret;
        if ( MyYear <= 1947 ) {
            AutumnEquinox_ret = 99;  //祝日法施行前
        } else if ( MyYear <= 1979 ) {
            AutumnEquinox_ret = (int)( 23.2588 +
                ( 0.242194 * ( MyYear - 1980 ) ) - (int)( (MyYear - 1983 ) / 4 ) );
        } else if ( MyYear <= 2099 ) {
            AutumnEquinox_ret = (int)( 23.2488 +
                ( 0.242194 * ( MyYear - 1980 ) ) - (int)( (MyYear - 1980 ) / 4 ) );
        } else if ( MyYear <= 2150 ) {
            AutumnEquinox_ret = (int)( 24.2488 +
                ( 0.242194 * ( MyYear - 1980 ) ) - (int)( (MyYear - 1980 ) / 4 ) );
        } else {
            AutumnEquinox_ret = 99;    //2151年以降は略算式が無いので不明
        }
        return AutumnEquinox_ret;
    }


    /*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
    _/
    _/ ここから先は、阿蛭栄一が独自に追加したコーディングです。
    _/ Thu, 18 Dec 2003 02:25:27 +0900
    _/ abiru@home.104.net
    _/
    _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ */

    //=====================================================================

    /*このメソッドは、引数にjava.util.Calendarを取るgetHolidayNameメソッドです。
        単にCalendarオブジェクトから"yyyy/MM/dd"形式の文字列を組み立てて
        getHolidayName( String prmDate )の方のメソッドを呼び出しているだけですが、
        他のアプリケーションからこのクラスを使う時のことを考慮するとString
        ではなく、Calendarを引数に取るメソッドがあった方が便利ですよね?*/

    public static String getHolidayName( Calendar prmDate ) throws ParseException
    {
        SimpleDateFormat f = new SimpleDateFormat ( "yyyy/MM/dd" );
        return getHolidayName( f.format( prmDate.getTime() ) );
    }

    //=====================================================================

    /*このメソッドは動作確認やデバッグ用に用意したメソッドです。
        通常は利用しませんので不要な場合には削除して頂いて結構です。
        使い方は以下の通りです。
        java KtHoliday 1948/01/01 2050/12/30
    */

    public static void main( String args[] ) throws Exception
    {
        SimpleDateFormat f = new SimpleDateFormat ( "yyyy/MM/dd" );
        Calendar current = new GregorianCalendar();
        current.setTime( f.parse( args[0] ) );
        Calendar end = new GregorianCalendar();
        end.setTime( f.parse( args[1] ) );

        String result = "";
        while( current.before( end ) || current.equals( end ) ){
            result = getHolidayName( current );
            if( !result.equals( "" ) ){
                System.out.print( f.format( current.getTime() ) );
                System.out.println( ",\"" + result + "\"" );
            }
            current.add( Calendar.DATE , 1 );
        }
    }
}







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