Finding week start and week end date - sql

I have a week number and year and i need to display "total for mm/dd/yy to mm/dd/yy in a row of my ssrs report. My week starts with Monday. For example if my week number is '2' and year is '2010' then I have to display "total for 01/04/2010 to 01/10/2010 in my ssrs column. how to do this?

Try this
declare #year char(4) = '2010'
declare #week int = 2
declare #fromdate datetime
declare #todate datetime
set #fromdate = DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + #year) + (#week-1), 7);
set #todate = DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + #year) + (#week-1), 6) ;
;WITH dates AS
(
SELECT CONVERT(datetime,#fromDate) as Date
UNION ALL
SELECT DATEADD(d,1,[Date])
FROM dates
WHERE DATE < #toDate
)
select * from dates

SQL Server has a DATEPART function which calculates the ordinal week number of a year. However, you have to call DATEFIRST before this to define which day of the week represents the start of the week. In your case, you have stated that the start of your week is Monday (i.e. 1).
SET DATEFIRST 1;
SELECT SUM([your data column])
FROM [your table]
WHERE DATEPART(WEEKNUM, [your date column])=[your week parameter]
AND DATEPART(YEAR, [your date column])=[your year parameter]

Your description is not american standard nor isoweek. Seems like a mix of those. I never heard of that as a standard. It is nearly isoweek. So that is what this answer is based on.
Calculating iso year is a bit tricky, you can read about it here:
This is the syntax you need:
DECLARE #year int = 2010
DECLARE #week int = 2
;WITH CTE AS
(
SELECT
dateadd(wk, datediff(wk, - #week * 7,
cast(cast(#year as char(4)) as datetime) - 5), 0) startofweek
)
SELECT
replace('total for ' + convert(char(10), startofweek, 110)
+ ' to ' + convert(char(10), dateadd(day, 6, startofweek) , 110), '-', '/')
FROM CTE
Result:
total for 01/11/2010 to 01/17/2010
Isoweek 2 in 2010 is 2010-01-11

Try setting DATEFIRST (https://msdn.microsoft.com/en-ie/library/ms181598.aspx)
SET DATEFIRST 7
declare #wk int
declare #yr int
declare #EndOfWeek as datetime
set #wk = 2
set #yr = 2010
SET #EndOfWeek = dateadd (week, #wk, dateadd (year, #yr-1900, 0)) + 1 - datepart(dw, dateadd (week, #wk, dateadd (year, #yr-1900, 0)) )
SELECT
replace('total for ' + convert(char(10), dateadd(day, -6, #EndOfWeek) , 110)
+ ' to ' + convert(char(10), #EndOfWeek, 110), '-', '/')
The result:
total for 01/04/2010 to 01/10/2010

I hope it helps:
declare #year char(4) = '2014'
declare #week int = 2
select dateadd(week,#week,convert(date,#year+'-01-01',121))
Change the date format appropriate for you from this list

Related

replace calendar dateto/from with year,month,day dropdown menus in ssrs

best way to do this would be to have parameters which link the day dropdown column to the month one so that there are correct days in every month?
You would also need to use your Year parameter for a leap day in February.
I would use a table of dates based on your other parameters:
DECLARE #YEAR AS INT = 2016 --FOR DEV/TESTING - REFERENCE PARAMETERS
DECLARE #MONTH AS INT = 2 --FOR DEV/TESTING
DECLARE #START_DATE DATE = CAST(#YEAR AS VARCHAR(4)) + '-' + RIGHT('0' + CAST(#MONTH AS VARCHAR(2)), 2) + '-' + '01'
DECLARE #END_DATE DATE = DATEADD(DAY, -1, DATEADD(MONTH, 1, #START_DATE))
;WITH GETDATES AS
(
SELECT #START_DATE AS THEDATE
UNION ALL
SELECT DATEADD(DAY,1, THEDATE) FROM GETDATES
WHERE THEDATE < #END_DATE
)
SELECT DAY(GETDATES.THEDATE) AS DAYS FROM GETDATES
OPTION (maxrecursion 0)

SQL Get "ISO Year" for ISO Week

I need to calculate the year a week is assigned to. For example the 29th december of 2003 was assigned to week one of year 2004 (this is only for europe, I think). You can take a look at this with this code:
SELECT DATEPART(isowk, '20141229');
But now I need an easy way to get the year this week is assigned to. What I currently do is not that elegant:
DECLARE #week int, #year int, #date char(8)
--set #date = '20150101'
set #date = '20141229'
SET #week = cast(datepart(isowk, #date) as int)
if #week = 1
begin
if DATEPART(MONTH, #date) = 12
begin
set #year = DATEPART(year, #date) + 1
end
else
begin
set #year = DATEPART(year, #date)
end
end
select #date "DATE", #week "WEEK", #year "YEAR"
If anybody knew a more elegant way, that would be nice :-)
This solution The code in the question does not return the correct value for the date '1-1-2027'.
The following will return the correct value with all dates i tested (and i tested quite a few).
SELECT YEAR(DATEADD(day, 26 - DATEPART(isoww, '2012-01-01'), '2012-01-01'))
As taken from: https://capens.net/content/sql-year-iso-week
This is the most compact solution I could come up with:
CASE
WHEN DATEPART(ISO_WEEK, #Date) > 50 AND MONTH(#Date) = 1 THEN YEAR(#Date) - 1
WHEN DATEPART(ISO_WEEK, #Date) = 1 AND MONTH(#Date) = 12 THEN YEAR(#Date) + 1
ELSE YEAR(#Date) END
Can be used directly inside a SELECT statement. Or you could consider creating a user-defined function that takes the #Date parameter as input and outputs the result of the case statement.
I think this solution is much more logical and easier to comprehend for ISO-8601.
"The first week of the year is the week containing the first Thursday."
see ISO Week definition
So we need to deduct the weekday of the given date from Thursday and add this to that same date to get the year.
Adding 5 and then taking the modulus of 7 to move Sunday to the previous week.
declare #TestDate date = '20270101'
select year(dateadd(day, 3 - (datepart(weekday, #TestDate) + 5) % 7, #TestDate))
This will result in 2026 which is correct.
This will give the correct result for all dates I check between 1990-2100 using this:
declare #TestDate date = '19900101'
declare #Results as table
(
TestDate date,
FirstDayofYear varchar(20),
ISOYear int,
ISOWeek int
)
while (#TestDate < '21000201')
begin
insert #Results(TestDate, FirstDayofYear, ISOYEar, ISOWeek)
select #TestDate, datename(weekday, dateadd(day, datepart(day, #TestDate) * -1 +1, #TestDate)),
year(dateadd(day, 3 - (datepart(weekday, #TestDate) + 5) % 7, #TestDate)), datepart(ISOWK, #TestDate)
set #TestDate = dateadd(day, 1, #Testdate)
if(datepart(day, #TestDate) > 7)
begin
set #TestDate = dateadd(year, 1, dateadd(day, datepart(day, #TestDate) * -1 + 1, #TestDate))
end
end
-- Show all results that are wrong:
select * from #Results
where (ISOYear <> datepart(year, TestDate) and ISOWeek < 3)
or (ISOYear = datepart(year, TestDate) and ISOWeek >= 52)
I think Bart Vanseer solution is nice and simple, but off by 1.
I believe it should be
select year(dateadd(day, 3 - ((datepart(weekday, #TestDate) + 5) % 7) , #TestDate))
Try following to find a few places were it differs
declare #TestDate date = '2000-01-01'
DECLARE #cnt INT = 0;
DECLARE #cnt_total INT = 10000;
WHILE #cnt < #cnt_total
BEGIN
SET #TestDate = dateadd(day,1, #TestDate)
if year(dateadd(day, 3 - (datepart(weekday, #TestDate) + 6) % 8, #TestDate)) <>
year(dateadd(day, 3 - ((datepart(weekday, #TestDate) + 5) % 7) , #TestDate))
BEGIN
select #TestDate, year(dateadd(day, 3 - (datepart(weekday, #TestDate) + 6) % 8, #TestDate))
select #TestDate, year(dateadd(day, 3 - ((datepart(weekday, #TestDate) + 5) % 7) , #TestDate))
END
SET #cnt = #cnt + 1;
END;
Inspired by the other answers, i came to the following solution:
declare #TestDate date = '20270101'
SELECT DATEPART(year, DATEADD(day, 4 - DATEPART(weekday, #TestDate), #TestDate))
Just get thursday of the current week to get the correct year.
Assuming DATEFIRST is set to Monday (1).
DECLARE #date DATETIME
SET #date='2014-12-29'
SELECT
CASE --Covers logic for ISO week date system which is part of the ISO 8601 date and time standard. Ref: https://en.wikipedia.org/wiki/ISO_week_date
WHEN (DATEPART(ISO_WEEK,#date) = 53) AND (DATEPART(MONTH,#date) = 1)
THEN CAST((DATEPART(YEAR, #date) - 1) AS varchar(4)) + ('-W') + CAST (RIGHT('0' + CAST(DATEPART(ISO_WEEK,#date) AS varchar(2)),2) AS varchar(2))
WHEN (DATEPART(ISO_WEEK,#date) = 1) AND (DATEPART(MONTH,#date) = 12)
THEN CAST((DATEPART(YEAR,#date) + 1) AS varchar(4)) + ('-W') + CAST (RIGHT('0' + CAST(DATEPART(ISO_WEEK,#date) AS varchar(2)),2) AS varchar(2))
ELSE CAST(DATEPART(YEAR,#date) AS varchar(4)) + ('-W') + CAST (RIGHT('0' + CAST(DATEPART(ISO_WEEK,#date) AS varchar(2)),2) AS varchar(2))
END AS ISO_week
For IsoYear, get the Thursday from IsoWeek, and then get the year.

SQL Server : get date with inparameters year,week,weekday

I have searched and have yet to find this little helpful snippet.
I want to input...
Year (2014)
Weeknumber (2)
Weekday (2 = Tuesday, in my case)
Expected result: 2014-01-07 (seventh of January)
And get the full date in return, anyone?
EDIT: My server is SQL 2008
The finished code thanks to all!.
declare #year int = 2014
declare #weeknr int = 2
declare #daynroffset int = 2
SELECT
DATEADD(DAY,+ (#daynroffset-1),
DATEADD(DAY,-DATEPART(DW,CAST('1/1/' + cast(#year as varchar) AS Date))+2,DATEADD(WK,#weeknr- 1,CAST('1/1/' + cast(#year as varchar) AS Date)))
)
The other answers (so far) use SQL Server default mechanisms to determine week and day of week. In this case the current language setting determines the day of the week (through the ##DATEFIRST setting) and the DATEPART(wk uses Jan 1st as the fixed date contained in week 1.
To get a deterministic answer independent of the language setting one can use the ISO 8601 week standard which starts a week on Mondays and where the first week always contains Jan 4th.
This code determines the date based on ISO weeks:
declare #year int = 2016
declare #isoweek int = 22
declare #isoday int = 2
-- ISO-WEEK 1 always contains 4th Jan, so let's use this as a base
declare #date datetime = cast(cast(#year as varchar(4)) + '-01-04T12:00:00' as datetime)
-- Offset the wanted DayOfWeek versus our base date
-- We also set DATEFIRST temporarily because it affects DayOfWeek
-- ISO-Weeks always start on Monday
declare #datefirst int = ##DATEFIRST
SET DATEFIRST 1
declare #offset int = datepart(dw, #date) - 1
SET DATEFIRST #datefirst
-- Add given day and week to basedate
set #date = dateadd(day, #isoday - 1 - #offset, dateadd(wk, #isoweek - 1, #date))
print #date
CODE:
2012+:
DATEADD(DAY,-DATEPART(DW,DATEFROMPARTS("YEAR",1,1))+1+"DAY OF WEEK",DATEADD(WK,"WEEK NUMBER"-1,DATEFROMPARTS(2014,1,1)))
2008+:
SELECT DATEADD(DAY,-DATEPART(DW,CAST(CONCAT('1/1/',"YEAR") AS Date))+1+"DAY OF WEEK",DATEADD(WK,"WEEK NUMBER"-1,CAST(CONCAT('1/1/',"YEAR") AS Date)))
Simply substitue the values where necessary.
This will work for any date.
declare #year int = 2014
declare #week int = 2
declare #day int = 2
declare #date datetime = cast(cast(#year as varchar(20)) + '-01-01' as datetime)
declare #offset int = datepart(dw, #date) - 1
set #date = dateadd(day, #day - #offset, dateadd(ww, #week - 1, #date))
print #date
This may have issues near the year boundary, but it works for the example data given. You may want to add further validations. I've broken down each step of the datetime manipulation into a new field, so you can see it being constructed
2008
DECLARE #Year INT = 2014
DECLARE #WeekNum INT = 2
DECLARE #WeekDay INT = 2
SELECT
BaseDate = CAST( #year AS VARCHAR(4) )
, RoundToWeekStart = DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST( #year AS VARCHAR(4) )), 0) -- Will be a Monday
, AddWeeksToRoundedDate = DATEADD(WEEK, #WeekNum - 1, DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST( #year AS VARCHAR(4) )), 0) )
, AddWeekDay = DATEADD( DAY, #WeekDay - 1, DATEADD(WEEK, #WeekNum - 1, DATEADD(WEEK, DATEDIFF(WEEK, 0, CAST( #year AS VARCHAR(4) )), 0) ) )
2012+
DECLARE #Year INT = 2014
DECLARE #WeekNum INT = 2
DECLARE #WeekDay INT = 2
SELECT
BaseDate = DATEFROMPARTS(#Year, 1, 1)
, RoundToWeekStart = DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEFROMPARTS(#Year, 1, 1)), 0) -- Will be a Monday
, AddWeeksToRoundedDate = DATEADD(WEEK, #WeekNum - 1, DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEFROMPARTS(#Year, 1, 1)), 0) )
, AddWeekDay = DATEADD( DAY, #WeekDay - 1, DATEADD(WEEK, #WeekNum - 1, DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEFROMPARTS(#Year, 1, 1)), 0) ) )

Date Value from a week number in SQL [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Get dates from a week number in T-SQL
How do I get the date value if I have a week number in SQL Query.
Like if I pass 26, it should give me 06/24/2012. If I pass 27, I should get 07/01/2012
Any help will be appreciated :)
Sots
SELECT DATEADD(week, n, '11/25/2011');
with n being the week number
If this doesn't work, try using WEEK() instead of WEEKOFYEAR().
CURDATE() - INTERVAL WEEKDAY(CURDATE()) DAY + INTERVAL (WEEKNO - WEEKOFYEAR(CURDATE())) WEEK
In SQL Server
DECLARE #StartDate DATE, #WeekVal INT
SET #WeekVal = 26 -- Set the week number
SET #StartDate = DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0) -- Start of current year
;WITH cte AS (
SELECT #StartDate AS DateVal, DATEPART(wk, #StartDate) AS WeekVal, 1 AS RowVal
UNION ALL
SELECT DATEADD(d, 1, DateVal), DATEPART(wk, DATEADD(d, 1, DateVal)), RowVal + 1
FROM cte WHERE RowVal < 365
)
SELECT MIN(DateVal) StartOfWeek
FROM cte
WHERE WeekVal = #WeekVal
OPTION (MAXRECURSION 365);
This gives you the start and end dates of the week. [For SQL Server]
Declare #week integer set #week = 26
Declare #Year Integer Set #Year = year(getdate())
declare #date datetime
-- ------------------------------------
Set #date = DateAdd(day, 0,
DateAdd(month, 0,
DateAdd(Year, #Year-1900, 0)))
set #date = Dateadd(week, #week-1, #date)
select #date startweek, DATEADD (D, -1 * DatePart (DW, #date) + 7, #date) endweek
This was the result from it:
startweek endweek
----------------------- -----------------------
2012-07-01 00:00:00.000 2012-07-07 00:00:00.000
(1 row(s) affected)

How to determine the number of days in a month in SQL Server?

I need to determine the number of days in a month for a given date in SQL Server.
Is there a built-in function? If not, what should I use as the user-defined function?
In SQL Server 2012 you can use EOMONTH (Transact-SQL) to get the last day of the month and then you can use DAY (Transact-SQL) to get the number of days in the month.
DECLARE #ADate DATETIME
SET #ADate = GETDATE()
SELECT DAY(EOMONTH(#ADate)) AS DaysInMonth
You can use the following with the first day of the specified month:
datediff(day, #date, dateadd(month, 1, #date))
To make it work for every date:
datediff(day, dateadd(day, 1-day(#date), #date),
dateadd(month, 1, dateadd(day, 1-day(#date), #date)))
Most elegant solution: works for any #DATE
DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,#DATE),0)))
Throw it in a function or just use it inline. This answers the original question without all the extra junk in the other answers.
examples for dates from other answers:
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'1/31/2009'),0))) Returns 31
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2404-feb-15'),0))) Returns 29
SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,'2011-12-22'),0))) Returns 31
--Last Day of Previous Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)))
--Last Day of Current Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)))
--Last Day of Next Month
SELECT DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0)))
Personally though, I would make a UDF for it if there is not a built in function...
I would suggest:
SELECT DAY(EOMONTH(GETDATE()))
This code gets you the number of days in current month:
SELECT datediff(dd,getdate(),dateadd(mm,1,getdate())) as datas
Change getdate() to the date you need to count days for.
--- sql server below 2012---
select day( dateadd(day,-1,dateadd(month, 1, convert(date,'2019-03-01'))))
-- this for sql server 2012--
select day(EOMONTH(getdate()))
Solution 1: Find the number of days in whatever month we're currently in
DECLARE #dt datetime
SET #dt = getdate()
SELECT #dt AS [DateTime],
DAY(DATEADD(mm, DATEDIFF(mm, -1, #dt), -1)) AS [Days in Month]
Solution 2: Find the number of days in a given month-year combo
DECLARE #y int, #m int
SET #y = 2012
SET #m = 2
SELECT #y AS [Year],
#m AS [Month],
DATEDIFF(DAY,
DATEADD(DAY, 0, DATEADD(m, ((#y - 1900) * 12) + #m - 1, 0)),
DATEADD(DAY, 0, DATEADD(m, ((#y - 1900) * 12) + #m, 0))
) AS [Days in Month]
You do need to add a function, but it's a simple one. I use this:
CREATE FUNCTION [dbo].[ufn_GetDaysInMonth] ( #pDate DATETIME )
RETURNS INT
AS
BEGIN
SET #pDate = CONVERT(VARCHAR(10), #pDate, 101)
SET #pDate = #pDate - DAY(#pDate) + 1
RETURN DATEDIFF(DD, #pDate, DATEADD(MM, 1, #pDate))
END
GO
SELECT Datediff(day,
(Convert(DateTime,Convert(varchar(2),Month(getdate()))+'/01/'+Convert(varchar(4),Year(getdate())))),
(Convert(DateTime,Convert(varchar(2),Month(getdate())+1)+'/01/'+Convert(varchar(4),Year(getdate()))))) as [No.of Days in a Month]
select datediff(day,
dateadd(day, 0, dateadd(month, ((2013 - 1900) * 12) + 3 - 1, 0)),
dateadd(day, 0, dateadd(month, ((2013 - 1900) * 12) + 3, 0))
)
Nice Simple and does not require creating any functions Work Fine
You need to create a function, but it is for your own convenience. It works perfect and I never encountered any faulty computations using this function.
CREATE FUNCTION [dbo].[get_days](#date datetime)
RETURNS int
AS
BEGIN
SET #date = DATEADD(MONTH, 1, #date)
DECLARE #result int = (select DAY(DATEADD(DAY, -DAY(#date), #date)))
RETURN #result
END
How it works: subtracting the date's day number from the date itself gives you the last day of previous month. So, you need to add one month to the given date, subtract the day number and get the day component of the result.
select add_months(trunc(sysdate,'MM'),1) - trunc(sysdate,'MM') from dual;
I upvoted Mehrdad, but this works as well. :)
CREATE function dbo.IsLeapYear
(
#TestYear int
)
RETURNS bit
AS
BEGIN
declare #Result bit
set #Result =
cast(
case when ((#TestYear % 4 = 0) and (#testYear % 100 != 0)) or (#TestYear % 400 = 0)
then 1
else 0
end
as bit )
return #Result
END
GO
CREATE FUNCTION dbo.GetDaysInMonth
(
#TestDT datetime
)
RETURNS INT
AS
BEGIN
DECLARE #Result int
DECLARE #MonthNo int
Set #MonthNo = datepart(m,#TestDT)
Set #Result =
case #MonthNo
when 1 then 31
when 2 then
case
when dbo.IsLeapYear(datepart(yyyy,#TestDT)) = 0
then 28
else 29
end
when 3 then 31
when 4 then 30
when 5 then 31
when 6 then 30
when 7 then 31
when 8 then 31
when 9 then 30
when 10 then 31
when 11 then 30
when 12 then 31
end
RETURN #Result
END
GO
To Test
declare #testDT datetime;
set #testDT = '2404-feb-15';
select dbo.GetDaysInMonth(#testDT)
here's another one...
Select Day(DateAdd(day, -Day(DateAdd(month, 1, getdate())),
DateAdd(month, 1, getdate())))
I know this question is old but I thought I would share what I'm using.
DECLARE #date date = '2011-12-22'
/* FindFirstDayOfMonth - Find the first date of any month */
-- Replace the day part with -01
DECLARE #firstDayOfMonth date = CAST( CAST(YEAR(#date) AS varchar(4)) + '-' +
CAST(MONTH(#date) AS varchar(2)) + '-01' AS date)
SELECT #firstDayOfMonth
and
DECLARE #date date = '2011-12-22'
/* FindLastDayOfMonth - Find what is the last day of a month - Leap year is handled by DATEADD */
-- Get the first day of next month and remove a day from it using DATEADD
DECLARE #lastDayOfMonth date = CAST( DATEADD(dd, -1, DATEADD(mm, 1, FindFirstDayOfMonth(#date))) AS date)
SELECT #lastDayOfMonth
Those could be combine to create a single function to retrieve the number of days in a month if needed.
SELECT DAY(SUBDATE(ADDDATE(CONCAT(YEAR(NOW()), '-', MONTH(NOW()), '-1'), INTERVAL 1 MONTH), INTERVAL 1 DAY))
Nice 'n' Simple and does not require creating any functions
Mehrdad Afshari reply is most accurate one, apart from usual this answer is based on formal mathematical approach given by Curtis McEnroe in his blog https://cmcenroe.me/2014/12/05/days-in-month-formula.html
DECLARE #date DATE= '2015-02-01'
DECLARE #monthNumber TINYINT
DECLARE #dayCount TINYINT
SET #monthNumber = DATEPART(MONTH,#date )
SET #dayCount = 28 + (#monthNumber + floor(#monthNumber/8)) % 2 + 2 % #monthNumber + 2 * floor(1/#monthNumber)
SELECT #dayCount + CASE WHEN #dayCount = 28 AND DATEPART(YEAR,#date)%4 =0 THEN 1 ELSE 0 END -- leap year adjustment
To get the no. of days in a month we can directly use Day() available in SQL.
Follow the link posted at the end of my answer for SQL Server 2005 / 2008.
The following example and the result are from SQL 2012
alter function dbo.[daysinm]
(
#dates nvarchar(12)
)
returns int
as
begin
Declare #dates2 nvarchar(12)
Declare #days int
begin
select #dates2 = (select DAY(EOMONTH(convert(datetime,#dates,103))))
set #days = convert(int,#dates2)
end
return #days
end
--select dbo.daysinm('08/12/2016')
Result in SQL Server SSMS
(no column name)
1 31
Process:
When EOMONTH is used, whichever the date format we use it is converted into DateTime format of SQL-server. Then the date output of EOMONTH() will be 2016-12-31 having 2016 as Year, 12 as Month and 31 as Days.
This output when passed into Day() it gives you the total days count in the month.
If we want to get the instant result for checking we can directly run the below code,
select DAY(EOMONTH(convert(datetime,'08/12/2016',103)))
or
select DAY(EOMONTH(convert(datetime,getdate(),103)))
for reference to work in SQL Server 2005/2008/2012, please follow the following external link ...
Find No. of Days in a Month in SQL
DECLARE #date DATETIME = GETDATE(); --or '12/1/2018' (month/day/year)
SELECT DAY(EOMONTH ( #date )) AS 'This Month';
SELECT DAY(EOMONTH ( #date, 1 )) AS 'Next Month';
result:
This Month
31
Next Month
30
DECLARE #m int
SET #m = 2
SELECT
#m AS [Month],
DATEDIFF(DAY,
DATEADD(DAY, 0, DATEADD(m, +#m -1, 0)),
DATEADD(DAY, 0, DATEADD(m,+ #m, 0))
) AS [Days in Month]
RETURN day(dateadd(month, 12 * #year + #month - 22800, -1))
select day(dateadd(month, 12 * year(date) + month(date) - 22800, -1))
A cleaner way of implementing this is using the datefromparts function to construct the first day of the month, and calculate the days from there.
CREATE FUNCTION [dbo].[fn_DaysInMonth]
(
#year INT,
#month INT
)
RETURNS INT
AS
BEGIN
IF #month < 1 OR #month > 12 RETURN NULL;
IF #year < 1753 OR #year > 9998 RETURN NULL;
DECLARE #firstDay DATE = datefromparts(#year, #month, 1);
DECLARE #lastDay DATE = dateadd(month, 1, #firstDay);
RETURN datediff(day, #firstDay, #lastDay);
END
GO
Similarily, you can calculate the days in a year:
CREATE FUNCTION [dbo].[fn_DaysInYear]
(
#year INT
)
RETURNS INT
AS
BEGIN
IF #year < 1753 OR #year > 9998 RETURN NULL;
DECLARE #firstDay DATE = datefromparts(#year, 1, 1);
DECLARE #lastDay DATE = dateadd(year, 1, #firstDay);
RETURN datediff(day, #firstDay, #lastDay);
END
GO
use SQL Server EOMONTH Function nested with day to get last day of month
select Day(EOMONTH('2020-02-1')) -- Leap Year returns 29
select Day(EOMONTH('2021-02-1')) -- returns 28
select Day(EOMONTH('2021-03-1')) -- returns 31
For any date
select DateDiff(Day,#date,DateAdd(month,1,#date))
select first_day=dateadd(dd,-1*datepart(dd,getdate())+1,getdate()),
last_day=dateadd(dd,-1*datepart(dd,dateadd(mm,1,getdate())),dateadd(mm,1,getdate())),
no_of_days = 1+datediff(dd,dateadd(dd,-1*datepart(dd,getdate())+1,getdate()),dateadd(dd,-1*datepart(dd,dateadd(mm,1,getdate())),dateadd(mm,1,getdate())))
replace any date with getdate to get the no of months in that particular date
DECLARE #Month INT=2,
#Year INT=1989
DECLARE #date DateTime=null
SET #date=CAST(CAST(#Year AS nvarchar) + '-' + CAST(#Month AS nvarchar) + '-' + '1' AS DATETIME);
DECLARE #noofDays TINYINT
DECLARE #CountForDate TINYINT
SET #noofDays = DATEPART(MONTH,#date )
SET #CountForDate = 28 + (#noofDays + floor(#noofDays/8)) % 2 + 2 % #noofDays + 2 * floor(1/#noofDays)
SET #noofDays= #CountForDate + CASE WHEN #CountForDate = 28 AND DATEPART(YEAR,#date)%4 =0 THEN 1 ELSE 0 END
PRINT #noofDays
DECLARE #date nvarchar(20)
SET #date ='2012-02-09 00:00:00'
SELECT DATEDIFF(day,cast(replace(cast(YEAR(#date) as char)+'-'+cast(MONTH(#date) as char)+'-01',' ','')+' 00:00:00' as datetime),dateadd(month,1,cast(replace(cast(YEAR(#date) as char)+'-'+cast(MONTH(#date) as char)+'-01',' ','')+' 00:00:00' as datetime)))
simple query in SQLServer2012 :
select day(('20-05-1951 22:00:00'))
i tested for many dates and it return always a correct result