function IsSpecialHoliday(ADate: TDate; var AName: string): Boolean; // ------------------------------------------------------------ // http://koyomi.vis.ne.jp/ // http://www.asahi-net.or.jp/~CI5M-NMR/misc/equinox.html#Rule // ------------------------------------------------------------ // ADateが祝日かどうかを返す。 // 祝日=True,祝日ではない=False // AName には祝日の名前を返す var dYear, dMonth, dDay: Word; DName: string; i:Integer; {FreqOfWeek Begin} function FreqOfWeek(AYear, AMonth: Word; AWeekNo, ADayOfWeeek: Byte): TDateTime; // AYear年AMonth月の第AWeekNo「ADayOfWeeek曜日」の日付を返す // ADayOfWeeek 日曜日=1..土曜日=7 var dDay: Word; dDoW: Word; dWeekNo: Byte; begin dDoW := DayOfWeek(EncodeDate(AYear, AMonth, 1)); dWeekNo := AWeekNo; if ADayOfWeeek >= dDoW then dWeekNo := dWeekNo - 1; dDay := (dWeekNo * 7) + (ADayOfWeeek - dDoW) + 1; result := EncodeDate(AYear, AMonth, dDay); end; {FreqOfWeek End} {LeapYearCount Begin} function LeapYearCount(SYear, EYear: Word): Integer; // SYearからEYear迄に何回閏年があるかを返す var i: Integer; Cnt: Integer; begin Cnt := 0; for i := sYear to eYear do begin if (i mod 4) <> 0 then Continue; if IsLeapYear(i) then Inc(Cnt); end; result := Cnt; end; {LeapYearCount End} {VernalEquinox End} function VernalEquinox(AYear: Word): TDateTime; // Ayearの春分の日を求める var dDay: Word; begin dDay := Trunc((21.147 + ((AYear - 1940) * 0.2421904) - (LeapYearCount(1940, AYear) - 1))); result := EncodeDate(AYear, 3, dDay); end; {VernalEquinox End} {AutumnalEquinox End} function AutumnalEquinox(AYear: Word): TDateTime; // Ayearの秋分の日を求める var dDay: Word; begin dDay := Trunc((23.5412 + ((AYear - 1940) * 0.2421904) - (LeapYearCount(1940, AYear) - 1))); result := EncodeDate(AYear, 9, dDay); end; {AutumnalEquinox End} {_IsSpecialHoliday Begin} function _IsSpecialHoliday(ADate: TDate; var AName: string): Boolean; // ADateが祝日かどうかを返す。 // 祝日=True,祝日ではない=False // AName には祝日の名前を返す // '国民の休日'はここでは算出されない var dYear, dMonth, dDay: Word; begin AName := ''; result := False; DecodeDate(ADate, dYear, dMonth, dDay); case dMonth of 1: begin // '元日' 1948~ if (dYear >= 1948) and (dDay = 1) then begin result := True; AName := '元日'; Exit; end; // '成人の日①' 1948~1999 if (dYear >= 1948) and (dYear <= 1999) and (dDay = 15) then begin result := True; AName := '成人の日'; Exit; end; // '成人の日②' 2000~ // 第2月曜日(ハッピーマンデー) if (dYear >= 2000) then begin if ADate = FreqOfWeek(dYear, dMonth, 2, 2) then begin result := True; AName := '成人の日'; Exit; end; end; end; 2: begin // '建国記念の日' 1966~ if (dYear >= 1966) and (dDay = 11) then begin result := True; AName := '建国記念の日'; Exit; end; // ※昭和天皇の大喪の礼(1989/02/24) if (dYear = 1989) and (dDay = 24) then begin result := True; AName := '昭和天皇の大喪の礼'; Exit; end; end; 3: begin // '春分の日' 1949~ if (dYear >= 1949) then begin if ADate = VernalEquinox(dYear) then begin result := True; AName := '春分の日'; Exit; end; end; end; 4: begin // '天皇誕生日' 1948~1988 if (dYear >= 1948) and (dYear <= 1988) and (dDay = 29) then begin result := True; AName := '天皇誕生日'; Exit; end; // 'みどりの日①' 1989~2006 if (dYear >= 1989) and (dYear <= 2006) and (dDay = 29) then begin result := True; AName := 'みどりの日'; Exit; end; // '昭和の日' 2007~ if (dYear >= 2007) and (dDay = 29) then begin result := True; AName := '昭和の日'; Exit; end; // ※皇太子明仁親王の結婚の儀(1959/04/10) if (dYear = 1959) and (dDay = 10) then begin result := True; AName := '皇太子明仁親王の結婚の儀'; Exit; end; end; 5: begin // '憲法記念日' 1948~ if (dYear >= 1948) and (dDay = 3) then begin result := True; AName := '憲法記念日'; Exit; end; // 'みどりの日②' 2007~ if (dYear >= 2007) and (dDay = 4) then begin result := True; AName := 'みどりの日'; Exit; end; // 'こどもの日' 1948~ if (dYear >= 1948) and (dDay = 5) then begin result := True; AName := 'こどもの日'; Exit; end; end; 6: begin // ※皇太子徳仁親王の結婚の儀(1993/06/09) if (dYear = 1993) and (dDay = 9) then begin result := True; AName := '皇太子徳仁親王の結婚の儀'; Exit; end; end; 7: begin // '海の日①' 1995~2002 if (dYear >= 1995) and (dYear <= 2002) and (dDay = 20) then begin result := True; AName := '海の日'; Exit; end; // '海の日②' 2003~ // 第3月曜日 if (dYear >= 2003) then begin if ADate = FreqOfWeek(dYear, dMonth, 3, 2) then begin result := True; AName := '海の日'; Exit; end; end; end; 8: begin end; 9: begin // '敬老の日①' 1966~2002 if (dYear >= 1966) and (dYear <= 2002) and (dDay = 15) then begin result := True; AName := '敬老の日'; Exit; end; // '敬老の日②' 2003~ // 第3月曜日 if (dYear >= 2003) then begin if ADate = FreqOfWeek(dYear, dMonth, 3, 2) then begin result := True; AName := '敬老の日'; Exit; end; end; // '秋分の日' 1948~ if (dYear >= 1948) then begin if ADate = AutumnalEquinox(dYear) then begin result := True; AName := '秋分の日'; Exit; end; end; end; 10: begin // '体育の日①' 1966~1999 if (dYear >= 1966) and (dYear <= 1999) and (dDay = 10) then begin result := True; AName := '体育の日'; Exit; end; // '体育の日②' 2000~ // 第2月曜日(ハッピーマンデー) if (dYear >= 2000) then begin if ADate = FreqOfWeek(dYear, dMonth, 2, 2) then begin result := True; AName := '体育の日'; Exit; end; end; end; 11: begin // '文化の日' 1948~ if (dYear >= 1948) and (dDay = 3) then begin result := True; AName := '文化の日'; Exit; end; // '勤労感謝の日' 1948~ if (dYear >= 1948) and (dDay = 23) then begin result := True; AName := '勤労感謝の日'; Exit; end; // ※即位礼正殿の儀(1990/11/12) if (dYear = 1990) and (dDay = 12) then begin result := True; AName := '即位礼正殿の儀'; Exit; end; end; 12: begin // '天皇誕生日' 1948~ if (dYear >= 1989) and (dDay = 23) then begin result := True; AName := '天皇誕生日'; Exit; end; end; end; end; {_IsSpecialHoliday End} begin result := False; AName := ''; if _IsSpecialHoliday(ADate, DName) then begin result := True; AName := DName; end else if (ADate >= EncodeDate(1973, 4, 12)) and (DayOfWeek(ADate) = 2) and _IsSpecialHoliday(ADate - 1, DName) then begin // 振替休日① 1973/04/12以降 // 日曜日と祝祭日が重なった場合には'振替休日'となる result := True; AName := '振替休日'; end else if (ADate >= EncodeDate(1988, 5, 4)) and (DayOfWeek(ADate) <> 1) and _IsSpecialHoliday(ADate - 1, DName) and _IsSpecialHoliday(ADate + 1, DName) then begin // 国民の休日 1988/05/04以降 // 祝日と祝日に挟まれた平日は'国民の休日'となる。 result := True; AName := '国民の休日'; end else if (ADate >= EncodeDate(2008, 5, 6)) and (DayOfWeek(ADate) <> 1) and _IsSpecialHoliday(ADate - DayOfWeek(ADate) + 1, DName) then begin // 振替休日② 2008/05/06以降 // '祝日'が日曜日に当たるときは、その日後においてその日に最も近い'祝日'でない日を休日とする result := True; AName := '振替休日'; for i:=1 to DayOfWeek(ADate) - 2 do begin if not _IsSpecialHoliday(ADate - i, DName) then begin result := False; AName := ''; Break; end; end; end; end;
|