* cvtymdsas.sas Daniel Brockman 070626 Convert yyyymmdd to a SAS date. ; %macro cvtymdsas(setin, datin, setout, datout) ; /* * setin = the data set on which to operate * datin = the name of the variable containing (yy)yymmdd data * setout = new data set created by this macro. * datout = the new variable containing SAS date equivalent to * datin and created by this macro. * * This macro incorporates a data step. * If datin isn't a valid date, then the corresponding value in datout * will be missing. * This macro uses three processing variables y, m, and d, which * would overwrite any variables by the same names in the setin dataset. * This macro eliminates all but the first obs for a given date. */ %let thisyear = 7; * we will straightaway overwrite this ; %let thiscent = 20; * we will straightaway overwrite this ; data NULL (drop=yr); yr=year(today()) ; call symput('thisyear',yr); * get the number of the current year; run; data &setout (drop=y m d); set &setin; /* There is something wrong with this drop line drop y m d ; * we won't need y m and d after this data step; */ if &datin ; * keep only obs with date ; if (&datin = lag(&datin)) then delete; * keep only 1st obs with given date ; * Break date into year, month & day.; y = int(&datin/10000); m = int((&datin - y*10000)/100); d = &datin - y*10000 - m*100 ; * convert to yyyymmdd from yymmdd; if (y < 100) then do; * we have a 2-digit year?; y = %eval(%eval(&thisyear/100)*100) + y ; * assume same cent as today; if (y < %eval(&thisyear-50)) then do; * today more than 50 yrs later? ; y = 100 + y ; * add 100 years to y; end; else if (y > %eval(&thisyear+50)) then do; * today > 50 yrs earlier? ; y = -100 + y ; * subtract 100 years from y; end; &datin = y * 10000 + m * 100 + d ; * restate datin; end ; * if (y<100) ; &datout = input (put (&datin, Z8.), yymmdd8.) ; run; * end of data step; * proc contents data=&setout; * test; * run; * test; %mend cvtymdsas ; * ---------------------------------------------------- ; */