Esta noticia ha sido probado por nuestros especialistas así se garantiza la exactitud de este enunciado.
Solución:
Todos datediff()
lo que hace es calcular el número de límites de períodos cruzados entre dos fechas. Por ejemplo
datediff(yy,'31 Dec 2013','1 Jan 2014')
devuelve 1.
Obtendrá un resultado más preciso si calcula la diferencia entre las dos fechas en días y la divide por la duración media de un año calendario en días durante un período de 400 años (365,2425):
datediff(day,start-date,end-date,) / 365.2425
Por ejemplo,
select datediff(day,'1 Jan 2000' ,'18 April 2014') / 365.2425
devolver 14.29461248
— simplemente redondearlo a la precisión deseada.
¿Ha intentado obtener la diferencia en meses y luego calcular los años de esa manera? Por ejemplo 30 meses/12 serían 2,5 años.
Editar: esta consulta SQL contiene varios enfoques para calcular la diferencia de fecha:
SELECT CONVERT(date, GetDate() - 912) AS calcDate
,DATEDIFF(DAY, GetDate() - 912, GetDate()) diffDays
,DATEDIFF(DAY, GetDate() - 912, GetDate()) / 365.0 diffDaysCalc
,DATEDIFF(MONTH, GetDate() - 912, GetDate()) diffMonths
,DATEDIFF(MONTH, GetDate() - 912, GetDate()) / 12.0 diffMonthsCalc
,DATEDIFF(YEAR, GetDate() - 912, GetDate()) diffYears
Creo que la división por 365.2425 no es una buena manera de hacer esto. Ninguna división puede hacer esto con total precisión (usar 365.25 también tiene problemas).
Sé que el siguiente script calcula una diferencia de fecha precisa (aunque podría no ser la forma más rápida):
declare @d1 datetime ,@d2 datetime
--set your dates eg:
select @d1 = '1901-03-02'
select @d2 = '2016-03-01'
select DATEDIFF(yy, @d1, @d2) -
CASE WHEN MONTH(@d2) < MONTH(@d1) THEN 1
WHEN MONTH(@d2) > MONTH(@d1) THEN 0
WHEN DAY(@d2) < DAY(@d1) THEN 1
ELSE 0 END
-- = 114 years
Para comparacion:
select datediff(day,@d1 ,@d2) / 365.2425
-- = 115 years => wrong!
Es posible que pueda calcular rangos pequeños con la división, pero ¿por qué arriesgarse?
La siguiente secuencia de comandos puede ayudar a probar las funciones yeardiff (simplemente cambie cast(datediff(day,@d1,@d2) / 365.2425 as int) a cualquiera que sea la función):
declare @d1 datetime set @d1 = '1900-01-01'
while(@d1 < '2016-01-01')
begin
declare @d2 datetime set @d2 = '2016-04-01'
while(@d2 >= '1900-01-01')
begin
if (@d1 <= @d2 and dateadd(YEAR, cast(datediff(day,@d1,@d2) / 365.2425 as int) , @d1) > @d2)
begin
select 'not a year!!', @d1, @d2, cast(datediff(day,@d1,@d2) / 365.2425 as int)
end
set @d2 = dateadd(day,-1,@d2)
end
set @d1 = dateadd(day,1,@d1)
end