DATEADD (Transact-SQL)

Devuelve un valor de date especificado con el intervalo de number especificado (entero con signo) agregado a un valor de datepart especificado de ese valor de date.

Para obtener una introducción de todos los tipos de datos y funciones de fecha y hora de Transact-SQL, consulte Tipos de datos y funciones de fecha y hora (Transact-SQL). Para obtener información y ejemplos comunes a los tipos de datos y funciones de fecha y hora, consulte Usar datos de fecha y hora.

Icono de vínculo a temasConvenciones de sintaxis de Transact-SQL

Sintaxis

DATEADD (datepart , number, date )

Argumentos

  • datepart
    Es una parte de date al que se agrega un integernumber. 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

    weekday

    dw, w

    hour

    hh

    minute

    mi, n

    second

    ss, s

    millisecond

    ms

    microsecond

    mcs

    nanosecond

    ns

  • number
    Es una expresión que se puede resolver como un valor int que se agrega a un valor datepart de date. Las variables definidas por el usuario son válidas.

    Si especifica un valor con una fracción decimal, la fracción se trunca y no se redondea.

  • date
    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. Si la expresión es un literal de cadena, debe tener como resultado un valor datetime. Para evitar la ambigüedad, utilice años de cuatro dígitos. Parta obtener información sobre los años de dos dígitos, consulte two digit year cutoff (opción).

Tipos de valor devueltos

El tipo de datos de retorno es el tipo de datos del argumento date, salvo los literales de cadena.

El tipo de datos de retorno para un literal de cadena es datetime. Se producirá un error si la escala de segundos del literal de cadena tiene más de tres posiciones (.nnn) o contiene la parte del desplazamiento de zona horaria.

[!NOTA]

Si los literales de cadena no se convierten explícitamente para el parámetro date, los locales que utilizan un formato de fecha día-mes-año (dma) pueden obtener resultados incorrectos cuando DATEADD se utiliza junto con otras funciones de fecha y hora.

Devolver un tipo datetime2

DATEADD devuelve un tipo datetime2 cuando el parámetro date es un tipo datetime2. Cuando se utilizan literales de cadena para el parámetro date, se deben convertir explícitamente a un tipo datetime2 para que DATEADD devuelva un tipo datetime2.

Valor devuelto

Argumento datepart

dayofyear, day y weekday devuelven el mismo valor.

Cada datepart y sus abreviaturas devuelven el mismo valor.

Si datepart es month y el mes date tiene más días que el mes de retorno y el día date no existe en el mes de retorno, se devuelve el último día del mes de retorno. Por ejemplo, septiembre tiene 30 días; por consiguiente, las dos instrucciones siguientes devuelven 2006-09-30 00:00:00.000:

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

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

Argumento number

El argumento number no puede superar el intervalo de int. En las instrucciones siguientes, el argumento para number supera el intervalo de int por 1. Se devuelve el mensaje de error siguiente: "Error de desbordamiento aritmético al convertir la expresión al tipo de datos int."

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

Argumento date

El argumento date no se puede incrementar a un valor fuera del intervalo de su tipo de datos. En las instrucciones siguientes, el valor number que se agrega al valor de date supera el intervalo del tipo de datos date. Se devuelve el mensaje de error siguiente: "Al agregar un valor a una columna 'datetime' se originó un desbordamiento."

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

Valores devueltos para una fecha smalldatetime y datepart de un segundo o fracciones de segundo

La parte correspondiente a los segundos de un valor smalldatetime siempre es 00. Si date es smalldatetime, se aplica lo siguiente:

  • Si datepart es second y number oscila entre -30 y +29, no se realiza ninguna adición.

  • Si datepart es second y number es inferior a -30 o superior a +29, la suma se realiza empezando por un minuto.

  • Si datepart es millisecond y number oscila entre -30001 y +29998, no se realiza ninguna suma.

  • Si datepart es millisecond y number es inferior a -30001 o superior a +29998, la suma se realiza empezando por un minuto.

Notas

DATEADD se puede utilizar en las cláusulas SELECT <lista>, WHERE, HAVING, GROUP BY y ORDER BY.

Precisión de fracciones de segundo

La suma para los tipos de datos datepart de microsecond o nanosecond para datesmalldatetime, date y datetime no está permitida.

Los milisegundos tienen una escala de 3 (0,123). Los microsegundos tienen una escala de 6 (0,123456). Los nanosegundos tienen una escala de 9 (0,123456789). Los tipos de datos time, datetime2 y datetimeoffset tienen una escala máxima de 7 (0,1234567). Si datepart es nanosecond, number debe ser 100 antes de que las fracciones de segundo de date aumenten. Un number entre 1 y 49 se redondea por defecto en 0 y un número de 50 a 99 se redondea por exceso en 100.

Las instrucciones siguientes agregan un datepart de millisecond, microsecond o 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
*/

Desplazamiento de zona horaria

La suma no se permite para el desplazamiento de zona horaria.

Ejemplos

A. Aumentar datepart en un intervalo de 1

Cada una de las instrucciones siguientes incrementa datepart en un 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. Aumentar más de un nivel de datepart en una instrucción

Cada una de las instrucciones siguientes incrementa datepart en un number los suficientemente grande para también incrementar el datepart más alto siguiente 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. Utilizar las expresiones como argumentos para los parámetros number y date

Los ejemplos siguientes utilizan tipos diferentes de expresiones como argumentos para los parámetros number y date.

Especificar una columna como fecha

El ejemplo siguiente agrega 2 días a cada OrderDate para calcular un nuevo PromisedShipDate.

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

Especificar las variables definidas por el usuario como number y date

El ejemplo siguiente especifica las variables definidas por el usuario como argumentos para number y 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);

Especificar la función de sistema escalar como date

En el siguiente ejemplo se especifica la palabra clave SYSDATETIME para date.

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

Especificar subconsultas y funciones escalares como number y date

El siguiente ejemplo utiliza subconsultas escalares y funciones escalares ms177499(v=sql.100).md, MAX(ModifiedDate) como argumentos para number y date. (SELECT TOP 1 ContactID FROM Person.Contact) es un argumento artificial para el parámetro number que se utiliza para mostrar cómo seleccionar un argumento number de una lista de valores.

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

Especificar las constantes como number y date

EL siguiente ejemplo utilizar constantes numéricas y de caracteres como argumentos para number y date.

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

Especificar expresiones numéricas y funciones de sistema escalares como number y date

El ejemplo siguiente utiliza expresiones numéricas (-(10/2)), operadores unarios (-), un operador aritmético (/) y las funciones de sistema escalares (SYSDATETIME) como argumentos para number y date.

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

Especificar las funciones de clasificación como number

El ejemplo siguiente utiliza una función de clasificación 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;

Especificar una función de ventana agregada como number

En el ejemplo siguiente se utiliza una función de agregado como 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. Utilizar DATEADD para configuraciones regionales que utilizan el formato de fecha dma

En los siguientes ejemplos se muestra cómo utilizar literales de cadena con DATEADD para algunas configuraciones regionales.

Mostrar los riesgos que supone el uso de una conversión implícita de un literal de cadena

En el siguiente ejemplo se muestra lo que sucede cuando un literal de cadena no se convierte explícitamente.

SET LANGUAGE Español;

GO

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

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

GO

La primera instrucción SELECT devuelve julio para el mes y la segunda instrucción SELECT devuelve marzo para el mes.

Evitar resultados erróneos mediante la conversión explícita del literal de cadena

En el siguiente ejemplo se muestra cómo convertir explícitamente el parámetro date para evitar resultados erróneos.

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 instrucciones SELECT devuelven marzo para el mes.

Utilizar una variable datetime2 en lugar de un literal de cadena

En el siguiente ejemplo se evita el uso directo de un literal de cadena.

SET LANGUAGE Español;

GO

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

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

SELECT DATENAME(m, @d);

GO

Vea también

Referencia