How the calculation happen for MONTH datepart in DATEADD()
Add Month
SELECT '2012-01-29' AS [Date], CAST(DATEADD(MONTH, 1, '2012-01-31') AS DATE) AS NextDate
UNION
SELECT '2012-01-31' AS [Date], CAST(DATEADD(MONTH, 1, '2012-01-31') AS DATE) AS NextDate
UNION
SELECT '2013-01-31' AS [Date], CAST(DATEADD(MONTH, 1, '2013-01-31') AS DATE) AS NextDate
Result
Subtract Month
SELECT '2012-02-29' AS [Date], CAST(DATEADD(MONTH, -1, '2012-02-29') AS DATE) AS PrevDate
UNION
SELECT '2012-03-01' AS [Date], CAST(DATEADD(MONTH, -1, '2012-03-01') AS DATE) AS PrevDate
Result
When I add a Month for the dates 29,30,31 of Jan'2012
, I get the same result as February 29
. For subtract, for the date 29 Feb'2012
, it shows 29 Jan'2012
. There is no way to get the dates 30 & 31 of Jan'2012
.
I want to know some brief explanation.
The behaviour is explicitly documented in the documentation for DATEADD
:
DATEADD (datepart , number , date )
...
If datepart is month and the date month has more days than the return month and the date day does not exist in the return month, the last day of the return month is returned. For example, September has 30 days; therefore, the two following statements return 2006-09-30 00:00:00.000:
SELECT DATEADD(month, 1, '2006-08-30');
SELECT DATEADD(month, 1, '2006-08-31');
As to why it has this behaviour, it all comes down to the fact that variable length months mean that you have to apply some form of tradeoff when performing date maths, and no one "correct" answer exists. Do you think of 31st January as being "the last day of January" or "30 days after the 1st day of January". Both of those are correct ways of thinking about the 31st. But if you change January
to February
, you now obtain two different dates - 28th or 29th of February for "the last day of February" or 2nd or 3rd of March for "30 days after the 1st day of February".
But functions have to return just one value.
I'm not saying that SQL Server applies either of the above interpretations. What it does do, though, is ensures that if you add, say, 1 month onto a particular date, you can be sure that the resulting date falls in the following month.