It seems like such a simple problem: how can you reliably compute the age of someone or something? Susan lamented the subtle issues using the YRDIF function exactly 1.0356164384 years ago.

Sure, you could write your own function for calculating such things, as I suggested 0.1753424658 years ago.

Or you could ask your colleagues in the discussion forums, as I noticed some people doing just about 3.7890410959 years ago.

Or, now that SAS 9.3 is available, you can take advantage of the new AGE basis that the YRDIF function supports. For example:

data _null_; x = yrdif('29JUN2010'd,today(),'AGE'); y = yrdif('09MAY2011'd,today(),'AGE'); z = yrdif('27SEP2007'd,today(),'AGE'); put x= y= z=; run; |

Yields:

x=1.0356164384 y=0.1753424658 z=3.7890410959

This new feature and many more were added in direct response to customer feedback from Susan and others. And that's a practice that never gets old.

## 10 Comments

Wow, I am so excited that there is finally a definitive way to compute ages!!!

Thanks for giving me credit, although I notice that they didn't use my suggestion that there should be an easy version of this function

x = AGE(birthdate);

The YRDIF solution is great for programmers, but it's going to confuse non-programmers. Maybe they'll put that in SAS 9.4?

Susan,

With FCMP, you can package up your own AGE function:

proc fcmp outlib=work.myfuncs.dates;

function age(d);

return(yrdif(d,today(),'AGE'));

endsub;

run; quit;

/** to use it **/

options cmplib=work.myfuncs;

data _null_;

x = age('29SEP2007'd);

put x=;

run;

Chris,

The YRDIF documentation is a bit sketchy. Does it precisely calculate the integer years of age (like Billy Kreuter's macro did)? I.e. will

FLOOR(YRDIF(begin, end, 'AGE'));

*always* provide the person's age in years. I'm concerned with roundoff (for things like determining Medicare eligibility).

Thanks,

Doc

I think if we assume that people who are born on 29th Feb in a leap Year celebrate their birthdays on 28th Feb in a non leap year and on 29th Feb in a Leap year then the following accurately calculates the Age of a Person in SAS 9.2 for all date ranges :

Data _NULL_ ;

BirthDate ='29Feb2008'd;

EndDate='28Feb2009'd;

Age = intck("year",BirthDate,EndDate)-(put(BirthDate,mmddyy4.) gt put(EndDate,mmddyy4.))+(put(BirthDate,mmddyy4.)="0229" and put(EndDate,mmddyy4.)="0228" and put(EndDate+1,mmddyy4.)="0301");

Put BirthDate=date9. EndDate=date9. Age=;

run;

This gives BirthDate=29FEB2008 EndDate=28FEB2009 Age=1 in the SAS Log.

I wonder if the YRDIF function in SAS 9.3 does the same too.

Prashant - yes, I believe it does work correctly for leap years. I tried your example and it worked simply with:

`Age2 = yrdif(BirthDate,EndDate,'AGE');`

Thanks for the Confirmation Chris.

These formulas are not the same though in a leapyear.

Data _NULL_ ;

BirthDate ='29Feb2008'd;

EndDate='28Feb2012'd;

Age = intck("year",BirthDate,EndDate)-(put(BirthDate,mmddyy4.) gt

put(EndDate,mmddyy4.))+(put(BirthDate,mmddyy4.)="0229" and put(EndDate,mmddyy4.)="0228" and put(EndDate+1,mmddyy4.)="0301");

Age2=yrdif(BirthDate,EndDate,'AGE');

Put BirthDate=date9. EndDate=date9. Age= Age2=;

run;

BirthDate=29FEB2008 EndDate=28FEB2012 Age=3 Age2=4

I agree, Lex, in this case (on multiples of 4 years after a Feb 29), YRDIF incorrectly increments the age on the 28th of the month instead of the 29th. No one born February 29th is going to celebrate their fortieth birthday on the 28th when there is a 29th in that year! The following statement, using the new-ish CONTINUOUS method for INTCK, calculates it correctly (as an integer) in all cases:

age3 = INTCK('YEAR', BirthDate, EndDate, 'C');

I have found that when it comes to leap year and how to count age, there is lots of opportunity to poke holes in the various algorithms. I think it comes down to the question you are trying to answer. "What is Joe's exact age in years?" might be different than "What day should I mail Joe's birthday card so it arrives on his birthday?"

Pingback: Visualize the ages of US presidents - The DO Loop