Hi Nic,
Here's a function that returns the age based on given @birth_date and
@event_date values.
* For simplification, I'm assuming that the inputs contain midnight in the
time portion. If you need to support non-midnight time portion, make sure
you first set the time portion to midnight.
For example, to set the time portion of @event_date to midnight use:
DATEADD(day, DATEDIFF(day, 0, @event_date), 0)
* I'm assuming that if the date of birth is Feb 29 in a leap year, and the
event date is in a non-leap year, the birth day date in the event year is
Mar 1.
See if the following works for you (explanations below):
CREATE FUNCTION dbo.fn_age
(@birth_date AS DATETIME, @event_date AS DATETIME)
RETURNS INT
AS
BEGIN
RETURN
( SELECT diff -
CASE
WHEN fix_bd_cur > @event_date THEN 1
ELSE 0
END AS age
FROM
( SELECT
diff,
bd_cur +
CASE
WHEN DAY(@birth_date) = 29 AND DAY(bd_cur) = 28 THEN 1
ELSE 0
END AS fix_bd_cur
FROM
( SELECT
diff,
DATEADD(year, diff, @birth_date) AS bd_cur
FROM
( SELECT DATEDIFF(year, @birth_date, @event_date) AS diff
) AS D1
) AS D2
) AS D3
)
END
GO
-- Test
SELECT
birth_date, event_date,
dbo.fn_age(birth_date, event_date) AS age
FROM (SELECT
CAST('20050212' AS DATETIME) AS birth_date,
CAST('20060211' AS DATETIME) AS event_date
UNION ALL SELECT '20050212', '20060212'
UNION ALL SELECT '20040229', '20060228'
UNION ALL SELECT '20040229', '20060301'
UNION ALL SELECT '20040229', '20080228'
UNION ALL SELECT '20040229', '20080229') AS D;
birth_date event_date age
----------------------- ----------------------- -----------
2005-02-12 00:00:00.000 2006-02-11 00:00:00.000 0
2005-02-12 00:00:00.000 2006-02-12 00:00:00.000 1
2004-02-29 00:00:00.000 2006-02-28 00:00:00.000 1
2004-02-29 00:00:00.000 2006-03-01 00:00:00.000 2
2004-02-29 00:00:00.000 2008-02-28 00:00:00.000 3
2004-02-29 00:00:00.000 2008-02-29 00:00:00.000 4
* The innermost derived table D1 calculates [diff], which is the difference
in years between @birth_date and @event_date.
* The derived table D2 calculates [bd_cur], which is @birth_date + [diff]
years. That is, [bd_cur] is the birth day date in the event year, relying on
the DATEADD function's treatment of leap years.
If you use DATEADD to add n years to a Feb 29 date, and the target year is a
leap year, you get Feb 29 in the target year. However, if the target year is
a non leap year, you get Feb 28 in the target year. The latter needs special
treatment, and is handled in the derived table D3.
* The derived table D3 "fixes" [bd_cur] by adding 1 day in the special case
where @birth_date has Feb 29 and the target year is a non leap year. In such
a case, [fix_bd_cur] becomes Mar 1.
* The outermost query returns [diff] as the age if [fix_bd_cur] <=
@birth_date, and [diff] - 1 year if [fix_bd_cur] > @birth_date.
Let me know if you have any questions.
--
BG, SQL Server MVP
www.SolidQualityLearning.com www.insidetsql.com Anything written in this message represents my view, my own view, and
nothing but my view (WITH SCHEMABINDING), so help me my T-SQL code.
[quoted text, click to view] "Niclas" <lindblom_niclas@hotmail.com> wrote in message
news:eZ2TS%23tkGHA.1936@TK2MSFTNGP04.phx.gbl...
> Hi,
>
> I have a 'date of birth' of a person and a date of an event and need to
> calculate the persons age at that event (both datetime format). Is there a
> function available I can use for this ?
>
> Any advice appreciated
>
> Nic
>