Following are two ways of adding days and months to a given date. Both seem to be logically correct but returns different values.
Column number 1: Add months and then days,
Column number 2: Add days and then months
DECLARE #d DATE = '20140128'
SELECT DATEADD(DAY, 3, DATEADD(MONTH, 1, #d)) Add_Months_Days,
DATEADD(MONTH, 1, DATEADD(DAY, 3, #d)) Add_Days_Months
Results and fiddle
Add_Months_Days Add_Days_Months
---------------- ----------------
2014-03-03 2014-02-28
I understand why it is happening and both are logical too. But in a situation where we need to add months and days to a given date at the same time, is there a standard way to do this?
They are both logical but return different results as implicit in your question is the truncation of the add-month result to month-end, should it take you over a month-boundary. You have this in the second query, but not the first.
I believe they are both correct, but they do different things.
MSDN states:
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.
In the first example you first add 1 month to 20140128 making it 20140228 (a valid date) and then add 3 days, ending up with 20140303.
In the second example however you add 3 days, getting 20140131 and then add 1 month, but since February 2014 only has 28 days you'll get 20140228 as the result as the dateadd operation returns the last day of the month as stated above.
I don't believe there is a standard way of doing this, I would think it comes down to the specific business requirements, however I personally think doing month-day and getting the latter end date might be "more correct" as it seem to follow from the intent (the day-month method seem to lose a few days).
Adding MONTH (1) to a date ("20140128"), will not add total days of the month (Jan - 31, Feb - 28 or 29, etc.). It will add the given MONTH value (1) to the input date and result will be "20140228".
Please refer this Question and Answer
Related
I am trying to calculate the number of days that have passed between 1/1/1900 and 5/1/2019.
I have tried this using several dates and get the same out come.
The value returned is 2 days off.
--
-- calculate the number of days between 1/1/1900 and 5/1/2018
--
SELECT DATEDIFF(DAY,CONVERT(DATE,'1/1/1900'),CONVERT(DATE,'5/1/2018'))
Expected Result: 43221
Actual Result: 43219
Thank you for your help!
DATEDIFF returns the number of days between the two dates. So if you want 1900-01-01 to be numbered as day 1, then you must add 1 to any difference you get from DATEDIFF. In Excel, day 0 is 1899-12-31.
Secondly, Excel treats 1900 as a leap year, and has a 29-Feb-1900 (day 60 in the Excel numbering system iirc). This was a holdover from Lotus 1-2-3 which originally used a simplified algorithm for leap years (treating every year divisible by 4 as a leap), and remains for backward compatibility
If you combine these two faults, these account for your off-by-two results.
I hope someone can share their experience with me. I've used the following ssrs expression to default a SSRS report parameter to the last day of the current month for months without issue:
=DateAdd(ādā, -1, DateSerial(Year(Now()), Month(Now()), 1))
This morning instead of returnng 3/31/2016, the expression is stuck on 3/29/2016. Can anyone help me understand why this happened?
You are substracting one day to the first day of the current month.
You have to get the first day of the next month and substract one day.
=DateAdd("d", -1, DateSerial(2016, Month(Now.AddMonths(1)), 1))
It returns 3/31/2016
Let me know if this helps.
The expression you show will give the last day of the previous month, not the last day of this month.
You want to do date arithmetic rather than build dates from scratch. Think about what will happen in December if you are using the current year but adding a month to find the month you need.
The safest way to get the last day of the current month would be to calculate the first day of this month, add one month then subtract a day:
=DateAdd(DateInterval.Day, -1, DateAdd(DateInterval.Month, 1, DateAdd(DateInterval.Day, 1-Day(Today), Today)))
If what you actually want is the last day of the previous month, then that is simple:
=DateAdd(DateInterval.Day, 0-Day(Today), Today)
I'm having a Report where I need to display the dates of last 7 days.
As shown below
Sun, Mon etc... are hard coded and the Dates are written in Expression
For example,
If today is Wednesday I need to show the Dates till last Tuesday.
If it is Thursday I need to show the Dates till last Wednesday.
How to retrieve the dates information and display below the corresponding days.
To get last seven days date you can do something like below in each expression,
To get Days in Header
=WeekdayName(weekday(Parameters!TodaysDate.Value)) --Tuesday
=WeekdayName(weekday(DateAdd("d",1,Parameters!TodaysDate.Value))) --Wedneday
Same for others too... Just by increment/decrement by 1.
To get Days Date in Data
=Format(Parameters!TodaysDate.Value,"dd-MMM-yyyy")
=Format(DateAdd("d", 1, Parameters!TodaysDate.Value),"dd-MMM-yyyy")
Same for others too... Just by increment/decrement by 1.
Here TodaysDate would be parameter date or Now() Date.
I have given demo of incremental one, you can change it as per your condition. I think you need to use decrement here. So Instead of 1 you need to use -1.
This will give you output like below,
I have a stored procedure that runs to pull data for sales in a given month.
It does not return 31 days on months that have 31 days.
I need some help understanding the breakdown of the following string
(dateadd(dd,-(datepart(dd,getdate())),CONVERT(CHAR(8),GetDate(),112)))+'23:59:59')
I understand that CONVERT(CHAR(8),GetDate(),112) is taking the system date and converting to YYYYMMDD and that datepart(dd,getdate()) takes the system date and takes just the day part, but I cannot decipher the entire string.
There is a issue with the expression you have given. The bracket after 23:59:59 does not have a opening brace.
However what the expression intends to do is:
(datepart(dd,getdate())) is getting the the current date's day part
CONVERT(CHAR(8),GetDate(),112)) is getting current date in YYYMMDD
(dateadd(dd,-(datepart(dd,getdate())),CONVERT(CHAR(8),GetDate(),112))) is subtracting the day part from today's date (see the negative sign).
Thus it is trying to get the first day of the current month. In case the result of the above expression crosses the last day of the previous month, it adds 23 hours 59 minutes.
The logic was probably intended to get the last day of the previous month. This adding of ~24 hours is creating confusion.
This will help you out:
declare #First datetime = dateadd(month,datediff(month,0,getdate()),0)
declare #Last datetime = dateadd(second,-1,dateadd(month,datediff(month,0,getdate())+1,0))
#First checks for the number of months from ZERO to NOW, then adds that number of months to ZERO to give you the first moment of this month.
#Last works similarly, but adds one month to the number of months added to ZERO to give you the first moment of next month, then it subtracts 1 second from that date to give you the last second of the last day of this month.
If you need to go to MS, you can change the last bit to subtract 3 miliseconds instead of 1 second.
As I understand it, there are 2 main ways to add/subtract days to a date/datetime in MS SQL Server:
For example, to add one day, there is:
GETDATE() + 1
DATEADD(day, 1, GETDATE())
Is there any advantage or disadvantage to either approach?
No real advantages except that when you use GETDATE()+1 we don't really know what you are adding (days, months, hours, seconds?).
DATEADD makes it explicit and also ease your job when you need to add something else than days.
In my opinion GetDate()+1 will add just 1 day to current date, there is no way to add months or years in current date, but if you want to add month, year, hours etc o than DATEADD provide various options using that you can get past\future dates based on current date.
So if you are trying to add just day, than both would have same impact.
Thanks
Suresh