Compartir a través de


DATEDIFF (Transact-SQL)

Devuelve el recuento (entero con firma) de los límites datepart que se han cruzado entre los valores startdate y enddate especificados.

Para obtener información general acerca de todos los tipos de datos y funciones de fecha y hora de Transact-SQL, vea Tipos de datos y funciones de fecha y hora (Transact-SQL).

Icono de vínculo a temas Convenciones de sintaxis de Transact-SQL

Sintaxis

DATEDIFF ( datepart , startdate , enddate )

Argumentos

  • datepart
    Es la parte de startdate y enddate que especifica el tipo de límite cruzado. En la siguiente tabla se recogen los argumentos válidos de datepart. Los equivalentes de variables definidas por el usuario no son válidos.

    datepart

    Abreviaturas

    year

    yy, yyyy

    quarter

    qq, q

    month

    mm, m

    dayofyear

    dy, y

    day

    dd, d

    week

    wk, ww

    hour

    hh

    minute

    mi, n

    second

    ss, s

    millisecond

    ms

    microsecond

    mcs

    nanosecond

    ns

  • startdate
    Es una expresión que se puede resolver como un valor time, date, smalldatetime, datetime, datetime2 o datetimeoffset. date puede ser una expresión, una expresión de columna, una variable definida por el usuario o un literal de cadena. startdate se resta de enddate.

    Para evitar la ambigüedad, utilice años de cuatro dígitos. Parta obtener información sobre los años de dos dígitos, vea Establecer la opción de configuración del servidor Fecha límite de año de dos dígitos.

  • enddate
    Vea startdate.

Tipo de valor devuelto

int

Valor devuelto

Cada datepart y sus abreviaturas devuelven el mismo valor.

Si el valor devuelto está fuera del intervalo para int (de -2.147.483.648 a +2.147.483.647), se devuelve un error. Para millisecond, la diferencia máxima entre startdate y enddate es de 24 días, 20 horas, 31 minutos y 23.647 segundos. Para second, la diferencia máxima es de 68 años.

Si startdate y enddate tienen asignado solo un valor de tiempo y datepart no es un datepart de tiempo, se devuelve 0.

Un componente de ajuste de zona horaria de startdate o endate no se utiliza para calcular el valor devuelto.

Puesto que smalldatetime solo es preciso hasta los minutos, cuando se use un valor smalldatetime para startdate o enddate, los segundos y milisegundos siempre se establecen en 0 en el valor devuelto.

Si solo se asigna un valor de tiempo a una variable de un tipo de datos de fecha, el valor de la parte de la fecha que falta se establece en el valor predeterminado: 1900-01-01. Si solo se asigna un valor de fecha a una variable de un tipo de datos de fecha u hora, el valor de la parte de la hora que falta se establece en el valor predeterminado: 00:00:00. Si startdate o enddate tienen solo una parte de hora y el otro solo una parte de la fecha, las partes de la hora que y la fecha que faltan se establecen en los valores predeterminados.

Si startdate y enddate son de tipos de datos de fecha diferentes y uno tiene más partes de hora o precisión de fracciones de segundo que el otro, las partes que faltan del otro se establecen en 0.

Límites de datepart

Las siguientes instrucciones tienen el mismo valor startdate y el mismo valor endate. Esas fechas son adyacentes y difieren y tienen una diferencia horaria de 0,0000001 segundos. La diferencia entre startdate y endate en cada instrucción cruza un límite de calendario u hora de su datepart. Cada instrucción devuelve 1. Si se usan años diferentes en este ejemplo y si tanto la startdate como la endate están en la misma semana del calendario, el valor devuelto para week será 0.

SELECT DATEDIFF(year, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(quarter, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(month, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(dayofyear, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(day, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(week, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(hour, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(minute, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(second, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

SELECT DATEDIFF(millisecond, '2005-12-31 23:59:59.9999999'

, '2006-01-01 00:00:00.0000000');

Comentarios

DATEDIFF se puede usar en la lista de selección y en las cláusulas WHERE, HAVING, GROUP BY y ORDER BY.

DATEDIFF convierte implícitamente los literales de cadena como un tipo datetime2. Esto significa que DATEDIFF no admite el formato año-día-mes cuando se pasa la fecha como cadena. La cadena se debe convertir explícitamente a un tipo datetime o smalldatetime para poder usar el formato año-día-mes.

La especificación de SET DATEFIRST no tiene efecto en DATEDIFF. DATEDIFF siempre utiliza Domingo como el primer día de la semana para garantizar que la función es determinística.

Ejemplos

En los ejemplos siguientes se usan diferentes tipos de expresiones como argumentos para los parámetros startdate y enddate.

A. Especificar las columnas para startdate y enddate

El ejemplo siguiente calcula el número de límites de día que se cruzan entre las fechas en dos columnas de una tabla.

CREATE TABLE dbo.Duration
    (
    startDate datetime2
    ,endDate datetime2
    );
INSERT INTO dbo.Duration(startDate,endDate)
    VALUES('2007-05-06 12:10:09','2007-05-07 12:10:09');
SELECT DATEDIFF(day,startDate,endDate) AS 'Duration'
FROM dbo.Duration;
-- Returns: 1

B. Especificar las variables definidas por el usuario para startdate y enddate

El ejemplo siguiente usa las variables definidas por el usuario como argumentos para startdate y enddate.

DECLARE @startdate datetime2 = '2007-05-05 12:10:09.3312722';
DECLARE @enddate datetime2 = '2007-05-04 12:10:09.3312722'; 
SELECT DATEDIFF(day, @startdate, @enddate);

C. Especificar las funciones de sistema escalares para startdate y enddate

El ejemplo siguiente usa las funciones de sistema escalares como argumentos para startdate y enddate.

SELECT DATEDIFF(millisecond, GETDATE(), SYSDATETIME());

D. Especificar las funciones escalares y de subconsulta para startdate y enddate

El ejemplo siguiente usa las funciones escalares y de subconsulta como argumentos para startdate y enddate.

USE AdventureWorks2012;
GO
SELECT DATEDIFF(day,(SELECT MIN(OrderDate) FROM Sales.SalesOrderHeader),
    (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader));

E. Especificar las constantes para startdate y enddate

El siguiente ejemplo usa constantes numéricas y de caracteres como argumentos para startdate y enddate.

SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635'
    , '2007-05-08 09:53:01.0376635');

F. Especificar expresiones numéricas y funciones de sistema escalares para enddate

El ejemplo siguiente usa una expresión numérica, (GETDATE ()+ 1), y funciones de sistema escalares, GETDATE y SYSDATETIME, como argumentos para enddate.

USE AdventureWorks2012;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', GETDATE()+ 1) 
    AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO
USE AdventureWorks2012;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', DATEADD(day,1,SYSDATETIME())) AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO

G. Especificar las funciones de clasificación para startdate

En el ejemplo siguiente se usa una función de categoría como argumento para startdate.

USE AdventureWorks2012;
GO
SELECT p.FirstName, p.LastName
    ,DATEDIFF(day,ROW_NUMBER() OVER (ORDER BY 
        a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson s 
    INNER JOIN Person.Person p 
        ON s.BusinessEntityID = p.BusinessEntityID
    INNER JOIN Person.Address a 
        ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0;

H. Especificar una función de ventana agregada para startdate

El ejemplo siguiente utiliza una función de ventana agregada como un argumento para startdate.

USE AdventureWorks2012;
GO
SELECT soh.SalesOrderID, sod.ProductID, sod.OrderQty,soh.OrderDate
    ,DATEDIFF(day,MIN(soh.OrderDate) 
        OVER(PARTITION BY soh.SalesOrderID),SYSDATETIME() ) AS 'Total'
FROM Sales.SalesOrderDetail sod
    INNER JOIN Sales.SalesOrderHeader soh
        ON sod.SalesOrderID = soh.SalesOrderID
WHERE soh.SalesOrderID IN(43659,58918);
GO

Vea también

Referencia

CAST y CONVERT (Transact-SQL)