Partilhar via


DATEDIFF (Transact-SQL)

Aplica-se a:Banco de Dados SQL doAzureInstância Gerenciada de SQL do AzureAzure Synapse AnalyticsAnalytics Platform System (PDW)Banco de Dados SQL no Microsoft Fabric

Esta função devolve a contagem (como um valor inteiro com sinal) dos limites de dataparte especificados cruzados entre a data de início e a data de fim especificadas.

Veja DATEDIFF_BIG para uma função que gere diferenças maiores entre os valores da data de início e da data de término . Consulte Tipos e funções de dados de data e hora para obter uma visão geral de todos os tipos e funções de dados de data e hora Transact-SQL.

Transact-SQL convenções de sintaxe

Sintaxe

DATEDIFF ( datepart , startdate , enddate )

Arguments

datepart

Especifica as unidades em que DATEDIFF reporta a diferença entre a data de início e a data de fim. As unidades de peças de data mais usadas incluem month ou second.

O valor da datapart não pode ser especificado numa variável, nem como uma cadeia de aspas como 'month'.

A tabela seguinte lista todos os valores válidos das datas . DATEDIFF aceita o nome completo da data, ou qualquer abreviatura listada do nome completo.

DataNome da parte abreviatura datepart
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y
day dd, d
week wk, ww
weekday dw, w
hour hh
minute mi, n
second ss, s
millisecond ms
microsecond mcs
nanosecond ns

Cada nome específico da datapart e as abreviaturas desse nome devolvem o mesmo valor.

data de início

Uma expressão que pode resolver para um dos seguintes valores:

  • date
  • datetime
  • datetimeoffset
  • datetime2
  • smalldatetime
  • time

Use anos de quatro dígitos para evitar ambiguidades. Consulte configuração do servidor: corte de ano de dois dígitos para informações sobre valores de dois dígitos.

Data de fim

Consulte a data de início.

Tipos de devolução

int

Valor de retorno

A diferença int entre a data de início e a data de fim, expressa na fronteira definida por datepart.

Por exemplo, SELECT DATEDIFF(day, '2036-03-01', '2036-02-28'); devolve -2, sugerindo que 2036 deve ser um ano bissexto. Este caso significa que, se começarmos na data2036-03-01 de início e depois contarmos -2 os dias, chegamos à data final de 2036-02-28.

Para um valor de retorno fora do intervalo para int (-2.147.483.648 a +2.147.483.647), DATEDIFF retorna um erro. Para millisecond, a diferença máxima entre a data de início e a data de fim é de 24 dias, 20 horas, 31 minutos e 23,647 segundos. Para second, a diferença máxima é de 68 anos, 19 dias, 3 horas, 14 minutos e 7 segundos.

Se a data de início e a data de fim tiverem ambas atribuídas apenas um valor temporal, e a datapart não for uma data temporal, devolve DATEDIFF0.

DATEDIFF utiliza o componente de deslocamento do fuso horário da data de início ou de fim para calcular o valor de retorno.

Como smalldatetime é preciso apenas ao minuto, segundos e milissegundos são sempre definidos no 0 valor de retorno quando a data de início ou a data de fim têm um valor smalldatetime .

Se apenas um valor de tempo for atribuído a uma variável de tipo de dados de data, DATEDIFF definirá o valor da parte de data ausente como o valor padrão: 1900-01-01. Se apenas um valor de data for atribuído a uma variável de um tipo de dados de data ou hora, DATEDIFF definirá o valor da parte de tempo ausente como o valor padrão: 00:00:00. Se a data de início ou a data de término tiverem apenas uma parte de tempo e a outra apenas uma parte de data, DATEDIFF definirá as partes de data e hora ausentes para os valores padrão.

Se a data de início e a data de fim tiverem tipos de dados de data diferentes, e um tiver mais partes de tempo ou precisão em frações de segundo do que o outro, DATEDIFF define as partes em falta da outra para 0.

Limites das partes de datas

As instruções a seguir têm os mesmos valores startdate e enddate . Essas datas são adjacentes e diferem em tempo em cem nanossegundos (0,0000001 segundo). A diferença entre a data de início e a data de término em cada instrução cruza um limite de calendário ou hora de sua parte de data. Cada afirmação devolve 1.

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(weekday, '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');
SELECT DATEDIFF(microsecond, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');

Se a data de início e a data de fim tiverem valores de ano diferentes, mas tiverem os mesmos valores da semana civil, devolve DATEDIFF0 a data de dataweek.

Observações

Use nas DATEDIFFcláusulas , SELECT <list>, WHERE, HAVING, , e GROUP BY .ORDER BY

DATEDIFF implicitamente converte literais de cadeia de caracteres como um tipo datetime2 . Ou seja, DATEDIFF não suporta o formato YDM quando a data é passada como uma cadeia. Deve explicitamente castar a string para um tipo datetime ou smalldatetime para usar o YDM formato.

A especificação SET DATEFIRST não tem efeito sobre DATEDIFFo . DATEDIFF sempre usa o domingo como o primeiro dia da semana para garantir que a função opere de forma determinística.

DATEDIFF pode transbordar com precisão igual ou minute superior, se a diferença entre data de término e data de início devolver um valor fora do intervalo para int.

Examples

Os exemplos de código neste artigo usam o banco de dados de exemplo AdventureWorks2025 ou AdventureWorksDW2025, que pode ser descarregado da página inicial de Exemplos e Projetos da Comunidade do Microsoft SQL Server.

Estes exemplos usam diferentes tipos de expressões como argumentos para os parâmetros da data de início e da data de término .

A. Especifique colunas para a data de início e a data de fim

Este exemplo calcula o número de limites de dias cruzados entre datas em 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;

Aqui está o conjunto de resultados.

Duration
--------
1

B. Especificar variáveis definidas pelo utilizador para a data de início e a data de fim

Neste exemplo, as variáveis definidas pelo utilizador servem como argumentos para a data de início e a data de término.

DECLARE @startdate AS DATETIME2 = '2007-05-05 12:10:09.3312722';
DECLARE @enddate AS DATETIME2 = '2007-05-04 12:10:09.3312722';

SELECT DATEDIFF(day, @startdate, @enddate);

C. Especifique funções escalares do sistema para a data de início e a data de fim

Este exemplo utiliza funções de sistema escalar como argumentos para a data de início e a data de fim.

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

D. Especificar subconsultas escalares e funções escalares para a data de início e data de fim

Este exemplo utiliza subconsultas escalares e funções escalares como argumentos para a data de início e a data de término.

USE AdventureWorks2022;
GO

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

E. Especifique constantes para a data de início e a data de fim

Este exemplo usa constantes de carácter como argumentos para a data de início e a data de fim.

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

F. Especificar expressões numéricas e funções escalares do sistema para a data final

Este exemplo utiliza uma expressão numérica, (GETDATE() + 1), e funções GETDATE do sistema escalar e SYSDATETIME, como argumentos para a data de término.

USE AdventureWorks2022;
GO

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

USE AdventureWorks2022;
GO

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

G. Especificar funções de classificação para a data de início

Este exemplo usa uma função de classificação como argumento para a data de início.

USE AdventureWorks2022;
GO

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

H. Especifique uma função de janela agregada para a data de início

Este exemplo utiliza uma função de janela agregada como argumento para a data de início.

USE AdventureWorks2022;
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 AS sod
     INNER JOIN Sales.SalesOrderHeader AS soh
         ON sod.SalesOrderID = soh.SalesOrderID
WHERE soh.SalesOrderID IN (43659, 58918);
GO

I. Encontre diferenças entre data de início e data de fim como sequências de partes de data

-- DOES NOT ACCOUNT FOR LEAP YEARS
DECLARE @date1 AS DATETIME, @date2 AS DATETIME, @result AS VARCHAR (100);

DECLARE @years AS INT, @months AS INT, @days AS INT, @hours AS INT, @minutes AS INT, @seconds AS INT, @milliseconds AS INT;

SET @date1 = '1900-01-01 00:00:00.000';

SET @date2 = '2018-12-12 07:08:01.123';

SELECT @years = DATEDIFF(yy, @date1, @date2);

IF DATEADD(yy, -@years, @date2) < @date1
    SELECT @years = @years - 1;

SET @date2 = DATEADD(yy, -@years, @date2);

SELECT @months = DATEDIFF(mm, @date1, @date2);

IF DATEADD(mm, -@months, @date2) < @date1
    SELECT @months = @months - 1;

SET @date2 = DATEADD(mm, -@months, @date2);

SELECT @days = DATEDIFF(dd, @date1, @date2);

IF DATEADD(dd, -@days, @date2) < @date1
    SELECT @days = @days - 1;

SET @date2 = DATEADD(dd, -@days, @date2);

SELECT @hours = DATEDIFF(hh, @date1, @date2);

IF DATEADD(hh, -@hours, @date2) < @date1
    SELECT @hours = @hours - 1;

SET @date2 = DATEADD(hh, -@hours, @date2);

SELECT @minutes = DATEDIFF(mi, @date1, @date2);

IF DATEADD(mi, -@minutes, @date2) < @date1
    SELECT @minutes = @minutes - 1;

SET @date2 = DATEADD(mi, -@minutes, @date2);

SELECT @seconds = DATEDIFF(s, @date1, @date2);

IF DATEADD(s, -@seconds, @date2) < @date1
    SELECT @seconds = @seconds - 1;

SET @date2 = DATEADD(s, -@seconds, @date2);

SELECT @milliseconds = DATEDIFF(ms, @date1, @date2);

SELECT @result = ISNULL(CAST (NULLIF (@years, 0) AS VARCHAR (10)) + ' years,', '')
    + ISNULL(' ' + CAST (NULLIF (@months, 0) AS VARCHAR (10)) + ' months,', '')
    + ISNULL(' ' + CAST (NULLIF (@days, 0) AS VARCHAR (10)) + ' days,', '')
    + ISNULL(' ' + CAST (NULLIF (@hours, 0) AS VARCHAR (10)) + ' hours,', '')
    + ISNULL(' ' + CAST (@minutes AS VARCHAR (10)) + ' minutes and', '')
    + ISNULL(' ' + CAST (@seconds AS VARCHAR (10)) + CASE
        WHEN @milliseconds > 0
        THEN '.' + CAST (@milliseconds AS VARCHAR (10))
        ELSE ''
    END + ' seconds', '');

SELECT @result;

Aqui está o conjunto de resultados.

118 years, 11 months, 11 days, 7 hours, 8 minutes and 1.123 seconds

Exemplos: Azure Synapse Analytics and Analytics Platform System (PDW)

Estes exemplos usam diferentes tipos de expressões como argumentos para os parâmetros da data de início e da data de término .

J. Especifique colunas para a data de início e a data de fim

Este exemplo calcula o número de limites de dias cruzados entre datas em 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 TOP (1) DATEDIFF(day, startDate, endDate) AS [Duration]
FROM dbo.Duration;
Duration
--------
1

K. Especificar subconsultas escalares e funções escalares para a data de início e data de fim

Este exemplo utiliza subconsultas escalares e funções escalares como argumentos para a data de início e a data de término.

-- Uses AdventureWorks
SELECT TOP (1) DATEDIFF(day, (SELECT MIN(HireDate)
                              FROM dbo.DimEmployee), (SELECT MAX(HireDate)
                                                      FROM dbo.DimEmployee))
FROM dbo.DimEmployee;

L. Especifique constantes para a data de início e a data de fim

Este exemplo usa constantes de carácter como argumentos para a data de início e a data de fim.

-- Uses AdventureWorks
SELECT TOP (1) DATEDIFF(day, '2007-05-07 09:53:01.0376635', '2007-05-08 09:53:01.0376635')
FROM DimCustomer;

M. Especificar funções de classificação para a data de início

Este exemplo usa uma função de classificação como argumento para a data de início.

-- Uses AdventureWorks
SELECT FirstName,
       LastName,
       DATEDIFF(day, ROW_NUMBER() OVER (ORDER BY DepartmentName), SYSDATETIME()) AS RowNumber
FROM dbo.DimEmployee;

N. Especifique uma função de janela agregada para a data de início

Este exemplo utiliza uma função de janela agregada como argumento para a data de início.

-- Uses AdventureWorks
SELECT FirstName,
       LastName,
       DepartmentName,
       DATEDIFF(year, MAX(HireDate) OVER (PARTITION BY DepartmentName), SYSDATETIME()) AS SomeValue
FROM dbo.DimEmployee;