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?
Here is a technique which seems to work around the edge cases: the end of the year and leap Februaries.
The problem with datediff(year,…,…)
is that it only finds the difference between the years, and not the actual dates, which is a bit naïve in my opinion. This is only reliable if the date of birth is 1st Jan.
The solution is to time warp the date of birth to the first of January, and the asking date by the same amount.
Because of the leap year problem using the day of year is also unreliable, so I use the month and day to do the time warp:
CREATE FUNCTION age(@then AS date,@now AS date) RETURNS int AS
BEGIN
DECLARE @month INT = month(@then)-1;
DECLARE @day INT = day(@then)-1;
SET @then=dateadd(month,-@month,@then);
SET @then=dateadd(day,-@day,@then);
SET @now=dateadd(month,-@month,@now;)
SET @now=dateadd(day,-@day,@now);
RETURN datediff(year,@then,@now);
END;
You can write this more compactly, of course. You can even write it in one line, if that’s your idea of having a good time:
CREATE FUNCTION age(@then AS date,@now AS date) RETURNS int AS
BEGIN
RETURN datediff(
year,
dateadd(day,-day(@then)+1,dateadd(month,-month(@then)+1,@then)),
dateadd(day,-day(@then)+1,dateadd(month,-month(@then)+1,@now))
);
END;
but that’s only showing off, and it’s less efficient as it needs to recalculate the offsets.