Following query will find the last day of the month. Query also take care of Leap Year. Use it any time you need the last day of month for a given date.

Script:
DECLARE @date DATETIME
SET @date='2008-02-03'
SELECT DATEADD(dd, -DAY(DATEADD(m,1,@date)), DATEADD(m,1,@date))
AS LastDayOfMonth
GO
DECLARE @date DATETIME
SET @date='2007-02-03'
SELECT DATEADD(dd, -DAY(DATEADD(m,1,@date)), DATEADD(m,1,@date))
AS LastDayOfMonth
GO
ResultSet:
LastDayOfMonth ----------------------- 2008-02-29 00:00:00.000 (1 row(s) affected) LastDayOfMonth ----------------------- 2007-02-28 00:00:00.000 (1 row(s) affected)
How the Last Day of Month Query Works
The trick is easier to trust once you see the steps. First, DATEADD moves the date one month forward. Then DAY() tells you which day of that next month you landed on. Subtract that many days and you step back to the end of the original month. For 3 February 2008, one month ahead is 3 March, and going back three days lands on 29 February.
It also works for dates at the end of a month. For 31 January 2008, one month ahead is 29 February, because SQL Server stops at the last valid day. Step back 29 days and you are on 31 January again.
Watch out for one detail: the time part of the input is kept. If you pass 2008-02-13 at 1:45 PM, you get 29 February at 1:45 PM, not midnight. If you need midnight, strip the time first, or use this form, which always returns midnight: DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, @date) + 1, 0)).
On SQL Server 2012 and later, the built in EOMONTH function does the same job in one call and returns a date with no time part. It also takes a second argument to add or subtract months, so EOMONTH(@date, -1) gives the end of the previous month.
A common mistake is filtering a datetime column with BETWEEN the first day and the last day of the month. Rows from later in the day on the last day are missed, because that last day means midnight. A safer filter is column >= first day of this month and column < first day of next month.
When you test any month end code, use a short list of dates: the first and last day of a month, 31 January, the end of February in a leap year and in a normal year, and 31 December, where the next month falls in the next year. If all of those work, you can trust the query.
Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.
Discover more from SQL Authority with Pinal Dave
Subscribe to get the latest posts sent to your email.





13 Comments. Leave new
DECLARE @date DATETIME
SET @date=’2009-02-04′
SELECT
DATEADD(mm,1,@date)-DAY(@DATE)
AS LastDayOfMonth
Doesn’t work if today IS the last day of the current month.
Thanks for this article. It helped me a lot .
:-)
Another method
DECLARE @date DATETIME
SET @date=’2008-02-03′
SELECT DATEADD(month,DATEDIFF(month,0,@date)+1,-1) AS LastDayOfMonth
Hello Pinal,
How do you calculate the last day of ANY month when you are only given the month and year, no day?
Thanks
The simple method is
declare @month int, @year int
select @month=3, @year=2009
select DATEADD(year,@year-1900,dateadd(month,@month,0))-1
Nice
also the EOMONTH function from the commericial package XLeratorDB…
Use EOMONTH to calculate the date for the last day of the month that is the indicated number of months before or after the start date. Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month.
SELECT DATEADD(MONTH,1,GETDATE())-DAY(GETDATE()) CurrentMonthLast_Day,
DATEADD(MONTH,0,GETDATE())-DAY(GETDATE())+1 CurrentMonthFirstt_Day,
DATEADD(MONTH,1,GETDATE())-DAY(GETDATE()-1) NextMonthFirst_Day
The code is missing a minus?
Ah – have no seen it hiding out on its on on my rendering.
:)
Hi you can try that too :)
SELECT DATEDIFF(DAY,GETDATE(),DATEADD(MONTH,1,GETDATE()))