This is a SAS code puzzle. The code works as is, but can you make it simpler? We do this while enjoying simulation and the quirkiness of the Gregorian calendar.
A person receives a gift on a random day. Relative to his birthday, how many days is the gift late?
Negative values indicate the gift is early, and zero indicates the gift is well timed. The difference must not be greater than one-half year.
Sample data set
This SAS code generates a data set containing the person identifier, his birth date, and the date he received a gift.
data birth_day_gifts; /* the event is the gift */ format birth_date gift_date yymmdd10.; do n = 1 to 40; /* create 40 cases */ /* the birth date is a random day in the 20th century */ birth_date = intnx('day', mdy(1,1, 1900+(2000-1900)*ranuni(0)), 365*ranuni(0)); /* the gift is a random day in 2010 or 2011 */ gift_date = intnx('day', mdy(1,1, 2010+2*ranuni(0)), 365*ranuni(0)); output; end; run;
For other problems, thirteen lines of code may seem elegant, but not for this one.
data birth_day_gifts; set birth_day_gifts; format birth_date_0 birth_date_minus1 birth_date_plus1 yymmdd10.; /* calculate the birthday in the same year as gift */ if month(birth_date) eq 2 and day(birth_date) eq 29 then birth_date_0 = mdy(month(birth_date), 28, year(gift_date)); else birth_date_0 = mdy(month(birth_date), day(birth_date), year(gift_date)); birth_date_0_diff = gift_date - birth_date_0; diff = birth_date_0_diff; /* one year ahead */ birth_date_plus1 = intnx('year', birth_date_0, 1, 'sameday'); birth_date_plus1_diff = gift_date - birth_date_plus1; if (abs(birth_date_plus1_diff) < abs(diff)) then diff = birth_date_plus1_diff; /* one year behind */ birth_date_minus1 = intnx('year', birth_date_0, -1, 'sameday'); birth_date_minus1_diff = gift_date - birth_date_minus1; if (abs(birth_date_minus1_diff) < abs(diff)) then diff = birth_date_minus1_diff; run;
I used SAS 9.1.3 which doesn’t yet have new date functions from SAS/ETS (e.g., INTCINDEX).