/* d3_prog.d3_appl.Feiertag.source Version 03.2 Datum: 2007/03/28 11:02 änd: delete seite Version 03.2 Datum: 2007/03/28 11:01 änd: aktuelles Jahr Version 03.2 Datum: 2007/03/28 10:00 änd: default-Jahr Version 03.2 Datum: 2007/03/28 09:00 änd: als entry im SAS catalog Version 03.1 Datum: 2007/03/28 08:00 änd: LST-Ausgabe Version 03.0 Datum: 2007/02/20 12:00 änd: klappt Version .... Version 02.1 Datum: 2006/11/22 15:00 änd: alle beweglichen Feiertage aufbauend auf OsterSo() Version 02.0 Datum: 2006/11/21 12:00 änd: SAS-Lösung der Kalenderfrage zu Ostern (redscope.org) Version .... Version 01.4 Datum: 1993/11/22 12:00 älteste gefundene Version feier.c Quelle: /u3/var/usr/HansK/VGS/HOME/feier.c Quelle: F:\KneilmannH\Diverses\0_cProgramme\feier.c */ /* ------------------------------------------------------------------------- * Programm für Bewegliche Feiertage zu bel. Jahr * * Version: * inklusive allen Hilfs-Makros * * Selektion: * keine * * Verdichtung: * keine * * * Ausgabe: * proc print * alle beweglichen Feiertage * Aufruf: * ======= * filename feiertag catalog 'd3_prog.d3_appl.Feiertag.source'; * %include feiertag; * %feiertage(2007); * * ----------------------------------------------------------------------------*/ %macro OsterSo(year); /* Format: yyyy, also z.2006 */ /*-------------------------------------------------- * Hilfs-Macro * * Berechne Ostersonntag zum Jahr laut Aufruf * Code aus * http://support.sas.com/ctx/samples/index.jsp?sid=1566&tab=code * Idee aus * redscope.org » Startseite » Foren » Allgemeine Fragen zu SAS » Kalenderfrage zu Ostern * http://www.redscope.org/node/432 * * Beispiel: * ========= * %OsterSo(2006); Soll-Datum: 20060416 * %put INFO: OsterSo=&OsterSo.; * %OsterSo(2007); Soll-Datum: 20070408 * %put INFO: OsterSo=&OsterSo.; *--------------------------------------------------*/ title3 "Berechne Ostersonntag zum Jahr &year. (&year. laut Aufruf)"; %put INFO: OsterSo(year=&year.), Start; %global OsterSo; %let OsterSo=00000000; %global OsterCnt; %let OsterCnt=000; data _null_; format easter_date worddate.; year=&year.; if 1980<=year<=2024 then do; c=int(year/100); n=year-(19*int(year/19)); k=int((c-17)/25); i=c-int(c/4)-int((c-k)/3)+(19*n)+15; i=i-(30*int(i/30)); i=i-(int(i/28)*(1-int(i/28)*int(29/(i+1))*int((21-n)/11))); j=year+int(year/4)+i+2-c+int(c/4); j=j-(7*int(j/7)); month=3+int((i-j+40)/44); day=i-j+28-(31*int(month/4)); easter_date=mdy(month,day,year); put easter_date; call symput("errcode", "0"); put day= month= year=; length OsterSo $8.; OsterSo = put(year, z4.) || put(month, z2.) || put(day, z2.); put OsterSo=; call symput("OsterSo", OsterSo); daydiff=intck ("day", input(put(year, z4.)||"0101", yymmdd8.), input(OsterSo, yymmdd8.) ); OsterCnt=daydiff; call symput("OsterCnt", put(OsterCnt,z3.)); end; else do; file log; put "%substr(###ERROR,4)" ": ungültiges Jahr (year=&year., nicht 1980<=year<=2024)"; call symput("errcode", "-9"); end; run; %put INFO: macro OsterSo, OsterSo zu Jahr=&year. ist OsterSo=&OsterSo., OsterCnt=&OsterCnt. (errcode=&errcode.), Ende; title3 " "; %mend OsterSo; %macro wotag(datum, OsterCnt= ); /* Format: yyyymmdd, also z.20061224 */ /*-------------------------------------------------- * Hilfs-Macro * * Berechne Wochentag zum Datum laut Aufruf * * Beispiel: * ========= * %wotag(20061122); * %put INFO: wotag=&wotag. (20061122 ist ein Mittwoch); * * %wotag(20071224, OsterCnt=97); * %put INFO: wotag=&wotag. (20071224 ist ein Montag); * *--------------------------------------------------*/ %put INFO: wotag(datum=&datum., OsterCnt=&OsterCnt.), Start; %global wotag; proc format; value wotgfmt 0 = 'Sonntag' 1 = 'Montag' 2 = 'Dienstag' 3 = 'Mittwoch' 4 = 'Donnerstag' 5 = 'Freitag' 6 = 'Samstag' other = 'kein Text vorhanden'; ; run; %if &OsterCnt. EQ %then %do; %OsterSo(%substr(&datum.,1,4)); %put INFO: wotag(datum=&datum., OsterCnt=&OsterCnt.); %end; data _null_; /*anf="%substr(&datum.,1,4)0101";*/ /*OsterSonn="&OsterSo.";*/ /*daydiff=intck ("day", input(anf, yymmdd8.), input(OsterSonn, yymmdd8.) );*/ /*ostern_cnt=daydiff;*/ ostern_cnt=&OsterCnt.; /*put _all_;*/ datum="&datum."; daydiff=intck ("day", input("%substr(&datum.,1,4)0101", yymmdd8.), input(datum, yymmdd8.) ); /*put _all_;*/ datum_wotag = mod((daydiff-ostern_cnt) , 7); put datum_wotag wotgfmt.; call symput("wotag", put(datum_wotag, wotgfmt.)); run; %put INFO: macro wotag, zu datum=&datum. ist wotag=&wotag., Ende; %mend wotag; %macro dcnt2ymd(daycnt, year); /* Input: lfd. Tag im Jahr, z.B. 105 für den 16.04.2006 */ /*-------------------------------------------------- * Hilfs-Macro * * Berechne Datum zum lfd. Tag im Jahr laut Aufruf (zum Jahr laut Aufruf) * * Beispiel: * ========= * %dcnt2ymd(105, 2006); * %put INFO: datum=&datum.; ergibt 16.04.2006 * * %dcnt2ymd(325, 2006); * %put INFO: datum=&datum.; ergibt 22.11.2006 *--------------------------------------------------*/ %put INFO: dcnt2ymd(daycnt=&daycnt., year=&year.), Start; %global datum; %let datum=00000000; data _null_; anf="%substr(&year.,1,4)0101"; datumD = intnx( 'day', input(anf, yymmdd8.), &daycnt. ); datumC = put(year( datumD), z4.) || put(month(datumD), z2.) || put(day( datumD), z2.); call symput("datum", datumC); run; %put INFO: macro dcnt2ymd, zu daycnt=&daycnt. ist datum=&datum., Ende; %mend dcnt2ymd; %macro feiertage(Jahr); /*-------------------------------------------------- * Macro-Programm * * Berechne alle beweglichen Feiertage zum Jahr laut Aufruf * Idee (insbes. die Feiertags-Rechenregeln) aus * feier.c von Nov. 1993 (feier.c Version 1.4 - 22/11/93 12:00) * Quelle: /u3/var/usr/HansK/VGS/HOME/feier.c * Quelle: F:\KneilmannH\Diverses\0_cProgramme\feier.c * * Beispiel: * ========= * %feiertage(2007); * * Ausgabe als Muster: * =================== * Berechne alle beweglichen Feiertage zum Jahr 2007 (2007 laut Aufruf) * * * ' * * Oster-Sonntag 2007 ist 20070408 * Fastnacht-Dienstag 2007 ist 20070220 * Karfreitag 2007 ist 20070406 * Oster-Montag 2007 ist 20070409 * Himmelfahrt 2007 ist 20070517 * Pfingst-Sonntag 2007 ist 20070527 * Pfingst-Montag 2007 ist 20070528 * Fronleichnam 2007 ist 20070607 * Heilig-Abend 2007 ist Montag * 1. Weihnachts-Tag 2007 ist Dienstag * 4. Advent 2007 ist 20071223 * Buss+Bettag 2007 ist 20071121 *--------------------------------------------------*/ title2 "Berechne alle beweglichen Feiertage zum Jahr &Jahr. (&Jahr. laut Aufruf)"; %put INFO: feiertage(Jahr=&Jahr.), Start; %if &Jahr. eq %then %do; %let jetztzt=%sysfunc(datetime()); %let aktyy4 =%sysfunc(putn(%sysfunc(year (%sysfunc(datepart(&jetztzt.)))),z4.)); %let Jahr=&AKTYY4.; title2 "Berechne alle beweglichen Feiertage zum Jahr &Jahr. "; %put INFO: Jahr=&Jahr. (default); %end; /* altes Ergebnis weglöschen (falls vorhanden): */ proc datasets lib=work nolist; delete seite; run; quit; %OsterSo(&Jahr.); %put INFO: OsterSo=&OsterSo. OsterCnt=&OsterCnt.; %put INFO: Oster-Sonntag &Jahr. ist &OsterSo.; data zeile; length text $80.; text="Oster-Sonntag &Jahr. ist &OsterSo."; run; proc append data=zeile base=seite; run; %let fastnaCnt=%eval(&OsterCnt. - 47); %dcnt2ymd(&fastnaCnt.,&Jahr.); %put INFO: Fastnacht-Dienstag &Jahr. ist &datum.; data zeile; length text $80.; text="Fastnacht-Dienstag &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; %let karfreCnt=%eval(&OsterCnt. - 2); %dcnt2ymd(&karfreCnt.,&Jahr.); %put INFO: Karfreitag &Jahr. ist &datum.; data zeile; length text $80.; text="Karfreitag &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; %let ostemoCnt=%eval(&OsterCnt. + 1); %dcnt2ymd(&ostemoCnt.,&Jahr.); %put INFO: Oster-Montag &Jahr. ist &datum.; data zeile; length text $80.; text="Oster-Montag &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; %let himmelCnt=%eval(&OsterCnt. + 39); %dcnt2ymd(&himmelCnt.,&Jahr.); %put INFO: Himmelfahrt &Jahr. ist &datum.; data zeile; length text $80.; text="Himmelfahrt &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; %let pfingsCnt=%eval(&OsterCnt. + 49); %dcnt2ymd(&pfingsCnt.,&Jahr.); %put INFO: Pfingst-Sonntag &Jahr. ist &datum.; data zeile; length text $80.; text="Pfingst-Sonntag &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; %let pfinmoCnt=%eval(&OsterCnt. + 50); %dcnt2ymd(&pfinmoCnt.,&Jahr.); %put INFO: Pfingst-Montag &Jahr. ist &datum.; data zeile; length text $80.; text="Pfingst-Montag &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; %let fronleCnt=%eval(&OsterCnt. + 60); %dcnt2ymd(&fronleCnt.,&Jahr.); %put INFO: Fronleichnam &Jahr. ist &datum.; data zeile; length text $80.; text="Fronleichnam &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; %wotag(&Jahr.1224, OsterCnt=&OsterCnt.); %put INFO: Heilig-Abend &Jahr. ist &wotag.; data zeile; length text $80.; text="Heilig-Abend &Jahr. ist &wotag."; run; proc append data=zeile base=seite; run; data _null_; ostern_cnt=&OsterCnt.; datum="&Jahr.1225"; daydiff=intck ("day", input("&Jahr.0101", yymmdd8.), input(datum, yymmdd8.) ); weihn1_cnt=daydiff; call symput("weihn1Cnt", put(weihn1_cnt,z3.)); datum_wotag = mod((daydiff-ostern_cnt) , 7); put datum_wotag wotgfmt.; weihn1_wotag=datum_wotag; put weihn1_wotag wotgfmt.; call symput("weihn1_wotag", put(weihn1_wotag, wotgfmt.)); if weihn1_wotag EQ 0 then do; adven4_cnt = weihn1_cnt - 7; end; else do; adven4_cnt = weihn1_cnt-weihn1_wotag; end; call symput("adven4Cnt", put(adven4_cnt,z3.)); run; %put INFO: 1. Weihnachts-Tag &Jahr. ist &weihn1_wotag.; %put INFO: 1. Weihnachts-Tag &Jahr. ist &weihn1Cnt. Tag im Jahr; %put INFO: 4. Advent &Jahr. ist &adven4Cnt. Tag im Jahr; data zeile; length text $80.; text="1. Weihnachts-Tag &Jahr. ist &weihn1_wotag."; run; proc append data=zeile base=seite; run; %dcnt2ymd(&adven4Cnt.,&Jahr.); %put INFO: 4. Advent &Jahr. ist &datum.; data zeile; length text $80.; text="4. Advent &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; %let busbetCnt=%eval(&adven4Cnt. - 3*7 - 1*7 - 4); %dcnt2ymd(&busbetCnt.,&Jahr.); %put INFO: Buss+Bettag &Jahr. ist &datum.; data zeile; length text $80.; text="Buss+Bettag &Jahr. ist &datum."; run; proc append data=zeile base=seite; run; /* Abschluß-Ausgabe */ proc print data=seite noobs label; label text=''; run; %macro AUS; /* 20070328: AUS, Programm soll stand-alone laufen können ! */ /* Ergebnis abliefern: */ proc copy out=&MyWork. in=work; select seite / mt=data ; run; %mend AUS; title2 " "; %mend feiertage;