declare
v_ergebnis varchar2(100);
/* Funktion gibt die Bezeichnung eines Feiertages aus, */
/* wenn 'p_date' auf einen Feiertag fällt, sonst 'null'. */
function wannistostern(p_date in date) return date is
-- Das 1. Kirchenkonzil im Jahre 325 hat festgelegt:
-- Ostern ist stets am ersten Sonntag nach dem ersten Vollmond des
-- Frühlings.
-- Stichtag ist der 21. März, die "Frühlings-Tagundnachtgleiche".
-- Am 15.10.1582 wurde von Papst Gregor XIII. der bis dahin gültige
-- Julianische Kalender reformiert. Dieser noch heute gültige
-- "Gregorianische Kalender" legt fest:
-- Ein Jahr hat 365 Tage und ein Schaltjahr wird eingefügt, wenn das
-- Jahr durch 4, aber nicht durch 100, oder durch 400 teilbar ist.
-- Hieraus ergeben sich die zwei notwendigen Konstanten, um den
-- Ostersonntag zu berechnen:
-- Die Jahreslänge von und bis zum Zeitpunkt der
-- "Frühlings-Tagundnachtgleiche": 365,2422 mittlere Sonnentage.
-- Ein Mondmonat: 29,5306 mittlere Sonnentage.
--
-- Carl Friedrich Gauß (1777-1855) entwickelte im Jahre 1800 die
-- "Osterformel". Damit läßt sich der Ostersonntag für jedes Jahr
-- von 1583 bis 8202 berechnen.
v_kalenderjahr integer := to_number(to_char(p_date, 'YYYY'));
v_a integer;
v_b integer;
v_c integer;
v_m integer;
v_s integer;
v_n integer;
v_d integer;
v_e integer;
v_oster_monat integer;
v_oster_tag integer;
begin
v_a := v_kalenderjahr mod 19;
v_b := v_kalenderjahr mod 4;
v_c := v_kalenderjahr mod 7;
v_m := trunc((8*(trunc(v_kalenderjahr/100)) + 13)/25) - 2;
v_s := trunc(v_kalenderjahr/100) - trunc(v_kalenderjahr/400) - 2;
v_m := (15 + v_s - v_m) mod 30;
v_n := (6 + v_s) mod 7;
v_d := (v_m + 19*v_a) mod 30;
if (v_d = 29) then
v_d := 28;
else
if ((v_d = 28) and (v_a >= 11)) then
v_d := 27;
end if;
end if;
v_e := (2*v_b + 4*v_c + 6*v_d + v_n) mod 7;
-- Ostern fällt auf den (d + e + 1)sten Tag nach dem 21. März
v_oster_tag := 21 + v_d + v_e + 1;
v_oster_monat := 3;
if (v_oster_tag > 31) then
v_oster_tag := v_oster_tag - 31;
v_oster_monat := 4;
end if;
-- Der früheste mögliche Ostertermin ist der 22. März.
-- (Wenn der Vollmond auf den 21. März fällt und der 22. März
-- ein Sonntag ist.)
-- Der späteste mögliche Ostertermin ist der 25. April.
-- (Wenn der Vollmond auf den 21. März fällt und der 21. März
-- ein Sonntag ist.)
return to_date(lpad(v_oster_tag, 2, '0')||'.'||
lpad(v_oster_monat, 2, '0')||'.'||
to_char(v_kalenderjahr), 'DD.MM.YYYY');
end wannistostern;
function Ist_Feiertag(p_date in date) return varchar2 is
type t_datum is record(tagmonat varchar2(5)
, bezeichnung varchar2(25)
);
type t_datumsliste is table of t_datum index by binary_integer;
v_feier t_datumsliste;
v_tagmonat varchar2(5) := to_char(p_date, 'DD.MM');
begin
-- Feste Feiertage.
v_feier(1).tagmonat := '01.01';
v_feier(1).bezeichnung := 'Neujahr';
v_feier(2).tagmonat := '01.05';
v_feier(2).bezeichnung := 'Maifeiertag';
v_feier(3).tagmonat := '03.10';
v_feier(3).bezeichnung := 'Tag der Einheit';
v_feier(4).tagmonat := '24.12';
v_feier(4).bezeichnung := 'Heiligabend';
v_feier(5).tagmonat := '25.12';
v_feier(5).bezeichnung := '1. Weihnachtstag';
v_feier(6).tagmonat := '26.12';
v_feier(6).bezeichnung := '2. Weihnachtstag';
v_feier(7).tagmonat := '31.12';
v_feier(7).bezeichnung := 'Sylvester';
-- Bewegliche Feiertage.
v_feier(8).tagmonat := to_char(wannistostern(p_date) - 2, 'DD.MM');
v_feier(8).bezeichnung := 'Karfreitag';
v_feier(9).tagmonat := to_char(wannistostern(p_date), 'DD.MM');
v_feier(9).bezeichnung := 'Ostersonntag';
v_feier(10).tagmonat := to_char(wannistostern(p_date) + 1, 'DD.MM');
v_feier(10).bezeichnung := 'Ostermontag';
v_feier(11).tagmonat := to_char(wannistostern(p_date) + 39, 'DD.MM');
v_feier(11).bezeichnung := 'Himmelfahrt';
v_feier(12).tagmonat := to_char(wannistostern(p_date) + 49, 'DD.MM');
v_feier(12).bezeichnung := 'Pfingstsonntag';
v_feier(13).tagmonat := to_char(wannistostern(p_date) + 50, 'DD.MM');
v_feier(13).bezeichnung := 'Pfingstmontag';
-- Keine Bezeichnung ausgeben, sofern die LOOP keinen Feiertag findet.
for v_i in v_feier.first .. v_feier.last loop
if (v_feier(v_i).tagmonat = v_tagmonat) then
return v_feier(v_i).bezeichnung;
end if;
end loop;
return null;
end Ist_Feiertag;
begin
v_ergebnis := Ist_Feiertag(to_date('01.04.2018', 'dd.mm.yyyy'));
dbms_output.put_line('01.04.2018 ist: '||v_ergebnis);
v_ergebnis := to_char(wannistostern(to_date('01.01.1976', 'dd.mm.yyyy')), 'dd.mm.yyyy');
dbms_output.put_line('Ostern 1976:'||v_ergebnis);
for jahr in 1976..2018
loop
v_ergebnis := wannistostern(to_date('01.01.'||to_char(jahr), 'dd.mm.yyyy'));
dbms_output.put_line(v_ergebnis);
end loop;
end;
01.04.2018 ist: Ostersonntag
Ostern 1976:18.04.1976
18-APR-76
10-APR-77
26-MAR-78
15-APR-79
06-APR-80
19-APR-81
11-APR-82
03-APR-83
22-APR-84
07-APR-85
30-MAR-86
19-APR-87
03-APR-88
26-MAR-89
15-APR-90
31-MAR-91
19-APR-92
11-APR-93
03-APR-94
16-APR-95
07-APR-96
30-MAR-97
12-APR-98
04-APR-99
23-APR-00
15-APR-01
31-MAR-02
20-APR-03
11-APR-04
27-MAR-05
16-APR-06
08-APR-07
23-MAR-08
12-APR-09
04-APR-10
24-APR-11
08-APR-12
31-MAR-13
20-APR-14
05-APR-15
27-MAR-16
16-APR-17
01-APR-18