2014-08-29 4 views
0

У меня проблема с функцией DATEDIFF.(Transact-SQL) DATEDIFIF и високосные годы

Мой формат даты: dd/mm/yyyy.

@START_DATE = 01/02/2004
@END_DATE = 29/01/2014

Запрос (DATEDIFF(DAY,@START_DATE,@END_DATE)/365) возвращение 10, но количество правильных лет 9. Это происходит потому, что мой запрос не учитывает високосные годы.


Что я могу сделать, чтобы сохранить точный счет? Спасибо.

+1

Есть ближе к 365,25 дней в году, так что вы не должны ожидать, что ваша арифметика чтобы быть правильным. –

ответ

0

Я считаю, что следующая логика делает то, что вы хотите:

datediff(year, 
      @START_DATE - datepart(dayofyear, @START_DATE) + 1, 
      @END_DATE - datepart(dayofyear, @START_DATE) + 1 
      ) as d2 

Примечание: Это относится, что даты как datetime, потому что арифметика проще выразить. Вы также можете написать это как:

datediff(year, 
      dateadd(day, - datepart(dayofyear, @START_DATE) + 1, @START_DATE), 
      dateadd(day, - datepart(dayofyear, @START_DATE) + 1, @END_DATE) 
      ) as d2 

Следующий запрос является демонстрация:

select datediff(year, 
       startdate - datepart(dayofyear, startdate) + 1, 
       enddate - datepart(dayofyear, startdate) + 1 
       ) as d2 
from (select cast('2004-02-01' as datetime) as startdate, 
      cast('2014-01-31' as datetime) as enddate 
     union all 
     select cast('2004-02-01' as datetime) as startdate, 
      cast('2014-02-01' as datetime) as enddate 

    ) t 
+0

Это работает! : D Но у меня есть один вопрос: зачем добавлять +1? – Andryx93

+0

@ Andryx93. , , 2014-01-05 - пятый день года. Если вы вычтите 5, вы получите 2013-12-31. Идея заключается в нормализации дат к началу года для сравнения. –

+0

Большое вам спасибо! – Andryx93

1

Вы можете создать функцию для решения, что:

CREATE FUNCTION [dbo].[getYears] 
(
    @START_DATE datetime, 
    @END_DATE datetime 
) 
RETURNS int 
AS 
BEGIN 
    DECLARE @yrs int 
    SET @yrs =DATEDIFF(year,@START_DATE,@END_DATE) 
    IF (@END_DATE < DATEADD(year, @yrs, @START_DATE)) 
     SET @yrs = @yrs -1 
    RETURN @yrs 
END 

Также проверьте this

1

Технически было бы 365,242 дней в году, когда приходится високосные годы так:

FLOOR(DATEDIFF(day, @STARTDATE, @ENDDATE)/365.242) 

Должно быть верным.

Тест:

SELECT FLOOR(DATEDIFF(day, '1980-01-16','2015-01-15')/365.242), 
     FLOOR(DATEDIFF(day, '1980-01-16','2015-01-16')/365.242) 

ResultSet:

Ура!

0

Подсчитайте количество високосных дней в end_date. Выведите количество високосных дней в start_date. Вычитайте ответ из вашего DIFIFIFF.

DECLARE 
    @START_DATE DATETIME = '2004-02-01', 
    @END_DATE DATETIME = '2014-01-29' 

SELECT (
     DATEDIFF(DAY,@START_DATE,@END_DATE) 
      - (
       (CONVERT(INT,@END_DATE - 58)/1461) 
       - 
       (CONVERT(INT,@START_DATE - 58)/1461) 
      ) 
     )/365 

-58 игнорировать январе и феврале 1900

/1461 является число дней между високосных

Смежные вопросы