[!div class=“nextstepaction”] Please help improve SQL Server docs!
This function adds a specified number value (as a signed integer) to a specified datepart of an input date value, and then returns that modified value.
See Date and Time Data Types and Functions (Transact-SQL) for an overview of all Transact\-SQL date and time data types and functions.
Transact-SQL Syntax Conventions
datepart
The part of date to which DATEADD
adds an integer number. This table lists all valid datepart arguments.
[!NOTE]
DATEADD
does not accept user-defined variable equivalents for the datepart arguments.
datepart | Abbreviations |
---|---|
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
An expression that can resolve to an int that DATEADD
adds to a datepart of date. DATEADD
accepts user-defined variable values for number. DATEADD
will truncate a specified number value that has a decimal fraction. It will not round the number value in this situation.
date
An expression that can resolve to one of the following values:
For date, DATEADD
will accept a column expression, expression, string literal, or user-defined variable. A string literal value must resolve to a datetime. Use four-digit years to avoid ambiguity issues. See Configure the two digit year cutoff Server Configuration Option for information about two-digit years.
The date argument data type becomes the DATEADD
return value data type, except for string literal date values. For a string literal, DATEADD
returns a datetime value. DATEADD
will raise an error if the string literal seconds scale exceeds three decimal place positions (.nnn) or if the string literal contains the time zone offset part.
dayofyear, day, and weekday return the same value.
Each datepart and its abbreviations return the same value.
If the following are true:
Then, DATEADD
returns the last day of the return month. For example, September has 30 (thirty) days; therefore, these statements return 2006-09-30 00:00:00.000:
The number argument cannot exceed the range of int. In the following statements, the argument for number exceeds the range of int by 1. These statements both return the following error message: "Msg 8115, Level 16, State 2, Line 1. Arithmetic overflow error converting expression to data type int."
DATEADD
will not accept a date argument incremented to a value outside the range of its data type. In the following statements, the number value added to the date value exceeds the range of the date data type. DATEADD
returns the following error message: “Msg 517, Level 16, State 1, Line 1 Adding a value to a 'datetime' column caused overflow
.”
The seconds part of a smalldatetime value is always 00. For a smalldatetime date value, the following apply:
DATEADD
makes no changes.DATEADD
performs its addition beginning at one minute.DATEADD
makes no changes.DATEADD
performs its addition beginning at one minute.Use DATEADD
in the following clauses:
DATEADD
does not allow addition for a datepart of microsecond or nanosecond for date data types smalldatetime, date, and datetime.
Milliseconds have a scale of 3 (.123), microseconds have a scale of 6 (.123456), and nanoseconds have a scale of 9 (.123456789). The time, datetime2, and datetimeoffset data types have a maximum scale of 7 (.1234567). For a datepart of nanosecond, number must be 100 before the fractional seconds of date increase. A number between 1 and 49 will round down to 0, and a number from 50 to 99 rounds up to 100.
These statements add a datepart of millisecond, microsecond, or 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);
Here is the result set.
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
DATEADD
does not allow addition for time zone offset.
Each of these statements increments datepart by an interval of 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);
Here is the result set.
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
Each of these statements increments datepart by a number large enough to additionally increment the next higher datepart of 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.1111111
SELECT DATEADD(month,13,@datetime2); --2008-02-01 01:01:01.1111111
SELECT DATEADD(dayofyear,365,@datetime2); --2008-01-01 01:01:01.1111111
SELECT DATEADD(day,365,@datetime2); --2008-01-01 01:01:01.1111111
SELECT DATEADD(week,5,@datetime2); --2007-02-05 01:01:01.1111111
SELECT DATEADD(weekday,31,@datetime2); --2007-02-01 01:01:01.1111111
SELECT DATEADD(hour,23,@datetime2); --2007-01-02 00:01:01.1111111
SELECT DATEADD(minute,59,@datetime2); --2007-01-01 02:00:01.1111111
SELECT DATEADD(second,59,@datetime2); --2007-01-01 01:02:00.1111111
SELECT DATEADD(millisecond,1,@datetime2); --2007-01-01 01:01:01.1121111
These examples use different types of expressions as arguments for the number and date parameters. The examples use the AdventureWorks database.
This example adds 2
(two) days to each value in the OrderDate
column, to derive a new column named PromisedShipDate
:
SELECT SalesOrderID
,OrderDate
,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;
A partial result set:
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
This example specifies user-defined variables as arguments for number and date:
DECLARE @days int = 365,
@datetime datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */;
SELECT DATEADD(day, @days, @datetime);
Here is the result set.
This example specifies SYSDATETIME
for date. The exact value returned depends on the day and time of statement execution:
Here is the result set.
This example uses scalar subqueries, MAX(ModifiedDate)
, as arguments for number and date. (SELECT TOP 1 BusinessEntityID FROM Person.Person)
serves as an artificial argument for the number parameter, to show how to select a number argument from a value list.
SELECT DATEADD(month,(SELECT TOP 1 BusinessEntityID FROM Person.Person),
(SELECT MAX(ModifiedDate) FROM Person.Person));
This example uses a numeric expression (-(10/2))
, unary operators (-
), an arithmetic operator (/
), and scalar system functions (SYSDATETIME
) as arguments for number and date.
This example uses a ranking function as an argument for number.
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;
This example uses an aggregate window function as an argument for number.
SELECT SalesOrderID, ProductID, OrderQty
,DATEADD(day,SUM(OrderQty)
OVER(PARTITION BY SalesOrderID),SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN(43659,43664);
GO