【 2016年9月15日  サイト 移転のお知らせ 】
      AddinBox サイトを [ DION ] から [ さくら インターネット ] へ移転しました。  なお、旧サイト は 2017年10月 まで残します。
      この ページ の 移転先 URL  ⇒⇒  http://addinbox.sakura.ne.jp/holiday_logic4.htm  
 

AddinBox(Title_Logo)

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

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

      VBA用コードは純粋にVB構文だけ(エクセル独自の機能は使ってません)で作って
    ありますので、エクセルだけでなくアクセスや、その他のVBAを使うアプリケーション
    でも利用できます。
  ※ 重要 ※
    ・ [ 生前退位/皇位継承 ] が 現実味を帯びてきました。 (H28/10/16)
      来年(平成29年)11月〜再来年(平成30年)3月の可能性が大です。
      -- 新サイトに掲載 --

    ・ [ 山の日:8月11日 ] の祝日法改正案が成立しました。 (H26/5/23)
       2016年(平成28年) から施行です。

 
  ※ 訂正案内 2016/3/5 ※
    応用例の Bank_Networkdays 関数に誤りがありました。
    If 文の True/False を取り違えていたため、営業日数 ではなく
    [休業]日数 を算出する ロジック となっていました。




※VBA以外に移植したコードも紹介しています※
 ・ 下記の全ての コード は 「山の日」 祝日改正への対応済みです。(2014/5/29)
 ・ 「昭和の日」 に伴う 「振替休日(5/6)」 改正への 修正方針 もお読みください。 ( 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
Go 言語 杉田 臣輔 さん 2015/ 1/ 6
       
      自由に各自のプログラムに組み込んで利用して下さい。なお、フリー/シェアソフト
    開発での利用も可(フリー/シェアでの利用の場合、事後で結構ですので一言
    お知らせください)です。ただし、引用に当たっては、マクロの先頭に記述してある
        コメント(CopyRight )を必ず一緒に引用する事

    を条件とします。

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

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

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

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

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



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

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

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

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

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




[ この場所へのリンク ]  [ サイト移転のお知らせ ]


Apollo 用祝日判定コード 】 2003/9/24 追記 , 2005/5/20 [昭和の日]改正の修正
                                            2007/5/28 祝日名が '元' になっていたのを '元' に修正
                                            2014/5/29 [山の日]改正の修正

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

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

    『祝日について

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

    --- 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 ]



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

# FROM http://www.h3.dion.ne.jp/~sakatsu/holiday_logic.htm

##_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
##_/
##_/  CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
##_/  ( http://www.h3.dion.ne.jp/~sakatsu/index.htm )
##_/
##_/  この祝日判定コードは[Excel:kt関数アドイン]で使用している
##_/  VBAマクロを[Apollo]に移植したものです。
##_/  この関数では、2016年施行の改正祝日法(山の日)までを
##_/  サポートしています。
##_/
##_/ (1) このコードを引用するに当たっては、必ずこのコメントも
##_/   一緒に引用する事とします。
##_/ (2) 他サイト上で本マクロを直接引用する事は、ご遠慮願います。
##_/   [ http://www.h3.dion.ne.jp/~sakatsu/holiday_logic.htm ]
##_/   へのリンクによる紹介で対応して下さい。
##_/ (3) [ktHolidayName]という関数名そのものは、各自の環境に
##_/   おける命名規則に沿って変更しても構いません。
##_/
##_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
##
## VBA以外の言語に移植する場合は、その言語の特性に合わせたベストな
## コード構成に変更しても構いません。
##
## また、出来上がったものをご連絡頂ければ、このページにて紹介させて貰います。
##
## 2003-09-21(日):…とのことなので imported by take_tk 
##
## 2014/5/29 [山の日]改正の修正
##

require "phi"

module Shukujitu

  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)
  end

  D_1973_4_12 = Phi::DateTime.new("1973/4/12")
  def self.hurikae_kyujitu? date
    # 月曜以外は振替休日判定不要
    # 5/6(火,水)の判定は[ kihon_shukujitu ]で処理済
    # 5/6(月)はここで判定する
    if ( date.wday == MONDAY ) && ( date >= D_1973_4_12 ) && ( kihon_shukujitu? date.inc_day(-1) )
      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  # 祝日法施行前
    year  = date.year
    month = date.month
    day   = date.day
    yobi  = date.wday
    shuu  = ( day - 1 ) / 7 + 1
    case month
    when 1
      return '元日' if day == 1
      if year >= 2000
        return '成人の日' if ( yobi == MONDAY ) && ( shuu == 2 )
      else
        return '成人の日' if ( day == 15 )
      end

    when 2
      case day
      when 11 ; return '建国記念の日'       if year >= 1967
      when 24 ; return '昭和天皇の大喪の礼' if year == 1989
      end

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

    when 4
      case day
      when 29
        case year
        when 2007..9999 ; return '昭和の日'
        when 1989..2006 ; return 'みどりの日'
        else                  ; return '天皇誕生日'
        end
      when 10 ; return '皇太子明仁親王の結婚の儀' if year == 1959
      end

    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が日曜]ケースのみ、ここで判定
      end

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

    when 7
      if year >= 2003
        return '海の日' if ( shuu == 3) && (yobi == MONDAY)
      elsif year >= 1996
        return '海の日' if day == 20
      end

    when 8
      return '山の日' if (day == 11) && (year >= 2016)

    when 9
      shuubun_day = shuubun_day(year)
      return '秋分の日'     if (shuubun_day == day)
      if year >= 2003
        return '敬老の日'   if (yobi == MONDAY) && (shuu == 3)
        return '国民の休日' if (yobi == TUESDAY) && (day == shuubun_day - 1)
      elsif year >= 1966
        return '敬老の日'   if (day == 15)
      end

    when 10
      if ( year >= 2000)
        return '体育の日' if (yobi == MONDAY) && (shuu == 2)
      elsif (year >= 1966)
        return '体育の日' if (day == 10)
      end

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

    when 12
      return '天皇誕生日' if (day == 23) && (year >= 1989)

    end
    return nil
  end
  
  # 春分/秋分日の略算式は
  #    『海上保安庁水路部 暦計算研究会編 新こよみ便利帳』
  # で紹介されている式です。
  # ruby の (-5/4) は -2 を返すので 1980 を使用する。
  # http://www.h3.dion.ne.jp/~sakatsu/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
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 用祝日判定コード 】  2005/4/15 追記 , 2005/5/20 [昭和の日]改正の修正
                                            2007/5/28 祝日名が '元' になっていたのを '元' に修正
                                            2014/5/29 [山の日]改正の修正

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

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

    『祝日について

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



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

# FROM http://www.h3.dion.ne.jp/~sakatsu/holiday_logic.htm

##_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
##_/
##_/  CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
##_/  ( http://www.h3.dion.ne.jp/~sakatsu/index.htm )
##_/
##_/  この祝日判定コードは[Excel:kt関数アドイン]で使用している
##_/  VBAマクロを[Ruby]に移植したものです。
##_/  この関数では、2016年施行の改正祝日法(山の日)までを
##_/  サポートしています。
##_/
##_/ (1) このコードを引用するに当たっては、必ずこのコメントも
##_/   一緒に引用する事とします。
##_/ (2) 他サイト上で本マクロを直接引用する事は、ご遠慮願います。
##_/   [ http://www.h3.dion.ne.jp/~sakatsu/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 [山の日]改正の修正
##
## 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

  MONDAY = 1
  TUESDAY = 2
  WEDNESDAY = 3

  def self.shukujitu? date
    kihon_shukujitu?(date) || hurikae_kyujitu?(date)
  end

  D_1973_4_12 = ::Time.local(1973,4,12)
  def self.hurikae_kyujitu? date
    # 月曜以外は振替休日判定不要
    # 5/6(火,水)の判定は[kihon_shukujitu?]で処理済
    # 5/6(月)はここで判定する
    if ( date.wday == MONDAY ) && ( date >= D_1973_4_12 ) && ( kihon_shukujitu? date.inc_day(-1) )
      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  # 祝日法施行前
    year  = date.year
    month = date.month
    day   = date.day
    yobi  = date.wday
    shuu  = ( day - 1 ) / 7 + 1
    case month
    when 1
      return '元日' if day == 1
      if year >= 2000
        return '成人の日' if ( yobi == MONDAY ) && ( shuu == 2 )
      else
        return '成人の日' if ( day == 15 )
      end

    when 2
      case day
      when 11 ; return '建国記念の日'       if year >= 1967
      when 24 ; return '昭和天皇の大喪の礼' if year == 1989
      end

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

    when 4
      case day
      when 29
        case year
        when 2007..9999 ; return '昭和の日'
        when 1989..2006 ; return 'みどりの日'
        else            ; return '天皇誕生日'
        end
      when 10 ; return '皇太子明仁親王の結婚の儀' if year == 1959
      end

    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が日曜]ケースのみ、ここで判定
      end

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

    when 7
      if year >= 2003
        return '海の日' if ( shuu == 3) && (yobi == MONDAY)
      elsif year >= 1996
        return '海の日' if day == 20
      end

    when 8
      return '山の日' if (day == 11) && (year >= 2016)

    when 9
      shuubun_day = shuubun_day(year)
      return '秋分の日'     if (shuubun_day == day)
      if year >= 2003
        return '敬老の日'   if (yobi == MONDAY) && (shuu == 3)
        return '国民の休日' if (yobi == TUESDAY) && (day == shuubun_day - 1)
      elsif year >= 1966
        return '敬老の日'   if (day == 15)
      end

    when 10
      if ( year >= 2000)
        return '体育の日' if (yobi == MONDAY) && (shuu == 2)
      elsif (year >= 1966)
        return '体育の日' if (day == 10)
      end

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

    when 12
      return '天皇誕生日' if (day == 23) && (year >= 1989)
    end
    return nil
  end

  # ruby の (-5/4) は -2 を返すので 1980 を使用する。
  # http://www.h3.dion.ne.jp/~sakatsu/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 用祝日判定コード 】  2003/12/21 追記 , 2004/3/17 修正 , 2005/5/20 [昭和の日]改正の修正
                                                    2009/4/30 [5月6日]の if ブロックで括弧不足を修正
                                                    2014/5/29 [山の日]改正の修正


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

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

    『祝日について

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

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


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

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

/*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/
_/ CopyRight(C) K.Tsunoda(AddinBox) 2001 All Rights Reserved.
_/ ( http://www.h3.dion.ne.jp/~sakatsu/index.htm )
_/
_/  この祝日マクロは『kt関数アドイン』で使用しているものです。
_/  このロジックは、レスポンスを第一義として、可能な限り少ない
_/   【条件判定の実行】で結果を出せるように設計してあります。
_/  この関数では、2016年施行の改正祝日法(山の日)までを
_/   サポートしています。
_/
_/ (*1)このマクロを引用するに当たっては、必ずこのコメントも
_/   一緒に引用する事とします。
_/ (*2)他サイト上で本マクロを直接引用する事は、ご遠慮願います。
_/   【 http://www.h3.dion.ne.jp/~sakatsu/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 cstAkihitoKekkon
        = new GregorianCalendar( 1959, Calendar.APRIL, 10 );     // 明仁親王の結婚の儀
    private static final  Calendar cstShowaTaiso
        = new GregorianCalendar( 1989, Calendar.FEBRUARY, 24 );  // 昭和天皇大喪の礼
    private static final  Calendar cstNorihitoKekkon
        = new GregorianCalendar( 1993, Calendar.JUNE, 9 );       // 徳仁親王の結婚の儀
    private static final  Calendar cstSokuireiseiden
        = new GregorianCalendar( 1990, Calendar.NOVEMBER, 12 );  // 即位礼正殿の儀
    private static final  Calendar cstImplementHoliday
        = new GregorianCalendar( 1973, Calendar.APRIL, 12 );     // 振替休日施行

    // [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 );
        if ( HolidayName.equals("") ) {
            if ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) {
                // 月曜以外は振替休日判定不要
                // 5/6(火,水)の判定は[ prvHolidayChk ]で処理済
                // 5/6(月)はここで判定する
                if ( MyDate.after( cstImplementHoliday ) || MyDate.equals( cstImplementHoliday ) ) {
                    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 );

        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 = "成人の日";
                    } else;
                } else {
                    if ( MyDay == 15 ) {
                        Result = "成人の日";
                    } else;
                }
            }
            break;
    // 2月 //
        case 2:
            if ( MyDay == 11 ) {
                if ( MyYear >= 1967 ) {
                    Result = "建国記念の日";
                } else;
            } else {
                if ( MyDate.equals( cstShowaTaiso ) ) {
                    Result = "昭和天皇の大喪の礼";
                } 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( 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;
            }
            break;
    // 6月 //
        case 6:
            if ( MyDate.equals( cstNorihitoKekkon ) ) {
                Result = "皇太子徳仁親王の結婚の儀";
            } else;
            break;
    // 7月 //
        case 7:
            if ( MyYear >= 2003 ) {
                NumberOfWeek = ( (MyDay - 1 ) / 7 ) + 1;
                if ( ( NumberOfWeek == 3 ) && ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) ) {
                    Result = "海の日";
                } else;
            } else {
                if ( MyYear >= 1996 ) {
                    if ( MyDay == 20 ) {
                        Result = "海の日";
                    } else;
                } else;
            }
            break;
    // 8月 //
        case 8:
            if ( MyDay == 11 ) {
                if ( MyYear >= 2016 ) {
                    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 = "敬老の日";
                    } 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:
            if ( MyYear >= 2000 ) {
                NumberOfWeek = ( ( MyDay - 1 ) / 7 ) + 1;
                if ( (NumberOfWeek == 2 ) && ( MyDate.get( Calendar.DAY_OF_WEEK ) == Calendar.MONDAY ) ) {
                    Result = "体育の日";
                } 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 = "即位礼正殿の儀";
                    } else;
                }
            }
            break;
    // 12月 //
        case 12:
            if ( MyDay == 23 ) {
                if ( MyYear >= 1989 ) {
                    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.