function IsSpecialHoliday(ADate: TDate; var AName: string): Boolean;
// ------------------------------------------------------------
// http://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html
// http://koyomi.vis.ne.jp/
// http://www.asahi-net.or.jp/~CI5M-NMR/misc/equinox.html#Rule
// ------------------------------------------------------------
// ADateが祝日かどうかを返す。
// 祝日=True,祝日ではない=False
// AName には祝日の名前を返す
var
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
case AYear of
1979:
dDay := 24;
else
dDay := Trunc((23.5412 + ((AYear - 1940) * 0.2421904) - (LeapYearCount(1940, AYear) - 1)));
end;
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
// '建国記念の日' 1967~
if (dYear >= 1967) and (dDay = 11) then
begin
result := True;
AName := '建国記念の日';
Exit;
end;
// '天皇誕生日②' 2020~
if (dYear >= 2020) and (dDay = 23) 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
// '天皇の即位' 2019/05/01
if (dYear = 2019) and (dDay = 1) then
begin
result := True;
AName := '天皇の即位';
Exit;
end;
// '憲法記念日' 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
// '海の日①' 1996~2002
if (dYear >= 1996) and (dYear <= 2002) and (dDay = 20) then
begin
result := True;
AName := '海の日';
Exit;
end;
// '海の日②' 2003~
// 第3月曜日 (五輪祝日移動法 により 2020 年は 23 日)
if (dYear >= 2003) then
begin
if ((dYear = 2020) and (dDay = 23)) or
((dYear <> 2020) and (ADate = FreqOfWeek(dYear, dMonth, 3, 2))) then
begin
result := True;
AName := '海の日';
Exit;
end;
end;
// '体育の日③' 2020 (五輪祝日移動法)
if (dYear = 2020) and (dDay = 24) then
begin
result := True;
AName := 'スポーツの日';
Exit;
end;
end;
8:
begin
// '山の日' 2016~
// 第3月曜日 (五輪祝日移動法 により 2020 年は 10 日)
if ((dYear >= 2016) and (dYear <> 2020) and (dDay = 11)) or ((dYear = 2020) and (dDay = 10)) then
begin
result := True;
AName := '山の日';
Exit;
end;
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;
// ※即位礼正殿の儀(2019/10/22)
if (dYear = 2019) and (dDay = 22) then
begin
result := True;
AName := '即位礼正殿の儀';
Exit;
end;
// '体育の日②' 2000~
// 第2月曜日(ハッピーマンデー) (五輪祝日移動法 により 2020 年を除く)
if (dYear >= 2000) and (dYear <> 2020) then
begin
if ADate = FreqOfWeek(dYear, dMonth, 2, 2) then
begin
result := True;
if (dYear < 2020) then
AName := '体育の日'
else
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~2018
if (dYear >= 1989) and (dYear <= 2018) 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;
|