Accurately calculating age in only one line

This SAS code was written by Billy Kreuter, who posted it to the SAS-L mailing list several years ago. Billy authored an article in SAS Communications (4th quarter 1998) which discusses this issue in greater detail.

The following code calculates age in completed years from the variables birth and somedate.

age = floor((intck('month',birth,somedate)
- (day(somedate) < day(birth))) / 12); 

This can be conveniently set up as a macro:

%macro age(date,birth);
floor ((intck('month',&birth,&date)
- (day(&date) < day(&birth))) / 12) 
%mend age;

The macro is used in a SAS DATA step as follows:

age = %age(somedate,birth); 

For example, the following lines:

age = %age('28aug1998'd,'24mar1955'd);
put age=; 

will cause the following message to be placed on the log:


The approach is to first calculate the number of completed months between the two dates and then divide by 12 and round down to get the number of completed years.

The following code could be used to calculate the number of completed months between the dates birth and somedate.

months = intck('month',birth,somedate) 
         - (day(somedate) < day(birth));

The first part of the code uses the intck function to calculate the number of times a 'month boundary' (e.g from January to February) is crossed between the two dates. Crossing a 'month boundary' does not necessarily mean that a completed month has elapsed so a correction needs to be made when the end date (somedate) is less than the start date (birth)..

To convert completed months to completed years one uses


The floor function simply rounds a real number down to the nearest integer, for example floor(4.93)=4.

See also the notes on Calculating age at diagnosis from PNR and diagnosis date.