```Date: Thu, 21 Jul 2011 16:56:24 -0400 Reply-To: Chang Chung Sender: "SAS(r) Discussion" From: Chang Chung Subject: Re: Figuring out Age in Years, Months and Days Comments: To: John Parker On Wed, 20 Jul 2011 11:30:11 -1000, John Parker wrote: ... >I have a requirement to figure out Age at Death and it has to be expressed >in Years, Months, Weeks and Days. ... Hi, John, I think Mark Miller has a right approach, which I implement a bit differently. HTH. Cheers, Chang options nocenter; proc fcmp outlib=work.func.test; /* report age in years months weeks and days */ /* public wrapper */ function xage(birth, death) \$200; length r \$200; r = xagerec(birth, death, "year"); if missing(r) then r = "less than a day"; return (r); endsub; /* recursive work horse */ function xagerec(birth, death, unit \$) \$200; length current next r \$200; if missing(unit) then return (" "); if unit = "day" then return (putf(death-birth, "day")); b = birth; do n = 0 by 1 until (b > death); b = intnx(unit, birth, n, 'same'); end; m = n - 1; current = catx(" ", putf(m, unit)); b = intnx(unit, birth, m, 'same'); nextunit = smaller(unit); next = xagerec(b, death, nextunit); r = catx(" ", current, next); return (r); endsub; /* utilities */ function smaller(unit \$) \$5; if unit = "year" then return ("month"); if unit = "month" then return ("week"); if unit = "week" then return ("day"); if unit = "day" then return (""); endsub; function putf(n, unit \$) \$20; length r \$20; if n <= 0 then r = ""; else do; r = catx(" ", putn(n, "best."), unit); if n > 1 then r = cats(r, "s"); end; return (r); endsub; quit; %let cmplib = %sysfunc(getoption(cmplib)); options cmplib = (work.func &cmplib); data one; input (born died)(:yymmdd.); format born died yymmdd10.; length age \$80.; age = xage(born, died); cards; 19131230 19131230 19131230 19131231 19131231 20110601 19140101 20110602 19140201 19140202 19140201 19140206 19140201 19140207 19140201 19140208 19140201 19140228 19440111 20100103 19450627 20110627 19451012 20110512 19451012 20110511 19451012 20110513 19990227 20000228 19990227 20000229 20000201 20000229 20000201 20000301 20000228 20010227 20000229 20010301 20071012 20100421 20071012 20081011 20071012 20081012 20071012 20081013 20071012 20081014 20071012 20071021 20071012 20071029 20011221 20020102 ; run; /* check */ proc print data=one; run; /* on lst Obs born died age 1 1913-12-30 1913-12-30 less than a day 2 1913-12-30 1913-12-31 1 day 3 1913-12-31 2011-06-01 97 years 5 months 1 day 4 1914-01-01 2011-06-02 97 years 5 months 1 day 5 1914-02-01 1914-02-02 1 day 6 1914-02-01 1914-02-06 5 days 7 1914-02-01 1914-02-07 6 days 8 1914-02-01 1914-02-08 1 week 9 1914-02-01 1914-02-28 3 weeks 6 days 10 1944-01-11 2010-01-03 65 years 11 months 3 weeks 2 days 11 1945-06-27 2011-06-27 66 years 12 1945-10-12 2011-05-12 65 years 7 months 13 1945-10-12 2011-05-11 65 years 6 months 4 weeks 1 day 14 1945-10-12 2011-05-13 65 years 7 months 1 day 15 1999-02-27 2000-02-28 1 year 1 day 16 1999-02-27 2000-02-29 1 year 2 days 17 2000-02-01 2000-02-29 4 weeks 18 2000-02-01 2000-03-01 1 month 19 2000-02-28 2001-02-27 11 months 4 weeks 2 days 20 2000-02-29 2001-03-01 1 year 1 day 21 2007-10-12 2010-04-21 2 years 6 months 1 week 2 days 22 2007-10-12 2008-10-11 11 months 4 weeks 1 day 23 2007-10-12 2008-10-12 1 year 24 2007-10-12 2008-10-13 1 year 1 day 25 2007-10-12 2008-10-14 1 year 2 days 26 2007-10-12 2007-10-21 1 week 2 days 27 2007-10-12 2007-10-29 2 weeks 3 days 28 2001-12-21 2002-01-02 1 week 5 days */ options cmplib = (&cmplib); ```

Back to: Top of message | Previous page | Main SAS-L page