Partilhar via


DATEADD (Transact-SQL)

Retorna um valor date especificado com o intervalo number especificado (inteiro assinado) adicionado à datepart especificada dessa date.

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). Para obter informações e exemplos comuns dos tipos de dados e funções de data e hora, consulte Usando dados de data e hora.

Ícone de vínculo de tópicoConvenções de sintaxe Transact-SQL

Sintaxe

DATEADD (datepart , number, date )

Argumentos

  • datepart
    É a parte de date para a qual um integernumber é adicionado. A tabela a seguir lista todos os argumentos datepart válidos. Equivalentes de variáveis definidas 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

    weekday

    dw, w

    hour

    hh

    minute

    mi, n

    second

    ss, s

    millisecond

    ms

    microsecond

    mcs

    nanosecond

    ns

  • number
    É uma expressão que pode ser resolvida para um int que é adicionado à datepart da date. Variáveis definidas pelo usuário são válidas.

    Se você especificar um valor com uma fração decimal, a fração será truncada e não arredondada.

  • date
    É uma expressão que pode ser resolvida para um valor time, date, smalldatetime, datetime, datetime2 ou valor 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. Se a expressão for uma cadeia de caracteres literal, deverá ser resolvido como um datetime. Para evitar ambigüidade, quatro dígitos para o ano. Para obter informações sobre anos de dois dígitos, consulte Opção two digit year cutoff.

Tipos de retorno

O tipo de dados de retorno é o tipo de dados do argumento date, com exceção de literais de cadeia de caracteres.

O tipo de dados de retorno para um literal de cadeia de caracteres é datetime. Um erro será gerado se a escala de segundos do literal de cadeia de caracteres possuir mais de três posições (.nnn) ou contiver a parte de deslocamento de fuso horário.

ObservaçãoObservação

Se os literais de cadeia de caracteres não forem convertidos explicitamente para o parâmetro date, os locais que usam um formato de data dia-mês-ano (dma) poderão obter resultados incorretos quando DATEADD for usada em conjunto com outras funções de data/hora.

Retornando um tipo datetime2

DATEADD retorna um tipo datetime2 quando o parâmetro date é um tipo datetime2. Ao usar literais de cadeia de caracteres para o parâmetro date, você deverá convertê-los explicitamente para um tipo datetime2 a fim de que DATEADD retorne um tipo datetime2.

Valor de retorno

Argumento datepart

dayofyear, day e weekday retornam o mesmo valor.

Cada datepart e suas abreviações retornam o mesmo valor.

Se datepart for month e o mês date tiver mais dias que o mês de retorno e o dia date não existir no mês de retorno, o último dia do mês de retorno será retornado. Por exemplo, setembro tem 30 dias; então, as duas instruções a seguir retornam 2006-09-30 00:00:00.000:

SELECT DATEADD(month, 1, '2006-08-30')

SELECT DATEADD(month, 1, '2006-08-31')

Argumento number

O argumento number não pode exceder o intervalo de int. Nas instruções a seguir, o argumento para number excede o intervalo de int em 1. A mensagem de erro a seguir é retornada: “Erro de estouro aritmético na conversão da expressão em dados tipo int”.

SELECT DATEADD(year,2147483648, '2006-07-31');
SELECT DATEADD(year,-2147483649, '2006-07-31');

Argumento date

O argumento date não pode ser incrementado a um valor fora do intervalo de seu tipo de dados. Nas instruções a seguir, o valor number que é adicionado ao valor date excede o intervalo do tipo de dados date. A mensagem de erro a seguir é retornada: "Adicionar um valor a uma coluna 'datetime' causou o estouro".

SELECT DATEADD(year,2147483647, '2006-07-31');
SELECT DATEADD(year,-2147483647, '2006-07-31');

Retorna valores de uma data smalldatetime e uma parte de data de segundo ou frações de segundo

A segunda parte de um valor smalldatetime é sempre 00. Se date for smalldatetime, o seguinte se aplicará:

  • Se datepart for second e number estiver entre -30 e +29, nenhum acréscimo será executado.

  • Se datepart for second e number for inferior a -30 ou superior a +29, o acréscimo será executado iniciando em um minuto.

  • Se datepart for millisecond e number estiver entre -30001 e +29998, nenhum acréscimo será executado.

  • Se datepart for millisecond e number for inferior a -30001 ou superior a +29998, o acréscimo será executado iniciando em um minuto.

Comentários

DATEADD pode ser usado na <lista> SELECT, cláusulas WHERE, HAVING, GROUP BY e ORDER BY.

Precisão de frações de segundo

O acréscimo de datepart de microsecond ou nanosecond para os tipos de dados datesmalldatetime, date e datetime não é permitido.

Os milissegundos têm uma escala de 3 (0,123). Os microssegundos têm uma escala de 6 (0,123456). Os nanossegundos têm uma escala de 9 (0,123456789). Os tipos de dados time, datetime2 e datetimeoffset têm uma escala máxima de 7 (0,1234567). Se datepart for nanosecond, number deve ser 100 antes das frações de segundo de aumento de date. Um number entre 1 e 49 será arredondado para 0 e um número de 50 a 99 será arredondado para 100.

As instruções a seguir adicionam um datepart de millisecond, microsecondou nanosecond.

DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111'
SELECT '1 millisecond' ,DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT '2 milliseconds', DATEADD(millisecond,2,@datetime2)
UNION ALL
SELECT '1 microsecond', DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT '2 microseconds', DATEADD(microsecond,2,@datetime2)
UNION ALL
SELECT '49 nanoseconds', DATEADD(nanosecond,49,@datetime2)
UNION ALL
SELECT '50 nanoseconds', DATEADD(nanosecond,50,@datetime2)
UNION ALL
SELECT '150 nanoseconds', DATEADD(nanosecond,150,@datetime2);
/*
Returns:
1 millisecond     2007-01-01 13:10:10.1121111
2 milliseconds    2007-01-01 13:10:10.1131111
1 microsecond     2007-01-01 13:10:10.1111121
2 microseconds    2007-01-01 13:10:10.1111131
49 nanoseconds    2007-01-01 13:10:10.1111111
50 nanoseconds    2007-01-01 13:10:10.1111112
150 nanoseconds   2007-01-01 13:10:10.1111113
*/

Deslocamento de fuso horário

Não é permitido acréscimo ao deslocamento de fuso horário.

Exemplos

A. Incrementando datepart em um intervalo de 1

Cada uma das instruções a seguir incrementa datepart por um intervalo de 1.

DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111'
SELECT 'year', DATEADD(year,1,@datetime2)
UNION ALL
SELECT 'quarter',DATEADD(quarter,1,@datetime2)
UNION ALL
SELECT 'month',DATEADD(month,1,@datetime2)
UNION ALL
SELECT 'dayofyear',DATEADD(dayofyear,1,@datetime2)
UNION ALL
SELECT 'day',DATEADD(day,1,@datetime2)
UNION ALL
SELECT 'week',DATEADD(week,1,@datetime2)
UNION ALL
SELECT 'weekday',DATEADD(weekday,1,@datetime2)
UNION ALL
SELECT 'hour',DATEADD(hour,1,@datetime2)
UNION ALL
SELECT 'minute',DATEADD(minute,1,@datetime2)
UNION ALL
SELECT 'second',DATEADD(second,1,@datetime2)
UNION ALL
SELECT 'millisecond',DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT 'microsecond',DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT 'nanosecond',DATEADD(nanosecond,1,@datetime2);
/*
Year         2008-01-01 13:10:10.1111111
quarter      2007-04-01 13:10:10.1111111
month        2007-02-01 13:10:10.1111111
dayofyear    2007-01-02 13:10:10.1111111
day          2007-01-02 13:10:10.1111111
week         2007-01-08 13:10:10.1111111
weekday      2007-01-02 13:10:10.1111111
hour         2007-01-01 14:10:10.1111111
minute       2007-01-01 13:11:10.1111111
second       2007-01-01 13:10:11.1111111
millisecond  2007-01-01 13:10:10.1121111
microsecond  2007-01-01 13:10:10.1111121
nanosecond   2007-01-01 13:10:10.1111111
*/

B. Incrementando mais de um nível de datepart em uma instrução

Cada uma das instruções a seguir incrementa datepart por um number grande o suficiente para também incrementar a próxima datepart superior de date.

DECLARE @datetime2 datetime2;
SET @datetime2 = '2007-01-01 01:01:01.1111111';
--Statement                                 Result   
-------------------------------------------------------------------                                   
SELECT DATEADD(quarter,4,@datetime2);     --2008-01-01 01:01:01.110
SELECT DATEADD(month,13,@datetime2);      --2008-02-01 01:01:01.110
SELECT DATEADD(dayofyear,365,@datetime2); --2008-01-01 01:01:01.110
SELECT DATEADD(day,365,@datetime2);       --2008-01-01 01:01:01.110
SELECT DATEADD(week,5,@datetime2);        --2007-02-05 01:01:01.110
SELECT DATEADD(weekday,31,@datetime2);    --2007-02-01 01:01:01.110
SELECT DATEADD(hour,23,@datetime2);       --2007-01-02 00:01:01.110
SELECT DATEADD(minute,59,@datetime2);     --2007-01-01 02:00:01.110
SELECT DATEADD(second,59,@datetime2);     --2007-01-01 01:02:00.110
SELECT DATEADD(millisecond,1,@datetime2); --2007-01-01 01:01:01.110

C. Usando expressões como argumentos para os parâmetros de número e data

Os exemplos a seguir usam tipos diferentes de expressões como argumentos para os parâmetros number e date.

Especificando coluna como data

O exemplo a seguir adiciona 2 dias a cada OrderDate para calcular uma nova PromisedShipDate.

USE AdventureWorks;
GO
SELECT SalesOrderID
    ,OrderDate 
    ,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;

Especificando variáveis definidas pelo usuário como número e data

O exemplo a seguir especifica variáveis definidas pelo usuário como argumentos para number e date.

DECLARE @days int;
DECLARE @datetime datetime;
SET @days = 365;
SET @datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */
SELECT DATEADD(day, @days, @datetime);

Especificando função de sistema escalar como data

O exemplo a seguir especifica SYSDATETIME para date.

SELECT DATEADD(month, 1, SYSDATETIME());

Especificando subconsultas e funções escalares como número e data

O exemplo a seguir usa subconsultas escalares e funções escalares, MAX(ModifiedDate), como argumentos para number e date. (SELECT TOP 1 ContactID FROM Person.Contact) é um argumento artificial para o parâmetro de número mostrar como é selecionado um argumento number de uma lista de valores.

USE AdventureWorks;
GO
SELECT DATEADD(month,(SELECT TOP 1 ContactID FROM Person.Contact),
    (SELECT MAX(ModifiedDate) FROM Person.Contact));

Especificando constantes como número e data

O exemplo a seguir usa constantes numéricas e de caractere como argumentos para number e date.

SELECT DATEADD(minute, 1, '2007-05-07 09:53:01.0376635');

Especificando expressões numéricas e funções de sistema escalares como número e data

O exemplo a seguir usa expressões numéricas (-(10/2)), operadores unários (-), um operador aritmético (/) e funções de sistema escalares (SYSDATETIME) como argumentos para number e date.

SELECT DATEADD(month,-(10/2), SYSDATETIME());

Especificando funções de classificação como número

O exemplo a seguir usa uma função de classificação como argumentos para number.

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

Especificando uma função de janela agregada como número

O exemplo a seguir usa uma função de janela agregada como um argumento para number.

USE AdventureWorks;
GO
SELECT SalesOrderID, ProductID, OrderQty
    ,DATEADD(day,SUM(OrderQty) 
        OVER(PARTITION BY SalesOrderID),SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail 
WHERE SalesOrderID IN(43659,43664);
GO

D. Usando DATEADD em localidades que usam o formato de data dma

Os exemplos a seguir mostram como usar literais de cadeia de caracteres como DATEADD para algumas localidades.

Demonstrando as armadilhas do uso de conversões implícitas de literais de cadeias de caracteres

O exemplo a seguir mostra o que acontece quando um literal de cadeia de caracteres não é convertido explicitamente.

SET LANGUAGE Español;

GO

SELECT DATENAME(m, DATEADD(d, 0,'1987-03-07'));

SELECT DATENAME(m, '1987-03-07');

GO

A primeira instrução select retorna julio (julho) para o mês e a segunda instrução select retorna marzo (março) para o mês.

Evite resultados incorretos ao converter de forma explícita o literal de cadeia de caracteres.

O exemplo a seguir mostra como converter explicitamente o parâmetro date para evitar resultados incorretos.

SET LANGUAGE Español;

GO

SELECT DATENAME(m, DATEADD(d, 0, CAST('1987-03-07' AS datetime2)));

SELECT DATENAME(m, '1987-03-07');

GO

Ambas as instruções select retornam marzo (março) como o mês.

Usando uma variável datetime2 em vez de um literal de cadeia de caracteres

O exemplo a seguir evita o uso direto de um literal de cadeia de caracteres.

SET LANGUAGE Español;

GO

DECLARE @d datetime2 = '1987-03-07';

SELECT DATENAME(m, DATEADD(d, 0, @d));

SELECT DATENAME(m, @d);

GO

Consulte também

Referência