How to calculate age (in years) based on Date of Birth and getDate()

前端 未结 30 2097
死守一世寂寞
死守一世寂寞 2020-11-22 02:08

I have a table listing people along with their date of birth (currently a nvarchar(25))

How can I convert that to a date, and then calculate their age in years?

30条回答
  •  醉酒成梦
    2020-11-22 02:39

    EDIT: THIS ANSWER IS INCORRECT. I leave it in here as a warning to anyone tempted to use dayofyear, with a further edit at the end.


    If, like me, you do not want to divide by fractional days or risk rounding/leap year errors, I applaud @Bacon Bits comment in a post above https://stackoverflow.com/a/1572257/489865 where he says:

    If we're talking about human ages, you should calculate it the way humans calculate age. It has nothing to do with how fast the earth moves and everything to do with the calendar. Every time the same month and day elapses as the date of birth, you increment age by 1. This means the following is the most accurate because it mirrors what humans mean when they say "age".

    He then offers:

    DATEDIFF(yy, @date, GETDATE()) -
    CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE()))
    THEN 1 ELSE 0 END
    

    There are several suggestions here involving comparing the month & day (and some get it wrong, failing to allow for the OR as correctly here!). But nobody has offered dayofyear, which seems so simple and much shorter. I offer:

    DATEDIFF(year, @date, GETDATE()) -
    CASE WHEN DATEPART(dayofyear, @date) > DATEPART(dayofyear, GETDATE()) THEN 1 ELSE 0 END
    

    [Note: Nowhere in SQL BOL/MSDN is what DATEPART(dayofyear, ...) returns actually documented! I understand it to be a number in the range 1--366; most importantly, it does not change by locale as per DATEPART(weekday, ...) & SET DATEFIRST.]


    EDIT: Why dayofyear goes wrong: As user @AeroX has commented, if the birth/start date is after February in a non leap year, the age is incremented one day early when the current/end date is a leap year, e.g. '2015-05-26', '2016-05-25' gives an age of 1 when it should still be 0. Comparing the dayofyear in different years is clearly dangerous. So using MONTH() and DAY() is necessary after all.

提交回复
热议问题