To get difference between 2 dates - sql

I have 2 dates. I want to get number of days between 2 dates in storedprocedure.

DateDiff function should do what you need
declare #var1 Datetime
declare #var2 Datetime
set #var1 = '2009-04-01'
set #var2 = '2009-04-16'
SELECT datediff(day,#var1, #var2 )

How about using the dateDiff function ?
eg
DECLARE #Dt INT
SET #Dt = DATEDIFF(dd,#StartDate,#EndDate)
should do the trick ?
Or did I miss something ?

USE tempdb
DECLARE #DATE1 datetime
DECLARE #DATE2 datetime
SET #DATE1 = '01/01/2000'
SET #DATE2 = '02/01/2000'
SELECT DATEDIFF(day, #DATE1, #DATE2)

DATEDIFF is the way to do it

Note that DATEDIFF only concerns itself with the date portion. If times are involved, a converted subtraction might yield better results.
DECLARE #start DATETIME
DECLARE #end DATETIME
SET #start = '20090514 00:00:00'
SET #end = '20090514 23:59:59'
PRINT CONVERT(FLOAT, (#end-#start)) -- 0.999988
PRINT DATEDIFF(DAY,#start,#end) -- 0

Related

Date losing value when being stored

I'm trying to get a set of dates into a particular format (ddmmyy) so that they can be run against a number of scripts that I have.
I have managed to convert the date into the correct format, but when I try to store this as a variable it just returns as null or the un-formatted date.
DECLARE #CurrentDate SMALLDATETIME
SELECT #CurrentDate = getdate()
SELECT #CurrentDate = DATEADD(day, -1, #CurrentDate)
SELECT #CurrentDate = STR_REPLACE(CONVERT(varchar,#CurrentDate,3),'/',null)
--Returns this:
20-Mar-2002 00:00:00
DECLARE #CurrentDate SMALLDATETIME
SELECT #CurrentDate = getdate()
SELECT #CurrentDate = DATEADD(day, -1, #CurrentDate)
SELECT STR_REPLACE(CONVERT(varchar,#CurrentDate,3),'/',null)
--Returns this:
020320
I believe the problem comes from the fact that my declared variable is a smalldatetime object but I'm not sure of how to convert it correctly into a string that can be stored as a variable?
I've tried having a second variable and declaring it as a varchar and then storing my date as the varchar but this isn't working either:
DECLARE #CurrentDate SMALLDATETIME
DECLARE #CurrentDateFinal VARCHAR
SELECT #CurrentDate = getdate()
SELECT #CurrentDate = DATEADD(day, -1, #CurrentDate)
SELECT #CurrentDateFinal = CAST(STR_REPLACE(#CurrentDate,'/',null) AS VARCHAR)
--Returns this:
03-Mar-2020 00:00:00
You can do the current date amendment with the dateadd all in one line - there's no need to do two lines. The below gives you the DDMMYY output although I wouldn't use that format personally as you can come unstuck with regional differences (e.g. US prefer MMDDYY and UK tends to be DDMMYY). Also always use 4 digit years IMO.
DECLARE #FirstDate SMALLDATETIME
DECLARE #FinalDate varchar(20)
SELECT #FirstDate = DATEADD(day, -1,getdate())
set #FinalDate = STR_REPLACE(CONVERT(varchar,#FirstDate,3),'/',null)
SELECT #FinalDate
--------------------
030320
(1 row affected)

How to check if DateTime lies within String times?

DECLARE #CurDate datetime,
#Begintime nvarchar(10),
#Endtime nvarchar(10)
SELECT #CurDate = GETDATE()
SELECT #Begintime = '9:00 AM'
SELECT #Endtime = '5:00 PM'
What is the best way to check if the CurDate lies within the given times? Thanks!
With SQL Server 2008 and higher, you can convert your current time, and the begin and end times (as nvarchar) into TIME variables and then do the check:
DECLARE #CurrTime TIME = CAST(#CurDate AS TIME)
DECLARE #TimeFrom TIME = CAST(#Begintime AS TIME)
DECLARE #TimeTo TIME = CAST(#Endtime AS TIME)
SELECT
#CurrTime, #TimeFrom, #TimeTo,
CASE
WHEN #CurrTime BETWEEN #TimeFrom AND #TimeTo THEN 'Yes!'
ELSE 'No, sorry'
END
Use the function DATEDIFF to calculate the hours and minutes difference.
Here -> https://msdn.microsoft.com/en-us/library/ms189794.aspx
I wouldn't use use nvarchar, but instead of it use something like this:
#BeginTime = DATEADD(hour, 9, CONVERT(datetime,CONVERT(date,getdate())))
#EndTime = DATEADD(hour, 17, CONVERT(datetime,CONVERT(date,getdate())))
The condition to use can be:
WHERE #CurDate BETWEEN #BeginTime AND #EndTime
Best regards,

datediff not returning what I'm expecting

Anyone know why the following is returning 8? I'm expecting 8 hours 30 minutes, or 8.5?
declare #start_day datetime;
declare #end_day datetime;
declare #start_time datetime;
declare #end_time datetime;
set #start_day = '2014-06-18';
set #end_day = '2014-06-18';
set #start_time = '09:00';
set #end_time = '17:30';
print datediff(hour,#start_day + #start_time, #end_day + #end_time);
Try this, CAST your DATEDIFF of the minutes to float then divide by 60 to get the hours.
declare #start_day datetime;
declare #end_day datetime;
declare #start_time datetime;
declare #end_time datetime;
set dateformat ymd
set #start_day = '2014-06-18';
set #end_day = '2014-06-18';
set #start_time = '09:00';
set #end_time = '17:30';
print cast(datediff(minute,#start_day + #start_time, #end_day + #end_time) as float) / 60;
Try this :
print cast(datediff(mi,#start_day + #start_time, #end_day + #end_time)
as decimal(10,2))/60;
it returns the number of fully elapsed hours.
if you want to have 8.5 return minutes and then divide by 60.0.
You have hour as a datepart, the documentation states:
DATEDIFF
Returns the count (signed integer) of the specified datepart
boundaries crossed between the specified startdate and enddate.
The The DATEDIFF() function returns the time between two dates. And its syntax is
DATEDIFF(datepart,startdate,enddate)
Here in datepart you are mentioning hour so thats why it is printing only hours part

How to get NextDayofWeek if you pass the date?

Here's what I am trying to do. I will change the following code into SP which takes two parameter #startdate, and #transactionDate, and it will return the NextTransactiondate. The logic is #startdate determine which day of the week it is. The #NexttransactionDate should be equal to the day following the transactiondate. so in this example, the startday is Wednesday so the next transaction date should be - 2011-05-04'. In the code below, it is always computing to friday, but it should be dynamically compute based on the day. Any help is appreciated?
declare #TransactionDate datetime
declare #startDate datetime
declare #startDay int
declare #NextTransactionDate datetime
--Monday
set #TransactionDate = '2011-05-02'
--Wednesday
set #startDate = '2011-04-27'
set #startDay = datepart(dw,#startDate)
set #NextTransactionDate= DATEADD(DAY,(CASE DATEPART(DW,#TransactionDate)
WHEN 7 THEN 6
WHEN 6 THEN 7
ELSE 6 - DATEPART(DW,#TransactionDate)
END),#TransactionDate);
print #NextTransactionDate
The following works for me:
declare #TransactionDate DATETIME
DECLARE #TransactionDay tinyint
declare #startDate datetime
declare #startDay int
declare #NextTransactionDate datetime
--Monday
set #TransactionDate = '2011-05-05'
SET #TransactionDay = DATEPART(dw, #TransactionDate)
--Wednesday
set #startDate = '2011-04-27'
set #startDay = datepart(dw,#startDate)
set #NextTransactionDate= DATEADD(DAY, ((#startDay - #TransactionDay) + 7) % 7 ,#TransactionDate);
select #startDay, DATEPART(dw, #NextTransactionDate), #NextTransactionDate
To explain the meat of it, I'm finding the difference in the day-of-week for the startDate and the transactionDate. I add 14 to it because negative numbers modulo positive numbers result in a negative number, which would put your next transaction date in the past (and you don't want that). The worst case is when #startDay is 1 and #TransactionDay is 7 which leads to a difference of -6. Adding 7 ensures that that difference is positive but still in the same equivalence class as the actual difference in the ring n mod 7(sorry... I'm a bit of a math nerd).
Try this:
declare #TransactionDate datetime
declare #startDate datetime
declare #startDay int
declare #transactionDay int
declare #NextTransactionDate datetime
declare #daysToAdd int
--Monday
set #TransactionDate = '2011-05-02'
set #transactionDay = datepart(dw,#TransactionDate)
--Wednesday
set #startDate = '2011-04-27'
set #startDay = datepart(dw,#startDate)
print #transactionDay
print #startDay
if(#startDay <= #transactionDay)
set #daysToAdd = (#startDay + 7) - #transactionDay
else
set #daysToAdd = #startDay - #transactionDay
set #NextTransactionDate = Dateadd(Day,#daysToAdd,#TransactionDate)
print #NextTransactionDate
I'm not sure I follow what you're saying. I think you're saying that the next #TransactionDate, should be the next occurence of the day of the week that the #startDate falls on.
If that's the case, you could try :
declare #tDay = datepart(w, #transactionDate)
set #NextTransactionDate = DATEADD(w, #startDay-#tDay, #TransactionDate);
I'm not sure what you're doing with the 6 and 7 though... are you trying to make sure the new #TransactionDate is not a weekend? If so, this would need to be slightly modified...

Time duration between two dates

i need to get the time duration in (hh:mm:ss) format between the two dates
2011/05/05 11:45:02 and 2011/05/01 08:09:57
For example if I had these two dates 2011/05/05 01:18:14 and 2011/05/05 11:00:00, the result would be: 02:18:14
DECLARE #dt1 datetime
DECLARE #dt2 datetime
SELECT #dt1 = '2011-05-05 11:45:02', #dt2 = '2011-05-05 08:09:57'
SELECT CONVERT(VARCHAR(8),#dt1-#dt2,108)
-- RESULT IS : 03:35:05
As far as i know there is no DATETIME_INTERVAL Data type in SQL (or TSQL) , so the only way you have to accomplish this is to manually format the result of a DATEDIFF function.
declare #hours as int
declare #minutes as int
declare #seconds as int
declare #time_interval as nvarchar(10)
set #hours = DATEDIFF(ss,'2011/05/05 01:18:14', '2011/05/05 11:00:00') / 3600
set #minutes = (DATEDIFF(ss,'2011/05/05 01:18:14', '2011/05/05 11:00:00') - #hours*3600)/60
set #seconds = DATEDIFF(ss,'2011/05/05 01:18:14', '2011/05/05 11:00:00') - #hours*3600 - #minutes * 60
set #time_interval = (cast(#hours as nvarchar) +':'+ cast(#minutes as nvarchar)+':'+ cast(#seconds as nvarchar))
print #time_interval
Try this:
declare #date1 datetime='2011/05/05 01:18:14', #date2 datetime='2011/05/05 11:00:00'
select CAST((#date2-#date1) as time(0))
Here is important order of elements in statement.In other case you will get 24h-your time.