/**** TIP000416 ****/

BY Chris Jones

Email: chris@mollingtonconsultants.com

* Easter Calculation;
* This works for all dates from 1583 (or first Gregorian date) through to 4099;
* translated to SAS from the Basic program developed by R W Mallen of the Astronimical Society of South Australia;
* and published at http://www.assa.org.au/edm.html#Computer ;

%macro calc_Easter(yy=);
%*options nomprint nomlogic nosymbolgen;
	%local firstDig Remain19 temp ta tb tc td te dd mm result;

	%let firstDig = %sysfunc(int(&yy / 100)); %* first two digits of year;
	%let remain19 = %sysfunc(mod(&yy, 19));	%* remainder of year;
	%put FirstDig=&firstDig;
	%put Remain19=&remain19;

	%* calculate PFM date;
	%let temp = %eval(%sysfunc(int((&firstDig. - 15) / 2)) + 202 - 11 * &remain19.);
	%put TEMP=&temp;

	%let dayarr=%str(21,24,25,27,28,29,30,31,32,34,35,38);
	%let day2arr=%str(33,36,37,39,40);
	%if %sysfunc(find(&dayarr.,&firstDig.)) %then %do;
		%let temp = %eval(&temp. - 1); %put TEMP - 1=&temp;
	%end;
	%else %if %sysfunc(find(&day2arr.,&firstDig.)) %then %do;
		%let temp = %eval(&temp. - 2); %put TEMP - 2=&temp;
	%end;
	%let temp = %sysfunc(mod(&temp., 30)); %put TEMP mod 30=&temp;

	%let tA= %eval(&temp + 21); %put TA=&tA;
	%if &temp. = 29 %then %do;
		%let tA = %eval(&tA - 1); %put TA (temp=29)=&tA;
	%end;
	%if &temp. = 28 and &remain19. > 10 %then %do;
		%let tA = %eval(&tA - 1); %put TA (temp=28 and remain19 > 10=&tA;
	%end;

	%* Find the next Sunday;
	%let tB = %sysfunc(mod(%eval(&tA - 19),7)); %put TB=&tb;

	%let tC = %sysfunc(mod(%eval(40 - &firstDig),4)); %put TC=&tc;
	%if &tC = 3 %then %do;
		%let tC = %eval(&tC + 1); %put TC (TC=3)=&tc;
	%end;
	%if &tC > 1 %then %do;
		%let tC = %eval(&tC + 1); %put TC (TC > 1)=&tc;
	%end;

	%let temp = %sysfunc(mod(&yy.,100)); %put TEMP=&temp;
	%let tD = %sysfunc(mod((&temp + %sysfunc(int(&temp. / 4))),7)); %put TD=&td;

	%let tE = %eval(%sysfunc(mod(%eval(20 - &tB -&tC - &tD),7)) + 1); %put TE=&te;
	%let Dd = %eval(&tA + &tE); %let DD=&Dd;

	%* Return the date;
	%if &dD > 31 %then %do;
		%let Dd = %eval(&Dd - 31); %put DD=&Dd;
		%let mM = 4; %put MM=&Mm;
	%end;
	%else %do;
		%let mm = 3; %put MM=&mm;
	%end;
	%let result=&yy.-&mm.-ⅆ
	&result
%mend;

%let easter=%calc_easter(yy=2016);
%put EASTER=&easter.;

/*** end of tip 00416 ***/