datediff not returning what I'm expecting - sql

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

Related

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,

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.

Getting the Whole Time

How can I get the whole time like this datediff(time, logindate, logoutdate)
I know this built-in function doesn't accept time argument but how can I get the whole time rather than minute, millisecond, second etc. ?
logindate datetime2
logoutdate datetime2
I want something like 1:05:45 rather than portion of it.
Try this
create table dbo.UserLog (UserID VARCHAR(32),loginDate DATETIME,logoutDate DATETIME)
insert into userLog VALUES ('SPARKY','11/14/2009 3:25pm',getDate())
insert into userLog VALUES ('JANNA','11/14/2009 10:45am',getDate())
select UserId,loginDate,logoutDate,
convert(varchar(12),dateAdd(mi,datediff(mi,logindate,logoutdate),'Jan 1 1753 12:00AM'),114) as timeSpent
FROM userLog
Basically, adding the minutes difference between the dates to the earliest valid SQL date and returning the value formatted as a time.
To have difference in days:
select cast(logoutdate - logindate as float) from table_name
or just
select logoutdate - logindatefrom table_name
You can evaluate days, hours, minutes from it.
EDIT
To have it formatted as time:
SELECT CONVERT(VARCHAR,DATA_KOSZTU - DATA_OST_ZMIANY,108) FROM TR_KOSZT
It will work if users are not logged for more than 24 hours, because CONVERT is used to format datetime, not timespan.
Because MSSQL do not have timepsan datatype, datediff returning in absolute integer from milliseconds to years should be enough for you to create a instance of say TimeSpan in .NET.
What Sql Server version are you talking about? In SQL Server 2000 and later, at least,
SELECT datediff(ss,'2006-11-10 05:47:53.497','2006-11-10 05:48:10.420')
will give you the difference between those two datetimes in seconds.
E.g.
select CONVERT(varchar(10),GETDATE(),108)
Here's the solution you are looking for.
DECLARE #Date1 datetime
DECLARE #Date2 datetime
SET #Date2 = '2006-11-15 07:26:25.000'
SET #Date1 = '2009-11-15 05:35:45.000'
-- -----------------------
-- Math done by hand 1:50:40
--
DECLARE #TotalSeconds bigint
DECLARE #Hours bigint
DECLARE #Minutes bigint
DECLARE #Seconds bigint
DECLARE #HH varchar(20)
DECLARE #MM varchar(2)
DECLARE #SS varchar(2)
DECLARE #Result varchar(50)
--
SET #TotalSeconds = datediff(ss,#Date1 ,#Date2)
SET #Hours = FLOOR(#TotalSeconds / 3600)
SET #TotalSeconds = #TotalSeconds % 3600
SET #Minutes = FLOOR(#TotalSeconds / 60)
SET #Seconds = #TotalSeconds % 60
--
SET #HH = CAST(#Hours as varchar)
SET #MM = CAST(#Minutes as varchar)
SET #SS = CAST(#Seconds as varchar)
IF #Minutes < 10 SET #MM = '0' + #MM
IF #Seconds < 10 SET #SS = '0' + #SS
--
SET #Result = #HH + ':' + #MM + ':' + #SS
SELECT #Result

To get difference between 2 dates

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