2012-08-09 12 views
5

Czy istnieje prosty sposób obliczyć różnicę pomiędzy dwoma datami, że:Różnica daty (w latach) wł. roku frakcja

  1. wyraża się jako liczbę lat włącznie. ułamek roku; i
  2. bierze pod uwagę lata przestępne?

Na przykład różnica między 1 marca 2011 r. A 1 marca 2012 r. Wynosi 1 rok. Jednakże, jeśli używam DATEDIFF (dzień, .., ..) i dzielę przez 365 otrzymuję (niepożądaną) odpowiedź 1,00274 z powodu roku przestępnego.

Żeby było jasne, potrzebuję także frakcji każdego roku (tj. Nie tylko całej liczby lat). Na przykład różnica między 1 marca 2011 r. A 3 marca 2012 r. Wynosi 1,005479 (1 rok + 2/365 lat). Różnica między 1 marca 2011 r. A 29 lutego 2012 r. Wynosi 0,997268 (0 rok + 365/366 lat)

Podsumowując, wynik (w DECIMAL (7,6)) z powyższych dwóch przykładów byłby następujący:

1,000000 1,005479 0,997268

+0

mógłbyś mi powiedzieć, co dokładnie chcesz jako wyjście w powyższym przykładzie? – AnandPhadke

+0

Być może to może pomóc: http://stackoverflow.com/questions/8882667/how-can-i-get-faction-of-the-decimal-in-sql – Bridge

+3

Ale jak zdefiniować "ułamek roku" (to nie jest dobrze znany termin, o ile mi wiadomo)? W zależności od konkretnych dat może zaistnieć potrzeba, aby rok wynosił 366 dni zamiast 365 dni. jaki jest przewidywany wynik dla różnicy między 1 marca 2011 r. a 29 lutego 2012 r.? –

Odpowiedz

0

Spróbuj tego,

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' 

Nadzieja to pomaga, dziękuję.

+0

Dzięki, ale nie do końca jestem tym, za czym jestem. Powinienem być bardziej konkretny w moim poście, który będę edytować. Chcę mieć ułamek roku i całą liczbę lat. – PingPing

4

Oto zapytanie. Ale w twoim przykładzie jest błąd logiczny. Myślę, że "różnica między 1 marca 2011 r. A 3 marca 2012 r. Wynosi 1.005479 (1 rok + 2/365 lat)" powinno być (1 rok + 2/366 lat), ponieważ 29.02.2012 między 3 marca 2011 r. A 3 marca 2012 r. ostatni rok 366 dni.

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

Działa to przez większość czasu, ale kończy się niepowodzeniem w dniu "2011-12-31" i "2012-01-01". Zauważyłem to po przegrywaniu –

+0

Dzięki. Tak, muszę ponownie przemyśleć moją logikę. – PingPing

+0

@ t-clausen.dk Naprawiłem ten problem, wypróbować nową wersję. – valex

3

myślę, że to działa (ja mam nadzieję, że wybrał nazwy można śledzić):

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 pracował dla dat, które testowałem –

0

spróbuj tego:

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