Partilhar via


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).

Ícone de vínculo de tópico 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

Consulte também

Referência

CAST e CONVERT (Transact-SQL)