Compartir a través de


DATEADD (Transact-SQL)

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

Para obtener una introducción de todos los tipos de datos y funciones de fecha y hora de Transact-SQL, vea Tipos de datos y funciones de fecha y hora (Transact-SQL).

Icono de vínculo a temas Convenciones de sintaxis de Transact-SQL

Sintaxis

DATEADD (datepart , number , date )

Argumentos

  • datepart
    Es una parte de date al que se agrega un integer number. 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
    Expresión que se puede resolver como un valor int que se suma a un 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 Establecer la opción de configuración del servidor Fecha límite de año de dos dígitos.

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 ajuste de zona horaria.

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');

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 un mensaje de error que indica lo siguiente: "Msg 8115, Level 16, State 2, Line 1. Arithmetic overflow error converting expression to data type int."

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

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 un mensaje de error que indica lo siguiente: "Msg 517, Level 16, State 1, Line 1 Adding a value to a 'datetime' column caused overflow".

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

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.

Comentarios

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 un datepart de microsecond o nanosecond para los tipos de datos date smalldatetime, date y datetime no está permitida.

Los milisegundos tienen una escala de 3 (0,123), los microsegundos tienen una escala de 6 (0,123456) y 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);

El conjunto de resultados es el siguiente.

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

Ajuste de zona horaria

La suma no se permite para el ajuste 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);

El conjunto de resultados es el siguiente.

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 emplean tipos diferentes de expresiones como argumentos para los parámetros number y date.

Especificar una columna como fecha

En el ejemplo siguiente se agregan 2 días a cada valor de la columna OrderDate para derivar una nueva columna denominada PromisedShipDate.

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

A continuación se muestra un conjunto de resultados parcial.

SalesOrderID OrderDate               PromisedShipDate
------------ ----------------------- -----------------------
43659        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43660        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43661        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
...
43702        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43703        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43704        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43705        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43706        2005-07-03 00:00:00.000 2005-07-05 00:00:00.000
...
43711        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
43712        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
...
43740        2005-07-11 00:00:00.000 2005-07-13 00:00:00.000
43741        2005-07-12 00:00:00.000 2005-07-14 00:00:00.000

Especificar las variables definidas por el usuario como number y date

En el ejemplo siguiente se especifican variables definidas por el usuario como argumentos para number y date.

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

El conjunto de resultados es el siguiente.

-----------------------
2000-12-31 01:01:01.110

(1 row(s) affected)

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());

El conjunto de resultados es el siguiente.

---------------------------
2013-02-06 14:29:59.6727944

(1 row(s) affected)

Especificar subconsultas y funciones escalares como number y date

En el ejemplo siguiente se usan subconsultas escalares, MAX(ModifiedDate), como argumentos de number y date. (SELECT TOP 1 BusinessEntityID FROM Person.Person) es un argumento artificial para el parámetro number que se usa para mostrar cómo se selecciona un argumento number de una lista de valores.

USE AdventureWorks2012;
GO
SELECT DATEADD(month,(SELECT TOP 1 BusinessEntityID FROM Person.Person),
    (SELECT MAX(ModifiedDate) FROM Person.Person));

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

En el ejemplo siguiente se utiliza una expresión numérica (-(10/2)), operadores unarios (-), un operador aritmético (/) y funciones del 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 AdventureWorks2012;
GO
SELECT p.FirstName, p.LastName
    ,DATEADD(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;

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 AdventureWorks2012;
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

Vea también

Referencia

CAST y CONVERT (Transact-SQL)