Calculate Age Function

| | |

Two variations of the function but the purpose is to determine the difference in dates and display the result in one column.

IF OBJECT_ID(N'dbo.fnAge') IS NOT NULL
	DROP FUNCTION dbo.fnAge
GO

CREATE FUNCTION [dbo].[fnAge] (
	@dayOfBirth DATETIME
	,@today DATETIME
	)
RETURNS VARCHAR(100)
AS
BEGIN
	DECLARE @thisYearBirthDay DATETIME
	DECLARE @years INT
		,@months INT
		,@days INT

	SET @thisYearBirthDay = DATEADD(year, DATEDIFF(year, @dayOfBirth, @today), @dayOfBirth)
	SET @years = DATEDIFF(year, @dayOfBirth, @today) - (
			CASE
				WHEN @thisYearBirthDay > @today
					THEN 1
				ELSE 0
				END
			)
	SET @months = MONTH(@today - @thisYearBirthDay) - 1
	SET @days = DAY(@today - @thisYearBirthDay) - 1

	RETURN cast(@years AS VARCHAR(2)) + ' years,' + cast(@months AS VARCHAR(2)) + ' months,' + cast(@days AS VARCHAR(3)) + ' days'
END
SELECT dbo.fnAge('1981-09-01', GETDATE()) AS Age;

Result: 31 years,5 months,26 days

Detailed
Credit goes to armen at http://stackoverflow.com/users/395720/armen
While his response on this URL isn’t a function it is his code that makes the function work http://stackoverflow.com/questions/11184476/how-to-calculate-age-in-t-sql-with-years-months-days-hours-minutes-seconds

IF OBJECT_ID(N'dbo.fnAge') IS NOT NULL
	DROP FUNCTION dbo.fnAge
GO

CREATE FUNCTION [dbo].[fnAge] (
	@dateFrom DATETIME
	,@dateTo DATETIME
	,@datetimeoption INT
	,@displayoption INT
	)
RETURNS VARCHAR(max)
AS
BEGIN
	DECLARE @tmpdate DATETIME
	DECLARE @years INT
	DECLARE @months INT
	DECLARE @days INT
	DECLARE @hours INT
	DECLARE @minutes INT
	DECLARE @seconds INT
	DECLARE @milliseconds INT
	DECLARE @sign CHAR
	DECLARE @return VARCHAR(max)

	--SELECT @dateFrom    = '2012-02-03 11:24:38:000'
	--SELECT @dateTo      = '2013-03-04 12:25:39:003'
	SELECT @sign = '+'

	IF @dateFrom > @dateTo
	BEGIN
		SET @tmpdate = @dateFrom
		SET @dateFrom = @dateTo
		SET @dateTo = @tmpdate
		SET @sign = '-'
	END

	SELECT @tmpdate = @dateFrom

	SELECT @years = DATEDIFF(yy, @tmpdate, @dateTo) - CASE
			WHEN (DATEPART(mm, @dateFrom) > DATEPART(mm, @dateTo))
				OR (
					DATEPART(mm, @dateFrom) = DATEPART(mm, @dateTo)
					AND DATEPART(dd, @dateFrom) > DATEPART(dd, @dateTo)
					)
				OR (
					DATEPART(dd, @dateFrom) = DATEPART(dd, @dateTo)
					AND DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo)
					)
				OR (
					DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo)
					AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo)
					)
				OR (
					DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo)
					AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)
					)
				OR (
					DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo)
					AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)
					)
				THEN 1
			ELSE 0
			END

	SELECT @tmpdate = DATEADD(yy, @years, @tmpdate)

	SELECT @months = DATEDIFF(mm, @tmpdate, @dateTo) - CASE
			WHEN (DATEPART(dd, @dateFrom) > DATEPART(dd, @dateTo))
				OR (
					DATEPART(dd, @dateFrom) = DATEPART(dd, @dateTo)
					AND DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo)
					)
				OR (
					DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo)
					AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo)
					)
				OR (
					DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo)
					AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)
					)
				OR (
					DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo)
					AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)
					)
				THEN 1
			ELSE 0
			END

	SELECT @tmpdate = DATEADD(mm, @months, @tmpdate)

	SELECT @days = DATEDIFF(dd, @tmpdate, @dateTo) - CASE
			WHEN (DATEPART(hh, @dateFrom) > DATEPART(hh, @dateTo))
				OR (
					DATEPART(hh, @dateFrom) = DATEPART(hh, @dateTo)
					AND DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo)
					)
				OR (
					DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo)
					AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)
					)
				OR (
					DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo)
					AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)
					)
				THEN 1
			ELSE 0
			END

	SELECT @tmpdate = DATEADD(dd, @days, @tmpdate)

	SELECT @hours = DATEDIFF(hh, @tmpdate, @dateTo) - CASE
			WHEN (DATEPART(mi, @dateFrom) > DATEPART(mi, @dateTo))
				OR (
					DATEPART(mi, @dateFrom) = DATEPART(mi, @dateTo)
					AND DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo)
					)
				OR (
					DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo)
					AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)
					)
				THEN 1
			ELSE 0
			END

	SELECT @tmpdate = DATEADD(hh, @hours, @tmpdate)

	SELECT @minutes = DATEDIFF(mi, @tmpdate, @dateTo) - CASE
			WHEN (DATEPART(ss, @dateFrom) > DATEPART(ss, @dateTo))
				OR (
					DATEPART(ss, @dateFrom) = DATEPART(ss, @dateTo)
					AND DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo)
					)
				THEN 1
			ELSE 0
			END

	SELECT @tmpdate = DATEADD(mi, @minutes, @tmpdate)

	SELECT @seconds = DATEDIFF(ss, @tmpdate, @dateTo) - CASE
			WHEN (DATEPART(ms, @dateFrom) > DATEPART(ms, @dateTo))
				THEN 1
			ELSE 0
			END

	SELECT @tmpdate = DATEADD(ss, @seconds, @tmpdate)

	SELECT @milliseconds = DATEDIFF(ms, @tmpdate, @dateTo)

	--SELECT
	--    @sign AS [sign]
	--    , @years AS [years]
	--    , @months AS [months]
	--    , @days AS [days]
	--    , @hours AS [hours]
	--    , @minutes AS [minutes]
	--    , @seconds AS [seconds]
	--    , @milliseconds AS [milliseconds]
	SET @return = (
			CASE
				WHEN @datetimeoption = 0
					THEN (
							CASE
								WHEN @displayoption = 0
									THEN CONVERT(VARCHAR(12), @years) + ' Year(s), ' + CONVERT(VARCHAR(12), @months) + ' Month(s), ' + CONVERT(VARCHAR(12), @days) + ' Day(s)'
								WHEN @displayoption = 1
									THEN CONVERT(VARCHAR(12), @years) + 'y ' + CONVERT(VARCHAR(12), @months) + 'm ' + CONVERT(VARCHAR(12), @days) + 'd'
								END
							)
				WHEN @datetimeoption = 1
					THEN (
							CASE
								WHEN @displayoption = 0
									THEN CONVERT(VARCHAR(12), @years) + ' Year(s), ' + CONVERT(VARCHAR(12), @months) + ' Month(s), ' + CONVERT(VARCHAR(12), @days) + ' Day(s), ' + CONVERT(VARCHAR(12), @hours) + ' Hour(s), ' + CONVERT(VARCHAR(12), @minutes) + ' Minute(s), ' + CONVERT(VARCHAR(12), @seconds) + ' Second(s), ' + CONVERT(VARCHAR(12), @milliseconds) + ' Millisecond(s)'
								WHEN @displayoption = 1
									THEN CONVERT(VARCHAR(12), @years) + 'y ' + CONVERT(VARCHAR(12), @months) + 'm ' + CONVERT(VARCHAR(12), @days) + 'd ' + CONVERT(VARCHAR(12), @hours) + 'h ' + CONVERT(VARCHAR(12), @minutes) + 'm ' + CONVERT(VARCHAR(12), @seconds) + 's ' + CONVERT(VARCHAR(12), @milliseconds) + 'ms'
								END
							)
				END
			)

	RETURN @return
END;


SELECT dbo.fnAge('1981-09-01 15:20:00', getdate(), 0, 0);
-- Result: 33 Year(s), 3 Month(s), 9 Day(s)
SELECT dbo.fnAge('1981-09-01 15:20:00', getdate(), 0, 1);
-- Result: 33y 3m 9d
SELECT dbo.fnAge('1981-09-01 15:20:00', getdate(), 1, 0);
-- Result: 33 Year(s), 3 Month(s), 9 Day(s), 18 Hour(s), 34 Minute(s), 26 Second(s), 476 Millisecond(s)
SELECT dbo.fnAge('1981-09-01 15:20:00', getdate(), 1, 1);
-- Result: 33y 3m 9d 18h 34m 26s 476ms
Originally Posted on February 25, 2013
Last Updated on October 26, 2015
All information on this site is shared with the intention to help. Before any source code or program is ran on a production (non-development) system it is suggested you test it and fully understand what it is doing not just what it appears it is doing. I accept no responsibility for any damage you may do with this code.