Related
Number of days left in a given month
How do I find the number of days left in the current month?
Example if current month is November and todays date is 16/11/2016
The Numbers of days in month – Elapse days = ? I want to do it dynamically
In my example 30 – 16 = 14
declare #date date
set #date='16 Nov 2016'
select datediff(day, #date, dateadd(month, 1, #date)) - 16 AS DaysLeft
Since this is sql server 2008 you can't use EOMonth (that was introduced in 2012 version).
You have to do some date adds and date diffs:
SELECT DATEDIFF(DAY,
GETDATE(),
DATEADD(MONTH,
1,
DATEADD(DAY, 1 - DAY(GETDATE()), GETDATE())
)
) - 1
explanations:
DATEADD(DAY, 1 - DAY(GETDATE()), GETDATE()) gets the first day of the current month, the wrapping DATEADD adds one month, and the wrapping DATEDIFF returns the number of days between the current date and the first date of the next month. This is why you need to subtruct 1 to get the correct number of days.
--For SQL 2012 And Above Version Use Below Query to Get Count Of Days Left In A Month
DECLARE #date DATE
SET #date=GETDATE()
SELECT DATEDIFF(DAY, #date,EOMONTH(#date))
-- And for Sql Server 2008 Use Below Query to Get Count of Days Left for the Month
DECLARE #date Date
SET #date=GETDATE()
SELECT DATEDIFF(DAY, #date, DATEADD(MONTH, 1, #date)) - DATENAME(DAY,GETDATE())
AS DaysLeft
Simply use the Datepart function:
declare #date date
set #date='16 Nov 2016'
select datediff(day, #date, dateadd(month, 1, #date)) - Datepart(DAY,#date)
Change your date to getdate()
declare #date date
set #date=GETDATE()
select datediff(day, #date, dateadd(month, 1, #date)) - DATENAME(DAY,GETDATE())
AS DaysLeft
DECLARE #date DATE SET #date='16 Nov 2016' SELECT DATEDIFF(DAY, #date,EOMONTH(#date))
Use EOMONTH and DATEDIFF functions
declare #date date
set #date='16 Nov 2016'
select datediff(day,#date,eomonth(#date)) as days_left
Use below solution For Below versions of sql server 2012
DECLARE #DATE DATE
SET #DATE='16 NOV 2016'
SELECT DATEDIFF(DAY,#DATE,DATEADD( MM,DATEDIFF(MM,0,#DATE)+1,0))-1 AS DAYS_LEFT
FUNCTION example
CREATE Or ALTER FUNCTION ReturnDaysLeftInMonth(#Date Date)
RETURNS Int
AS
BEGIN
RETURN DATEDIFF(DAY, #Date, EOMONTH(#Date)) + 1
END
Or use
Declare #Date Date
Set #Date=GETDATE()
DATEDIFF(DAY, #Date, EOMONTH(#Date)) + 1
I need to loop through each day within a month but with a fixed number as the last day of the month.
E.g. If the last day of the month is fixed as 30,
January would become:
Start of Month: Dec 31 2012 12:00AM
End of Month: Jan 30 2013 12:00AM
I have implemented the following which works perfectly except for the month of February. I can't seem to find a solution that will ensure this always works for every month no matter what the month end date is.
Any suggestions are much appreciated.
DECLARE #dt DATETIME
DECLARE #DayInstance DATETIME
DECLARE #LastDayOfMonth DATETIME
DECLARE #monthEndDate INT = 30
SET #dt = '2012-01-01 00:00:00.000'
WHILE #dt < GETDATE()
BEGIN
SET #DayInstance = #dt
SET #LastDayOfMonth = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(DATEADD(mm,1,#dt))),DATEADD(mm,1,#dt)),101))
IF #monthEndDate > 0
BEGIN
SET #LastDayOfMonth = DATEADD(DAY,(#monthEndDate-DATEPART(dd,#LastDayOfMonth)),#LastDayOfMonth)
SET #DayInstance = DATEADD(MONTH, -1, #LastDayOfMonth)
SET #DayInstance = DATEADD(DAY, 1, #DayInstance)
END
PRINT 'Month Start Date: ' + CAST(#DayInstance AS NVARCHAR(20))
PRINT 'Month End Date: ' + CAST(#LastDayOfMonth AS NVARCHAR(20))
PRINT ''
WHILE #DayInstance <= #LastDayOfMonth
BEGIN
-- Going to do more stuff here
SET #DayInstance = DATEADD(DAY, 1, #DayInstance)
END
SET #dt = DATEADD(MONTH, 1, #dt)
END
I think that this query (it can be simplified still further, but I want to show how I was thinking) sets #StartDate and #EndDate to suitable dates - you can then do your iteration between these two values:
DECLARE #dt DATETIME
DECLARE #DayInstance DATETIME
DECLARE #monthEndDate INT = 30
SET #dt = '2012-01-01 00:00:00.000'
DECLARE #MagicDate1 DATETIME
DECLARE #MagicDate2 DATETIME
SELECT #MagicDate1 = DATEADD(day,#monthEndDate-1,'20010101'),
#MagicDate2 = DATEADD(day,#monthEndDate-1,'20001201')
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SELECT #StartDate = DATEADD(day,1,DATEADD(month,DATEDIFF(month,'20010101',#dt),
#MagicDate2)),
#EndDate = DATEADD(month,DATEDIFF(month,'20010101',#dt),#MagicDate1)
select #StartDate,#EndDate
I first construct two "magic" dates. Those are, respectively the Nth day of January 2001 and the Nth day of December 2000, where N is the desired month end date. Notice that the choice of 2000/2001 was arbitrary, and never need to be changed.1
What we then do in the final expressions is to work out how many months have elapsed between January 2001 and your #dt variable. If we then add that same number of months onto our two "magic" dates then we end up with the Nth day of the same month as #dt and the Nth day of the previous month to #dt (Or the last day of either month if the month has fewer than N days).
Finally, we adjust what we've found as the Nth day of last month by adding 1 to it - which should be the "first" day of the current month.
1 The only important thing is to pick two months which both have 31 days and are consecutive in the calendar. The year is arbitrary.
You've slightly over-complicated things I think the following I believe does what you want it to do:
DECLARE #dt DATETIME
DECLARE #LastDayOfMonth DATETIME
SET #dt = '2012-01-01 00:00:00.000'
WHILE #dt < GETDATE()
BEGIN
SET #LastDayOfMonth = DATEADD(DAY,-1,(DATEADD(MONTH,1,#dt)))
PRINT 'Month Start Date: ' + CAST(#dt AS NVARCHAR(20))
PRINT 'Month End Date: ' + CAST(#LastDayOfMonth AS NVARCHAR(20))
PRINT ''
SET #dt = DATEADD(MONTH, 1, #dt)
END
This will work so long as #dt is the first of the month, otherwise you will have to create a new #FirstDayOfMonth variable and set this above the Setting of `#LastDayOfMonth', but the above should be a good starting point.
I am trying to get the specific day of a Year.
Here's what I have tried till now:-
-- Declare few variables
DECLARE #Currentdate AS DATETIME
DECLARE #DueDate AS DATETIME
DECLARE #NewDate AS DATETIME
-- Set the variables properly, just for testing
SET #Currentdate = GETDATE()
SET #DueDate = DATEADD(MONTH, 2, DATEADD(YEAR, 1, #Currentdate))
-- Check the output
SELECT #Currentdate -- 2013-09-30 00:00:00.000
SELECT #DueDate -- 2014-11-30 00:00:00.000
So, I want to get the #NewDate based on the #Currentdate year.
For this I tried:-
SELECT #NewDate = DATEADD(DAY, DAY(DATEDIFF(day, 1, #DueDate)), DATEADD(MONTH, DATEDIFF(MONTH, 0, #Currentdate), 0))
SELECT #NewDate -- 2013-09-30 00:00:00.000
But it didn't worked. :(
My expected result is like:
-- 2013-11-30 00:00:00.000
-- Having the due date month and date same, but the year as current date one.
Any help is appreciated!
UPDATE
Sorry for all the confusion I have created. My question in simple words is:-
I want to get the a new date variable having the date and the month same as #DueDate variable but the year as given in the #Currentdate variable.
I hope that would clear things up a bit.
If the question is "given I have a particular datetime value in one variable, can I set another variable to be for the same day and month but in the current year" then the answer would be:
declare #DueDate datetime
declare #NewDate datetime
set #DueDate = '20141130'
--Need to set #NewDate to the same month and day in the current year
set #NewDate = DATEADD(year,
--Here's how you work out the offset
DATEPART(year,CURRENT_TIMESTAMP) - DATEPART(year,#DueDate),
#DueDate)
select #DueDate,#NewDate
I want to get the a new date variable having the date and the month same as #DueDate variable but the year as given in the #Currentdate variable.
Well, that's simply the above query with a single tweak:
set #NewDate = DATEADD(year,
--Here's how you work out the offset
DATEPART(year,#Currentdate) - DATEPART(year,#DueDate),
#DueDate)
Try this instead ?
DECLARE #Currentdate AS DATETIME
DECLARE #DueDate AS DATETIME
-- Set the variables properly, just for testing
SET #Currentdate = GETDATE()
SET #DueDate = DATEADD(MONTH, 2, DATEADD(YEAR, 1,
DateAdd(day, datediff(day, 0, #currentDate), 0)))
-- Check the output
SELECT #Currentdate -- 2013-09-30 18:32:35.310
SELECT #DueDate
Using DateAdd(day, datediff(day, 0, #DateTime), 0) strips off the time portion. You should also check out this SO Question/answer.
Try this one:
CAST(CAST( -- cast INT to VARCHAR and then to DATE
YEAR(GETDATE()) * 10000 + MONTH(#DueDate) * 100 + DAY(#DueDate) -- convert current year + #DueDate's month and year parts to YYYYMMDD integer representation
+ CASE -- change 29th of February to 28th if current year is a non-leap year
WHEN MONTH(#DueDate) = 2 AND DAY(#DueDate) = 29 AND ((YEAR(GETDATE()) % 4 = 0 AND YEAR(GETDATE()) % 100 <> 0) OR YEAR(GETDATE()) % 400 = 0) THEN 0
ELSE -1
END
AS VARCHAR(8)) AS DATE)
How to get Saturday's Date. I have today's date with me.
GETDATE()
How to do this.
For eg. TODAY is 08-08-2011
I want output as 08-13-2011
This is a function that will return the next Saturday if you call it like this:
SELECT dbo.fn_Get_NextWeekDay('2011-08-08', 6)
The "6" comes from the list of possible values you can set for DATEFIRST.
You can get any other day of the week by changing the second parameter accordingly.
This is the function:
IF OBJECT_ID('dbo.fn_Get_NextWeekDay') IS NOT NULL
DROP FUNCTION dbo.fn_Get_NextWeekDay
GO
CREATE FUNCTION dbo.fn_Get_NextWeekDay(
#aDate DATETIME
, #dayofweek INT
/*
#dw - day of the week
1 - Monday
2 - Tuesday
3 - Wednesday
4 - Thursday
5 - Friday
6 - Saturday
7 - Sunday
*/
)
RETURNS DATETIME
AS
/*
SELECT dbo.fn_Get_NextWeekDay('2011-08-08', 6)
SELECT dbo.fn_Get_NextWeekDay('2011-08-08', 1)
*/
BEGIN
RETURN
DATEADD(day
, ( #dayofweek + 8 - DATEPART(dw, #aDate) - ##DATEFIRST ) % 7
, #aDate
)
END
GO
[EDIT]
This might be another solution. This should work in any language:
IF OBJECT_ID('dbo.fn_NextWeekDay') IS NOT NULL
DROP FUNCTION dbo.fn_NextWeekDay
GO
CREATE FUNCTION dbo.fn_NextWeekDay(
#aDate DATE
, #dayofweek NVARCHAR(30)
)
RETURNS DATE
AS
/*
SELECT dbo.fn_NextWeekDay('2016-12-14', 'fri')
SELECT dbo.fn_NextWeekDay('2016-03-15', 'mon')
*/
BEGIN
DECLARE #dx INT = 6
WHILE UPPER(DATENAME(weekday,#aDate)) NOT LIKE UPPER(#dayofweek) + '%'
BEGIN
SET #aDate = DATEADD(day,1,#aDate)
SET #dx=#dx-1
if #dx < 0
BEGIN
SET #aDate = NULL
BREAK
END
END
RETURN #aDate
END
GO
Use DATEPART to get the day of week of today and add the difference to the desired day of week to todays date.
DECLARE #Today date = 'TODAYS-DATE';
DECLARE #TodayNumber int = DATEPART(dw, #Today) -- Get the day number
DECLARE #Saturday date = DATEADD(DAY, (6-#TodayNumber)%7, #Today)
-- Add the number of days between today and saturday (the 6th day), modulus 7 to stop you adding negative days
Hope that helps!
Use a Calendar table (table with one row per date):
SELECT MIN(DateValue) DateValue
FROM Calendar
WHERE DateValue >= CURRENT_TIMESTAMP
AND DayOfWeek = 'Saturday';
Another approach to this takes two steps, but might be more readable (look ma, no modulus):
Go back to last saturday: DATEADD(DAY, -1 * datepart(weekday, GETDATE()), getdate())
Then, add on a week: DATEADD(WEEK, 1, #lastSaturday, getdate()))
The whole thing:
declare #today DATETIME = GETDATE()
declare #lastSaturday DATETIME = DATEADD(DAY, -1 * datepart(weekday, #today), #today)
declare #nextSaturday DATETIME = DATEADD(WEEK, 1, #lastSaturday)
Or, if you're ok with #today being GETDATE(), you can do the calculation all at once:
SELECT DATEADD(WEEK, 1, DATEADD(DAY, -1 * datepart(weekday, GETDATE()), getdate()))
Checkout the SQL DATEADD function.
DATEADD (Transact-SQL)
Which you can use this along with DATEPART function to return the correct date.
DATEPART (Transact-SQL)
Try this :
SET DATEFIRST 7
DECLARE #d DATETIME
SET #d = '2011-08-08' --GETDATE()
SELECT NEXT_SAT = DATEADD(day, (7 + ##DATEFIRST - DATEPART(dw, #d)) % 7, #d )
declare #Curdate date=( SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(),'+05:30') )
declare #nextsaturdaydate date=(select dateadd(d, 7-datepart(WEEKDAY, #CurDate),#Curdate))
select #nextsaturdaydate
Looking for a way to get the date in the format "11/1/2009", which would be the first sunday of next month. I want to run this query after the first sunday in october to get the first sunday of the upcoming month. What is the best method to accomplish this with a T-SQL query?
Thanks
try this:
Declare #D Datetime
Set #D = [Some date for which you want the following months' first sunday]
Select DateAdd(day, (8-DatePart(weekday,
DateAdd(Month, 1+DateDiff(Month, 0, #D), 0)))%7,
DateAdd(Month, 1+DateDiff(Month, 0, #D), 0))
EDIT Notes:
The first of next Month is given by the expression:
DateAdd(Month, 1+DateDiff(Month, 0, #D), 0)
or by:
which can be modified to give the first of the month two months from now by changing the 1 to a 2:
DateAdd(Month, 2+DateDiff(Month, 0, #D), 0)
EDIT: In response to #NissanFan, and #Anthony: to modify this to return the first Monday Tuesday Wednesday, etc, change the value 8 to a 9, 10, 11, etc....
Declare #Sun TinyInt Set #Sun = 8
Declare #Mon TinyInt Set #Mon = 9
Declare #Tue TinyInt Set #Tue = 10
Declare #Wed TinyInt Set #Wed = 11
Declare #Thu TinyInt Set #Thu = 12
Declare #Fri TinyInt Set #Fri = 13
Declare #Sat TinyInt Set #Sat = 14
Declare #D Datetime, #FONM DateTime -- FirstofNextMonth
Set #D = [Some date for which you want the following months' first sunday]
Set #FONM = DateAdd(Month, 1+DateDiff(Month, 0, #D),0)
Select
DateAdd(day, (#Sun -DatePart(weekday, #FONM))%7, #FONM) firstSunInNextMonth,
DateAdd(day, (#Mon -DatePart(weekday, #FONM))%7, #FONM) firstMonInNextMonth,
DateAdd(day, (#Tue -DatePart(weekday, #FONM))%7, #FONM) firstTueInNextMonth,
DateAdd(day, (#Wed -DatePart(weekday, #FONM))%7, #FONM) firstWedInNextMonth,
DateAdd(day, (#Thu -DatePart(weekday, #FONM))%7, #FONM) firstThuInNextMonth,
DateAdd(day, (#Fri -DatePart(weekday, #FONM))%7, #FONM) firstFriInNextMonth,
DateAdd(day, (#Sat -DatePart(weekday, #FONM))%7, #FONM) firstSatInNextMonth
Just an FYI rather then coming up with some code to do this how about using a calendar table.
Take a look at this: http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html
This also may help:
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=99696
Here is a query to get first working day of next month
DECLARE #DAYOFWEEK INT,#ReminderDate DateTime
SET #DAYOFWEEK = DATEPART( WEEKDAY,DateAdd(D,- Day(GetDate())+1, DATEADD(M,1,GetDate())) )
Print #DAYOFWEEK
If #DAYOFWEEK = 1
Set #ReminderDate = DateAdd(D,- Day(GetDate())+2, DATEADD(M,1,GetDate()))
Else If #DAYOFWEEK =7
Set #ReminderDate = DateAdd(D,- Day(GetDate())+3, DATEADD(M,1,GetDate()))
Else
Set #ReminderDate = DateAdd(D,- Day(GetDate())+1, DATEADD(M,1,GetDate()))
Print #ReminderDate
Reference taken from this blog:
SQL Server 2012 introduced one new TSQL EOMONTH to return the last day of the month that contains the specified date with an optional offset.
CREATE TABLE tbl_Test_EOMONTH
(
SampleDate DATETIME
)
GO
INSERT INTO tbl_Test_EOMONTH VALUES ('2015-12-20')
INSERT INTO tbl_Test_EOMONTH VALUES ('2015-11-08')
INSERT INTO tbl_Test_EOMONTH VALUES ('2015-10-16')
INSERT INTO tbl_Test_EOMONTH VALUES ('2015-09-26')
INSERT INTO tbl_Test_EOMONTH VALUES ('2016-01-31')
GO
SELECT
DATEADD(DAY,8-DATEPART(WEEKDAY,DATEADD(DAY,0,EOMONTH([SampleDate])))
,EOMONTH([SampleDate])) AS FirstSunday_ofTheNextMonth
FROM tbl_Test_EOMONTH
GO
You can use DATENAME to determine the day you want, I might recommend a loop to move the date from the 01 of the month in question to get to the first sunday.
So lets try:
DECLARE #DateTime DATETIME
Set to the date to start off with, then add 1 day until you find what you are looking for. Use datename with dw...
We have used this to determine weekends, but holidays will be a problem, where we use a table to store that.
Try this code as a function:
-- Variables
DECLARE #DATE DATETIME
DECLARE #DAY INT
DECLARE #DAYOFWEEK INT
DECLARE #TESTDATE DATETIME
-- Set
SET #TESTDATE = GETDATE()
SET #DATE = DATEADD( MONTH, 1, #TESTDATE )
SET #DAY = DATEPART( DAY, #TESTDATE )
SET #DATE = DATEADD( DAY, -#DAY + 1, #DATE )
SET #DAYOFWEEK = DATEPART( WEEKDAY, #DATE )
IF #DAYOFWEEK > 1
BEGIN
SET #DAYOFWEEK = 8 - #DAYOFWEEK
END
ELSE
BEGIN
SET #DAYOFWEEK = 0
END
SET #DATE = DATEADD( DAY, #DAYOFWEEK, #DATE )
-- Display
PRINT #TESTDATE
PRINT #DAY
PRINT #DAYOFWEEK
PRINT #DATE
Here is the non-system specific way to determine the first Sunday of the following month:
First, get the current month and add one month.
Next, set the date of that variable to be on the first.
Next, find the day value of that date (let's assume Mondays are 1 and Sundays are 7).
Next, subtract the day value of the 1st of the month from the day value of Sunday (7).
You now have the number of days between the first of the month and the first Sunday. You could then add that to the date variable to get the first Sunday, or, since we know the first of the month is 1, you could just add one to the difference (found in that last step above) and that is the date of the first Sunday. (You have to add one because it's subtracting and thus if the first of the given month IS Sunday, you'd end up with 0).
I have been looking through the T-SQL documentation and it is not at all intuitive as to how how you would use my method, but you will need the concept of "day of week number" to make it work no matter what.
This would be simplest with an auxiliary calendar table. See this link, for example.
However, it can be done without one, though it's rather tricky. Here I assume you want the first future date that is the first Sunday of a month. I've written this with a variable #now for - well - now, so it's easier to test. It might be possible to write more simply, but I think this has a better chance of being correct than quickly-written simpler solutions. [Corrected by adding DAY(d) < 8]
SET #now = GETDATE();
WITH Seven(i) AS (
SELECT -1 UNION ALL SELECT 0 UNION ALL SELECT 1
UNION ALL SELECT 3 UNION ALL SELECT 4
UNION ALL SELECT 5 UNION ALL SELECT 6
), Candidates(d) AS (
SELECT DATEADD(WEEK,i+DATEDIFF(WEEK,'19000107',#now),'19000107')
FROM Seven
)
SELECT TOP (1) d AS SoonestFutureFirstSunday
FROM Candidates
WHERE DAY(d) < 8 AND MONTH(d) >= MONTH(#now)
AND (MONTH(d) > MONTH(#now) OR DAY(d) > DAY(#now))
ORDER BY d; ORDER BY d;
I reckon that the answer is this
SELECT DATEADD(Month, DATEDIFF(Month, 0, GETDATE()) + 1, 0) + 6 - (DATEPART(Weekday,
DATEADD(Month,
DATEDIFF(Month,0, GETDATE()) + 1, 0))
+ ##DateFirst + 5) % 7 --FIRST sunday of following month