2009-07-10 11 views

Respuesta

5

averiguar la distancia entre dos fechas utilizando DateDiff, y luego dividir ese valor por 365

EDITAR

Se podría, por supuesto, crear su propia función para hacer el trabajo:

create function yearfrac (@d1 datetime, @d2 datetime) returns float 
as 
begin 
return abs(datediff(d, @d1, @d2))/365.00 
end 
+2

que no se corresponde con el comportamiento por defecto de la función YEARFRAC. .. – Guffa

+0

@Guffa - buena llamada, no había notado la diferencia. –

+0

, lo tienes, guffa, me lo perdí. en su versión, sin embargo, tendría que hacer algo como mi solución * 365.00 * arriba, para forzar a la división a trabajar con decimales, de lo contrario siempre terminará con 0. –

3

Para el uso predeterminado (dos parámetros de datos):

datediff(day, date1, date2)/360.0 

Para el caso especial en el que el tercer parámetro tiene el valor 3:

datediff(day, date1, date2)/365.0 

Editar:
añadido un decimal para que sea una operación de punto flotante.

+0

fyi, esto trunca el valor de retorno. –

-3

Sé que esto es un poco tarde de una respuesta, pero sólo en caso de que alguien se tropieza demás sobre esto aquí es lo que he hecho:

CREATE FUNCTION dbo.udfYearFrac 
(
    @StartDate AS DATETIME, 
    @EndDate AS DATETIME 
) 
RETURNS DECIMAL(18,6) 
AS 
BEGIN 
    DECLARE @YearFrac  AS DECIMAL(18,6) 
    DECLARE @nbDaysInPeriod AS INT 
    DECLARE @nbYears  AS INT 

    SELECT 
     @nbDaysInPeriod = DATEDIFF(DAY, @StartDate, @EndDate) 
     ,@nbYears = YEAR(@EndDate) - YEAR(@StartDate) + 1 

    SELECT @YearFrac = @nbDaysInPeriod/
     CASE WHEN YEAR(@StartDate) = YEAR(@EndDate) OR (YEAR(@EndDate)-1 = YEAR(@StartDate) AND (MONTH(@StartDate) > MONTH(@EndDate) OR MONTH(@StartDate) = MONTH(@EndDate) AND (DAY(@StartDate) >= DAY(@EndDate)))) 
     THEN 
      CASE WHEN YEAR(@StartDate) = YEAR(@EndDate) AND ISDATE(CAST(YEAR(@StartDate) AS CHAR(4)) + '0229') = 1 
      THEN 366.0 
      ELSE 
       CASE WHEN DAY(@EndDate) = 29 AND MONTH(@EndDate) = 2 
       THEN 366.0 
       ELSE 
        CASE WHEN ISDATE(CAST(YEAR(@StartDate) AS CHAR(4)) + '0229') = 1 
        THEN 
         CASE WHEN (@StartDate <= cast('2/29/' + cast(YEAR(@StartDate) AS CHAR(4)) AS DATETIME) AND cast('2/29/' + cast(YEAR(@StartDate) AS CHAR(4)) AS DATETIME) <= @EndDate) 
         THEN 366.0 
         ELSE 365.0 
         END 
        ELSE 
         CASE WHEN ISDATE(CAST(YEAR(@EndDate) AS CHAR(4)) + '0229') = 1 
         THEN 
          CASE WHEN (@StartDate <= cast('2/29/' + cast(YEAR(@EndDate) AS CHAR(4)) AS DATETIME) AND cast('2/29/' + cast(YEAR(@EndDate) AS CHAR(4)) AS DATETIME) <= @EndDate) 
          THEN 366.0 
          ELSE 365.0 
          END 
         ELSE 365.0 
         END 
        END 
       END 
      END 
     ELSE 
      ((@nbYears * 365.0) + 
       (
        SELECT COUNT(*) FROM 
        (
         SELECT (ROW_NUMBER() OVER(ORDER BY TABLE_NAME ASC) - 1) * 4 + 1900 AS [YEAR] 
         FROM INFORMATION_SCHEMA.COLUMNS 
        ) yr 
        WHERE [YEAR] BETWEEN YEAR(@StartDate) AND YEAR(@EndDate) 
       ) 
      )/@nbYears 
     END 
    RETURN @YearFrac 
END