DATEDIFF (Transact-SQL)
Retorna a contagem (inteiro com sinal) dos limites especificados de datepart cruzados entre os parâmetros especificados startdate e enddate.
Para obter uma visão geral de todos os tipos de dados e funções de data e hora do Transact-SQL, consulte tipos de dados e funções de data e hora (Transact-SQL).
Convenções de sintaxe Transact-SQL
Sintaxe
DATEDIFF ( datepart , startdate , enddate )
Argumentos
datepart
É a parte de startdate e enddate que especifica o tipo de limite cruzado. A tabela a seguir lista todos os argumentos datepart válidos. Equivalentes de variável definidos pelo usuário não são válidos.datepart
Abreviações
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
É uma expressão que pode ser resolvida para um valor time, date, smalldatetime, datetime, datetime2 ou datetimeoffset. date pode ser uma expressão, uma expressão de coluna, uma variável definida pelo usuário ou um literal de cadeia de caracteres. startdate é subtraído de enddate.Para evitar ambiguidade, use anos de quatro dígitos. Para obter informações sobre anos de dois dígitos, consulte Configurar a opção two digit year cutoff de configuração de servidor.
enddate
Consulte startdate.
Tipo de retorno
int
Valor de retorno
Cada datepart e suas abreviações retornam o mesmo valor.
Se o valor de retorno estiver fora do intervalo de int (-2,147,483,648 a +2,147,483,647), um erro será retornado. Para millisecond, a diferença máxima entre startdate e enddate é de 24 dias, 20 horas, 31 minutos e 23.647 segundos. Para second, a diferença máximo é de 68 anos.
Se a startdate e enddate forem atribuídos apenas um valor de hora e o datepart não for um datepart de hora, será retornado 0.
Um componente de deslocamento de fuso horário de startdate ou endate não é usado no cálculo do valor de retorno.
Como smalldatetime tem precisão apenas quanto ao minuto, quando um valor de smalldatetime é usado para startdate ou enddate, os segundos e milissegundos são sempre definidos como 0 no valor de retorno.
Se apenas um valor temporal for atribuído a uma variável de tipo de dados “data”, o valor da parte “data” faltante será definido como o padrão: 1900-01-01. Se apenas um valor de data for atribuído a uma variável de tipo de dados “hora” ou “data”, o valor da parte “hora” faltante será definido como o padrão: 00:00:00. Se tanto startdate quanto enddate tiverem apenas uma parte “hora” e a outra somente uma parte “data”, as partes “hora” e “data” faltantes serão definidas como os valores padrão.
Se startdate e enddate forem de tipos de dados “data” diferentes e um tiver mais partes “hora” ou precisão de frações de segundos do que o outro, as partes faltantes do outro serão definidas como 0.
Limites de datepart
As instruções a seguir têm o mesmo startdate e endate. Essas datas são adjacentes e diferem, quanto à hora, em 0,0000001 segundo. A diferença entre startdate e endate em cada instrução cruza um calendário ou limite de hora de seu datepart. Cada atribuição retorna 1. Se anos diferentes forem usados neste exemplo e se startdate e endate estiverem na mesma semana de calendário, o valor retornado 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');
Comentários
DATEDIFF pode ser usado na lista de seleção, cláusulas WHERE, HAVING, GROUP BY e ORDER BY.
DATEDIFF converte implicitamente literais de cadeias de caracteres como um tipo datetime2. Isso significa que DATEDIFF não oferece suporte ao formato YDM quando a data é transmitida como cadeia de caracteres. É necessário converter explicitamente a cadeia de caracteres em um tipo datetime ou smalldatetime para usar o formato YDM.
A especificação de SET DATEFIRST não tem nenhum efeito em DATEDIFF. DATEDIFF sempre usa Domingo como o primeiro dia da semana par assegurar que a função seja determinística.
Exemplos
Os exemplos a seguir usam diferentes tipos de expressões como argumentos para os parâmetros startdate e enddate.
A. Especificando colunas para startdate e enddate
O exemplo a seguir calcula o número de limites de dia que são cruzados entre as datas de duas colunas de uma tabela.
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. Especificando variáveis definidas pelo usuário para startdate e enddate
O exemplo a seguir utiliza variáveis definidas pelo usuário como argumentos para startdate e 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. Especificando funções de sistema escalares para startdate e enddate
O exemplo a seguir usa funções de sistema escalares como argumentos para startdate e enddate.
SELECT DATEDIFF(millisecond, GETDATE(), SYSDATETIME());
D. Especificando subconsultas e funções escalares para startdate e enddate
O exemplo a seguir usa subconsultas e funções escalares como argumentos para startdate e enddate.
USE AdventureWorks2012;
GO
SELECT DATEDIFF(day,(SELECT MIN(OrderDate) FROM Sales.SalesOrderHeader),
(SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader));
E. Especificando constantes para startdate e enddate
O exemplo a seguir usa constantes de caractere como argumentos para startdate e enddate.
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635'
, '2007-05-08 09:53:01.0376635');
F. Especificando expressões numéricas e funções de sistema escalares para enddate
O exemplo a seguir usa uma expressão numérica, (GETDATE ()+ 1), e as funções de sistema escalares GETDATE e 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. Especificando funções de classificação para startdate
O exemplo a seguir usa uma função de classificação 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. Especificando uma função de janela de agregação para startdate
O exemplo a seguir usa uma função de janela de agregação como um 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