2012-08-09 18 views
5

¿Hay una forma sencilla de calcular la diferencia entre dos fechas que:Diferencia de fecha (en años) incl. fracción años

  1. expresa como el número de años incl. la fracción del año; y
  2. tiene en cuenta los años bisiestos?

Por ejemplo, la diferencia entre el 1 de marzo de 2011 y el 1 de marzo de 2012 es de 1 año. Sin embargo, si uso DATEDIFF (day, .., ..) y lo divido por 365, obtengo una respuesta (no deseable) de 1.00274 debido al año bisiesto.

Para ser claro, necesito cualquier fracción de año también (es decir, no solo la cantidad total de años). Por ejemplo, la diferencia entre el 1 de marzo de 2011 y el 3 de marzo de 2012 es 1.005479 (1 año + 2/365 años). La diferencia entre el 1 de marzo de 2011 y el 29 de febrero de 2012 es 0.997268 (0 años + 365/366 años)

Por lo tanto, en resumen, la salida (en DECIMAL (7,6)) de los dos ejemplos anteriores sería:

1,000000 1,005479 0,997268

+0

¿Me puede decir qué es exactamente lo que quiere como salida en tu ejemplo anterior? – AnandPhadke

+0

Quizás esto podría ayudar: http://stackoverflow.com/questions/8882667/how-can-i-get-the-fraction-of-the-decimal-in-sql – Bridge

+3

Pero, ¿cómo se debe definir una "fracción de año" (no es un término bien conocido, que yo sepa) Según las fechas específicas, es posible que deba contabilizar un año con 366 días de duración en lugar de 365. Por ejemplo, ¿Cuál es el resultado esperado para la diferencia entre el 1 de marzo de 2011 y el 29 de febrero de 2012? –

Respuesta

0

Prueba de esto,

SELECT Cast(DateDiff(yyyy, '2011-03-01', '2012-03-01') As VARCHAR) + 'Yer : ' 
+ Cast(DateDiff(mm, '2011-03-01', '2012-03-01') As VARCHAR) + 'Mon : ' 
+ Cast(DateDiff(dd, '2011-03-01', '2012-03-01') As VARCHAR) + 'Dte' 

la esperanza que esto le ayuda, gracias.

+0

Gracias, pero no es lo que busco. Debería haber sido más explícito en mi publicación, que editaré. Quiero cualquier fracción de año así como la cantidad total de años. – PingPing

4

Aquí hay una consulta. Pero hay un error lógico en tu ejemplo. Creo que "la diferencia entre el 1 de marzo de 2011 y el 3 de marzo de 2012 es 1.005479 (1 año + 2/365 años)" debería ser (1 año + 2/366 años) porque el 29.02.2012 entre el 3 de marzo de 2011 y el 3 de marzo de 2012 en el último año 366 días.

Declare @BDate datetime 
    Declare @EDate datetime 
    SET @BDate='2011-03-01' 
    SET @EDate='2012-02-29' 

    select 

    datediff(year,@BDate,@Edate)- 
    case when dateadd(year,datediff(year,@BDate,@Edate),@BDate)>@Edate then 1 else 0 end 
    +cast(datediff(day,dateadd(year,datediff(year,@BDate,@Edate)- 
    case when dateadd(year,datediff(year,@BDate,@Edate),@BDate)>@Edate then 1 else 0 end ,@BDate),@Edate) as float)/ 
cast(datediff(day,dateadd(year,-1,@Edate),@Edate) as float) 
+0

Esto funciona la mayor parte del tiempo, pero falla en '2011-12-31' y '2012-01-01'. Me di cuenta de esto después de votaciones –

+0

Gracias. Sí, necesito repensar mi lógica. – PingPing

+0

@ t-clausen.dk He solucionado este problema con una nueva versión. – valex

3

creo que esto funciona (es de esperar que he recogido los nombres puede seguir):

declare @StartTime datetime 
declare @EndTime datetime 

select @StartTime = '20110301',@EndTime = '20120303' 

select YearsDiffNorm + ((DaysIntoYear * 1.0)/(DaysIntoYear + DaysRemainingInYear)) 
from (
select 
    YearsDiffNorm, 
    DATEDIFF(day,DATEADD(YEAR,YearsDiffNorm,@StartTime),@EndTime) as DaysIntoYear, 
    DATEDIFF(day,@EndTime,DATEADD(YEAR,YearsDiffNorm+1,@StartTime)) as DaysRemainingInYear 
from (
select CASE WHEN DATEADD(year,YearsDiff,@StartTime) > @EndTime then YearsDiff - 1 else YearsDiff END as YearsDiffNorm 
from (
    select DATEDIFF(year,@StartTime,@EndTime) as YearsDiff 
) t 
) t2 
) t3 
+0

+1 trabajado para las fechas que probé –

0

intente esto:

DECLARE @stdate datetime,@eddate datetime 
    SET @stdate='2007-02-01' 
    SET @eddate='2012-03-03' 

    ;WITH CTE as (
    select DATEDIFF(yy,@stdate,convert(datetime,cast(DATEPART(year,@eddate) as varchar)+'-'+cast(DATEPART(month,@stdate) as varchar)+'-'+cast(DATEPART(dd,@stdate) as varchar))) yrs, 
    DATEDIFF(dd,convert(datetime,cast(DATEPART(year,@eddate) as varchar)+'-'+cast(DATEPART(month,@stdate) as varchar)+'-'+cast(DATEPART(dd,@stdate) as varchar)),@eddate) as dayss, 
    CAST(CASE WHEN DATEPART(dd,DATEADD(mm,datediff(mm,-1,(convert(datetime,cast(DATEPART(year,@eddate) as varchar)+'-'+cast(DATEPART(month,@stdate) as varchar)+'-'+cast(DATEPART(dd,@stdate) as varchar)))),-1)) = 29 then 366 else 365 end as float) as ydays 
    ) 
    select yrs+dayss/cast(ydays as float) from CTE 
Cuestiones relacionadas