una persona meses fechas exacta entre edad dias como calcular años tsql datediff

tsql - persona - Cómo calcular la edad en T-SQL con años, meses y días



calcular meses entre dos fechas sql server (21)

¿Cuál sería la mejor manera de calcular la edad de alguien en años, meses y días en T-SQL (SQL Server 2000)?

La función de datediff no maneja bien los límites de los años, además de obtener meses y días separados será un oso. Sé que puedo hacerlo por el lado del cliente con relativa facilidad, pero me gustaría que se haga en mi procedimiento almacenado .


Implementado por aritmética con fecha de formato ISO.

declare @now date,@dob date, @now_i int,@dob_i int, @days_in_birth_month int declare @years int, @months int, @days int set @now = ''2013-02-28'' set @dob = ''2012-02-29'' -- Date of Birth set @now_i = convert(varchar(8),@now,112) -- iso formatted: 20130228 set @dob_i = convert(varchar(8),@dob,112) -- iso formatted: 20120229 set @years = ( @now_i - @dob_i)/10000 -- (20130228 - 20120229)/10000 = 0 years set @months =(1200 + (month(@now)- month(@dob))*100 + day(@now) - day(@dob))/100 %12 -- (1200 + 0228 - 0229)/100 % 12 = 11 months set @days_in_birth_month = day(dateadd(d,-1,left(convert(varchar(8),dateadd(m,1,@dob),112),6)+''01'')) set @days = (sign(day(@now) - day(@dob))+1)/2 * (day(@now) - day(@dob)) + (sign(day(@dob) - day(@now))+1)/2 * (@days_in_birth_month - day(@dob) + day(@now)) -- ( (-1+1)/2*(28 - 29) + (1+1)/2*(29 - 29 + 28)) -- Explain: if the days of now is bigger than the days of birth, then diff the two days -- else add the days of now and the distance from the date of birth to the end of the birth month select @years,@months,@days -- 0, 11, 28

Casos de prueba

El enfoque de los días es diferente de la respuesta aceptada, las diferencias que se muestran en los comentarios a continuación:

dob now years months days 2012-02-29 2013-02-28 0 11 28 --Days will be 30 if calculated by the approach in accepted answer. 2012-02-29 2016-02-28 3 11 28 --Days will be 31 if calculated by the approach in accepted answer, since the day of birth will be changed to 28 from 29 after dateadd by years. 2012-02-29 2016-03-31 4 1 2 2012-01-30 2016-02-29 4 0 30 2012-01-30 2016-03-01 4 1 2 --Days will be 1 if calculated by the approach in accepted answer, since the day of birth will be changed to 30 from 29 after dateadd by years. 2011-12-30 2016-02-29 4 1 30

Una versión corta de Days by case statement:

set @days = CASE WHEN day(@now) >= day(@dob) THEN day(@now) - day(@dob) ELSE @days_in_birth_month - day(@dob) + day(@now) END

Si desea la edad de años y meses solamente, podría ser más simple

set @years = ( @now_i/100 - @dob_i/100)/100 set @months =(12 + month(@now) - month(@dob))%12 select @years,@months -- 1, 0

NOTA: Un enlace muy útil de formatos de fecha de SQL Server


¿Estás tratando de calcular el total de días / meses / años de una edad? ¿tienes una fecha de inicio? ¿O está tratando de diseccionarlo (ej: 24 años, 1 mes, 29 días)?

Si tiene una fecha de inicio con la que está trabajando, datediff mostrará el total de días / meses / años con los siguientes comandos:

Select DateDiff(d,''1984-07-12'',''2008-09-11'') Select DateDiff(m,''1984-07-12'',''2008-09-11'') Select DateDiff(yyyy,''1984-07-12'',''2008-09-11'')

con las salidas respectivas (8827/290/24).

Ahora, si quisieras hacer el método de disección, tendrías que restar el número de años en días (días - 365 * años), y luego hacer más cálculos sobre eso para obtener los meses, etc.


Aquí está el código SQL que le da la cantidad de años, meses y días desde sysdate. Ingrese el valor para input_birth_date este formato (dd_mon_aa). nota: ingrese el mismo valor (fecha de nacimiento) por años, meses y días, como 01-mar-85

select trunc((sysdate -to_date(''&input_birth_date_dd_mon_yy''))/365) years, trunc(mod(( sysdate -to_date(''&input_birth_date_dd_mon_yy''))/365,1)*12) months, trunc((mod((mod((sysdate -to_date(''&input_birth_date_dd_mon_yy''))/365,1)*12),1)*30)+1) days from dual


Aquí hay algunos T-SQL que le dan la cantidad de años, meses y días desde el día especificado en @date. Tiene en cuenta el hecho de que DATEDIFF () calcula la diferencia sin considerar qué mes o día es (por lo que el mes difiere entre 8/31 y 9/1 es 1 mes) y maneja eso con una declaración de caso que disminuye el resultado donde apropiado.

DECLARE @date datetime, @tmpdate datetime, @years int, @months int, @days int SELECT @date = ''2/29/04'' SELECT @tmpdate = @date SELECT @years = DATEDIFF(yy, @tmpdate, GETDATE()) - CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END SELECT @tmpdate = DATEADD(yy, @years, @tmpdate) SELECT @months = DATEDIFF(m, @tmpdate, GETDATE()) - CASE WHEN DAY(@date) > DAY(GETDATE()) THEN 1 ELSE 0 END SELECT @tmpdate = DATEADD(m, @months, @tmpdate) SELECT @days = DATEDIFF(d, @tmpdate, GETDATE()) SELECT @years, @months, @days


Aquí hay una versión (un poco) más simple:

CREATE PROCEDURE dbo.CalculateAge @dayOfBirth datetime AS DECLARE @today datetime, @thisYearBirthDay datetime DECLARE @years int, @months int, @days int SELECT @today = GETDATE() SELECT @thisYearBirthDay = DATEADD(year, DATEDIFF(year, @dayOfBirth, @today), @dayOfBirth) SELECT @years = DATEDIFF(year, @dayOfBirth, @today) - (CASE WHEN @thisYearBirthDay > @today THEN 1 ELSE 0 END) SELECT @months = MONTH(@today - @thisYearBirthDay) - 1 SELECT @days = DAY(@today - @thisYearBirthDay) - 1 SELECT @years, @months, @days GO


Así es como calculo la edad dada una fecha de nacimiento y la fecha actual.

select case when cast(getdate() as date) = cast(dateadd(year, (datediff(year, ''1996-09-09'', getdate())), ''1996-09-09'') as date) then dateDiff(yyyy,''1996-09-09'',dateadd(year, 0, getdate())) else dateDiff(yyyy,''1996-09-09'',dateadd(year, -1, getdate())) end as MemberAge go


El mismo tipo de cosa que una función.

create function [dbo].[Age](@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


Hay una manera fácil, basada en las horas entre los dos días, PERO con la fecha de finalización truncada.

SELECT CAST(DATEDIFF(hour,Birthdate,CAST(GETDATE() as Date))/8766.0 as INT) AS Age FROM <YourTable>

Este ha demostrado ser extremadamente preciso y confiable. Si no fuera por el CAST interno en el GETDATE (), podría voltear el cumpleaños unas horas antes de la medianoche pero, con el CAST, está muerto con el cambio de edad exactamente a la medianoche.


He visto la pregunta varias veces con resultados que arrojan resultados de años, meses, días pero nunca un resultado numérico / decimal. (Al menos no uno que no se redondea incorrectamente). Agradezco los comentarios sobre esta función. Puede que aún no necesite un poco de ajuste.

- La entrada a la función es de dos fechas. - Salida es el número numérico de años entre las dos fechas en formato decimal (7,4). - La salida siempre es siempre un número positivo.

- NOTA: La salida no se maneja si la diferencia es mayor que 999.9999

- La lógica se basa en tres pasos. - 1) Es la diferencia de menos de 1 año (0.5000, 0.3333, 0.6667, etc.) - 2) Es la diferencia exactamente un número entero de años (1,2,3, etc.)

- 3) (Else) ... La diferencia es años y algunos días. (1.5000, 2.3333, 7.6667, etc.)

CREATE Function [dbo].[F_Get_Actual_Age](@pi_date1 datetime,@pi_date2 datetime) RETURNS Numeric(7,4) AS BEGIN Declare @l_tmp_date DATETIME ,@l_days1 DECIMAL(9,6) ,@l_days2 DECIMAL(9,6) ,@l_result DECIMAL(10,6) ,@l_years DECIMAL(7,4) --Check to make sure there is a date for both inputs IF @pi_date1 IS NOT NULL and @pi_date2 IS NOT NULL BEGIN IF @pi_date1 > @pi_date2 --Make sure the "older" date is in @pi_date1 BEGIN SET @l_tmp_date = @pi_date2 SET @pi_date2 = @Pi_date1 SET @pi_date1 = @l_tmp_date END --Check #1 If date1 + 1 year is greater than date2, difference must be less than 1 year IF DATEADD(YYYY,1,@pi_date1) > @pi_date2 BEGIN --How many days between the two dates (numerator) SET @l_days1 = DATEDIFF(dd,@pi_date1, @pi_date2) --subtract 1 year from date2 and calculate days bewteen it and date2 --This is to get the denominator and accounts for leap year (365 or 366 days) SET @l_days2 = DATEDIFF(dd,dateadd(yyyy,-1,@pi_date2),@pi_date2) SET @l_years = @l_days1 / @l_days2 -- Do the math END ELSE --Check #2 Are the dates an exact number of years apart. --Calculate years bewteen date1 and date2, then add the years to date1, compare dates to see if exactly the same. IF DATEADD(YYYY,DATEDIFF(YYYY,@pi_date1,@pi_date2),@pi_date1) = @pi_date2 SET @l_years = DATEDIFF(YYYY,@pi_date1, @pi_date2) --AS Years, ''Exactly even Years'' AS Msg ELSE BEGIN --Check #3 The rest of the cases. --Check if datediff, returning years, over or under states the years difference SET @l_years = DATEDIFF(YYYY,@pi_date1, @pi_date2) IF DATEADD(YYYY,@l_years,@pi_date1) > @pi_date2 SET @l_years = @l_years -1 --use basicly same logic as in check #1 SET @l_days1 = DATEDIFF(dd,DATEADD(YYYY,@l_years,@pi_date1), @pi_date2) SET @l_days2 = DATEDIFF(dd,dateadd(yyyy,-1,@pi_date2),@pi_date2) SET @l_years = @l_years + @l_days1 / @l_days2 --SELECT @l_years AS Years, ''Years Plus'' AS Msg END END ELSE SET @l_years = 0 --If either date was null RETURN @l_Years --Return the result as decimal(7,4) END

`


Muy vieja pregunta, pero quiero compartir lo que he hecho para calcular la edad

Declare @BirthDate As DateTime Set @BirthDate = ''1994-11-02'' SELECT DATEDIFF(YEAR,@BirthDate,GETDATE()) - (CASE WHEN MONTH(@BirthDate)> MONTH(GETDATE()) THEN 1 WHEN MONTH(@BirthDate)= MONTH(GETDATE()) AND DAY(@BirthDate) > DAY(GETDATE()) THEN 1 Else 0 END)


Para los que quieren crear una columna calculada en una tabla para almacenar la edad:

CASE WHEN DateOfBirth< DATEADD(YEAR, (DATEPART(YEAR, GETDATE()) - DATEPART(YEAR, DateOfBirth))*-1, GETDATE()) THEN DATEPART(YEAR, GETDATE()) - DATEPART(YEAR, DateOfBirth) ELSE DATEPART(YEAR, GETDATE()) - DATEPART(YEAR, DateOfBirth) -1 END


Prueba esto...

SELECT CASE WHEN (DATEADD(year,DATEDIFF(year, @datestart ,@dateend) , @datestart) > @dateend) THEN DATEDIFF(year, @datestart ,@dateend) -1 ELSE DATEDIFF(year, @datestart ,@dateend) END

Básicamente, el "DateDiff (año ...") te da la edad que la persona cumplirá este año, así que acabo de agregar un enunciado de caso para decir, si aún no han celebrado un cumpleaños este año, luego restar 1 año, sino devuelve el valor


Una manera simple de obtener la edad como texto es la siguiente:

Select cast((DATEDIFF(m, date_of_birth, GETDATE())/12) as varchar) + '' Y & '' + cast((DATEDIFF(m, date_of_birth, GETDATE())%12) as varchar) + '' M'' as Age

El formato de resultados será:

**63 Y & 2 M**


DateTime valores de DateTime en T-SQL se almacenan como flotantes. Puede restar las fechas entre sí y ahora tiene una nueva fecha que es el intervalo de tiempo entre ellas.

declare @birthdate datetime set @birthdate = ''6/15/1974'' --age in years - short version print year(getdate() - @birthdate) - year(0) --age in years - visualization declare @mindate datetime declare @span datetime set @mindate = 0 set @span = getdate() - @birthdate print @mindate print @birthdate print getdate() print @span --substract minyear from spanyear to get age in years print year(@span) - year(@mindate) print month(@span) print day(@span)


CREATE FUNCTION DBO.GET_AGE ( @DATE AS DATETIME ) RETURNS VARCHAR(MAX) AS BEGIN DECLARE @YEAR AS VARCHAR(50) = '''' DECLARE @MONTH AS VARCHAR(50) = '''' DECLARE @DAYS AS VARCHAR(50) = '''' DECLARE @RESULT AS VARCHAR(MAX) = '''' SET @YEAR = CONVERT(VARCHAR,(SELECT DATEDIFF(MONTH,CASE WHEN DAY(@DATE) > DAY(GETDATE()) THEN DATEADD(MONTH,1,@DATE) ELSE @DATE END,GETDATE()) / 12 )) SET @MONTH = CONVERT(VARCHAR,(SELECT DATEDIFF(MONTH,CASE WHEN DAY(@DATE) > DAY(GETDATE()) THEN DATEADD(MONTH,1,@DATE) ELSE @DATE END,GETDATE()) % 12 )) SET @DAYS = DATEDIFF(DD,DATEADD(MM,CONVERT(INT,CONVERT(INT,@YEAR)*12 + CONVERT(INT,@MONTH)),@DATE),GETDATE()) SET @RESULT = (RIGHT(''00'' + @YEAR, 2) + '' YEARS '' + RIGHT(''00'' + @MONTH, 2) + '' MONTHS '' + RIGHT(''00'' + @DAYS, 2) + '' DAYS'') RETURN @RESULT END SELECT DBO.GET_AGE(''04/12/1986'')


DECLARE @BirthDate datetime, @AgeInMonths int SET @BirthDate = ''10/5/1971'' SET @AgeInMonths -- Determine the age in "months old": = DATEDIFF(MONTH, @BirthDate, GETDATE()) -- .Get the difference in months - CASE WHEN DATEPART(DAY,GETDATE()) -- .If today was the 1st to 4th, < DATEPART(DAY,@BirthDate) -- (or before the birth day of month) THEN 1 ELSE 0 END -- ... don''t count the month. SELECT @AgeInMonths / 12 as AgeYrs -- Divide by 12 months to get the age in years ,@AgeInMonths % 12 as AgeXtraMonths -- Get the remainder of dividing by 12 months = extra months ,DATEDIFF(DAY -- For the extra days, find the difference between, ,DATEADD(MONTH, @AgeInMonths -- 1. Last Monthly Birthday , @BirthDate) -- (if birthdays were celebrated monthly) ,GETDATE()) as AgeXtraDays -- 2. Today''s date.


DECLARE @DoB AS DATE = ''1968-10-24'' DECLARE @cDate AS DATE = CAST(''2000-10-23'' AS DATE) SELECT --Get Year difference DATEDIFF(YEAR,@DoB,@cDate) - --Cases where year difference will be augmented CASE --If Date of Birth greater than date passed return 0 WHEN YEAR(@DoB) - YEAR(@cDate) >= 0 THEN DATEDIFF(YEAR,@DoB,@cDate) --If date of birth month less than date passed subtract one year WHEN MONTH(@DoB) - MONTH(@cDate) > 0 THEN 1 --If date of birth day less than date passed subtract one year WHEN MONTH(@DoB) - MONTH(@cDate) = 0 AND DAY(@DoB) - DAY(@cDate) > 0 THEN 1 --All cases passed subtract zero ELSE 0 END


SELECT DOB AS Birthdate , YEAR(GETDATE()) AS ThisYear, YEAR(getdate()) - YEAR(DOB) AS Age FROM tableprincejain


create procedure getDatedifference ( @startdate datetime, @enddate datetime ) as begin declare @monthToShow int declare @dayToShow int --set @startdate=''01/21/1934'' --set @enddate=getdate() if (DAY(@startdate) > DAY(@enddate)) begin set @dayToShow=0 if (month(@startdate) > month(@enddate)) begin set @monthToShow= (12-month(@startdate)+ month(@enddate)-1) end else if (month(@startdate) < month(@enddate)) begin set @monthToShow= ((month(@enddate)-month(@startdate))-1) end else begin set @monthToShow= 11 end -- set @monthToShow= convert(int, DATEDIFF(mm,0,DATEADD(dd,DATEDIFF(dd,0,@enddate)- DATEDIFF(dd,0,@startdate),0)))-((convert(int,FLOOR(DATEDIFF(day, @startdate, @enddate) / 365.25))*12))-1 if(@monthToShow<0) begin set @monthToShow=0 end declare @amonthbefore integer set @amonthbefore=Month(@enddate)-1 if(@amonthbefore=0) begin set @amonthbefore=12 end if (@amonthbefore in(1,3,5,7,8,10,12)) begin set @dayToShow=31-DAY(@startdate)+DAY(@enddate) end if (@amonthbefore=2) begin IF (YEAR( @enddate ) % 4 = 0 AND YEAR( @enddate ) % 100 != 0) OR YEAR( @enddate ) % 400 = 0 begin set @dayToShow=29-DAY(@startdate)+DAY(@enddate) end else begin set @dayToShow=28-DAY(@startdate)+DAY(@enddate) end end if (@amonthbefore in (4,6,9,11)) begin set @dayToShow=30-DAY(@startdate)+DAY(@enddate) end end else begin --set @monthToShow=convert(int, DATEDIFF(mm,0,DATEADD(dd,DATEDIFF(dd,0,@enddate)- DATEDIFF(dd,0,@startdate),0)))-((convert(int,FLOOR(DATEDIFF(day, @startdate, @enddate) / 365.25))*12)) if (month(@enddate)< month(@startdate)) begin set @monthToShow=12+(month(@enddate)-month(@startdate)) end else begin set @monthToShow= (month(@enddate)-month(@startdate)) end set @dayToShow=DAY(@enddate)-DAY(@startdate) end SELECT FLOOR(DATEDIFF(day, @startdate, @enddate) / 365.25) as [yearToShow], @monthToShow as monthToShow ,@dayToShow as dayToShow , convert(varchar,FLOOR(DATEDIFF(day, @startdate, @enddate) / 365.25)) +'' Year '' + convert(varchar,@monthToShow) +'' months ''+convert(varchar,@dayToShow)+'' days '' as age return end


declare @StartDate datetime = ''2016-01-31'' declare @EndDate datetime = ''2016-02-01'' SELECT @StartDate AS [StartDate] ,@EndDate AS [EndDate] ,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END AS [Years] ,DATEDIFF(Month,(DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate)),@EndDate) - CASE WHEN DATEADD(Month, DATEDIFF(Month,DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate),@EndDate) , @StartDate) > @EndDate THEN 1 ELSE 0 END AS [Months] ,DATEDIFF(Day, DATEADD(Month,DATEDIFF(Month, (DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate)),@EndDate) - CASE WHEN DATEADD(Month, DATEDIFF(Month,DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate),@EndDate) , @StartDate) > @EndDate THEN 1 ELSE 0 END ,DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate)) ,@EndDate) - CASE WHEN DATEADD(Day,DATEDIFF(Day, DATEADD(Month,DATEDIFF(Month, (DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate)),@EndDate) - CASE WHEN DATEADD(Month, DATEDIFF(Month,DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate),@EndDate) , @StartDate) > @EndDate THEN 1 ELSE 0 END ,DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate)) ,@EndDate),DATEADD(Month,DATEDIFF(Month, (DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate)),@EndDate) - CASE WHEN DATEADD(Month, DATEDIFF(Month,DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate),@EndDate) , @StartDate) > @EndDate THEN 1 ELSE 0 END ,DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate) - CASE WHEN DATEADD(Year,DATEDIFF(Year,@StartDate,@EndDate), @StartDate) > @EndDate THEN 1 ELSE 0 END,@StartDate))) > @EndDate THEN 1 ELSE 0 END AS [Days]


select DOB as Birthdate, YEAR(GETDATE()) as ThisYear, YEAR(getdate()) - EAR(date1) as Age from TableName