2012-08-09 12 views
5

C'è un modo semplice per calcolare la differenza tra due date che:Differenza di data (in anni) incl. frazione anno

  1. esprime come il numero di anni incl. la frazione dell'anno; e
  2. tiene conto degli anni bisestili?

Ad esempio, la differenza tra 1 marzo 2011 e 1 marzo 2012 è di 1 anno. Tuttavia, se uso DATEDIFF (giorno, .., ..) e dividi per 365 ottengo una risposta (indesiderata) di 1.00274 a causa dell'anno bisestile.

Per essere chiari, ho bisogno anche di una frazione dell'anno (cioè non solo il numero intero di anni). Ad esempio, la differenza tra 1 marzo 2011 e 3 marzo 2012 è 1.005479 (1 anno + 2/365 anni). La differenza tra 1 marzo 2011 e 29 febbraio 2012 è 0.997268 (0 anno + 365/366 anni)

Quindi, in sintesi, l'output (in DECIMAL (7,6)) dai due esempi precedenti potrebbe essere:

1,000000 1,005479 0,997268

+0

La prego di dirmi che cosa esattamente si vuole come output nel tuo esempio sopra? – AnandPhadke

+0

Forse questo potrebbe aiutare: http://stackoverflow.com/questions/8882667/how-can-i-get-the-fraction-of-the-decimal-in-sql – Bridge

+3

Ma come deve essere definita una "frazione dell'anno" (non è un termine ben noto, per quanto ne so)? In base alle date specifiche, potrebbe essere necessario considerare un anno di 366 giorni anziché 365. Es. qual è l'output atteso per la differenza tra il 1 marzo 2011 e il 29 febbraio 2012? –

risposta

0

Prova questo,

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' 

Spero che questo ti aiuta, grazie.

+0

Grazie ma non è proprio quello che sto cercando. Avrei dovuto essere più esplicito nel mio post, che modificherò. Voglio qualsiasi frazione dell'anno così come il numero intero di anni. – PingPing

4

Ecco una query. Ma c'è un errore logico nel tuo esempio. Penso che "la differenza tra 1 marzo 2011 e 3 marzo 2012 è 1.005479 (1 anno + 2/365 anni)" dovrebbe essere (1 anno + 2/366 anni) perché il 29.02.2012 tra il 3 marzo 2011 e il 3 marzo 2012, quindi in l'anno scorso 366 giorni.

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

Questo funziona la maggior parte del tempo, ma non riesce su '2011-12-31' e '2012-01-01'. L'ho notato dopo aver mandato a monte –

+0

Grazie. Sì, ho bisogno di ripensare alla mia logica. – PingPing

+0

@ t-clausen.dk Ho risolto questo problema, provare la nuova versione. – valex

3

penso che questo funziona (ho preso spera nomi si possono seguire):

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 ha funzionato per le date che ho testato –

0

provare questo:

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