Finding difference between time - sql

In below code I am trying to find time difference in minutes
declare #a time
declare #b time
select #a = "Apr 1, 2014 22:36.000"
select #b = "Apr 2, 2014 02:25.000"
select datediff(minutes,#a,#b)
Expected output is 229 minutes.
24 min (60- 36) + 3 hour (180 min) + 25 min = 229 minutes
But I am getting -1211.This function is doing direct subration.
Please help.

You have declared the variables as time which cannot exceed 24 hours. The date portion is ignored.
In effect you are sending this to the datediff functoon
datediff(minute,'22:36.000', '02:25.000')
and that is why you are getting a negative result.
I suggest you declare #a and #b as datetime instead.
declare #a datetime
declare #b datetime
select #a = "Apr 1, 2014 22:36.000"
select #b = "Apr 2, 2014 02:25.000"
select datediff(minutes,#a,#b)

You can use this query as reference to calculate time difference .
select DATEDIFF(day,2007-11-30,2007-11-20) AS NumberOfDays, DATEDIFF(hour,2007-11-30,2007-11-20) AS NumberOfHours, DATEDIFF(minute,2007-11-30,2007-11-20) AS NumberOfMinutes FROM test_table

you are using time data types rather than datetime data types in your code ( they will ignore the date part and just store the time part.
so its calculating 2:25 - 22:36, ie 20 hours ( 1200 ) plus 11 minutes (all minus because the first time is after the second)
sql server date / time date types are documented here : http://msdn.microsoft.com/en-gb/library/ms186724.aspx

Related

Convert an Integer to time

I am being supplied a single integer that is supposed to represent an hour. So If it returns 1 it is 1:00 am and so forth on a 24 hour clock,13 for example is 1:00 pm. I need to convert this into time in SQL.
I know in MYSQL they have a function which does this:
SEC_TO_TIME(TheHour*60*60)
Is there an equivalent I can use in SQL? How do I do this?
You could do something like this.
select cast(DATEADD(hour, 13, 0) as time)
The upside is that it will still work even with negative numbers or values over 24.
There are two T-SQL function:
DATEFROMPARTS ( year, month, day )
and
TIMEFROMPARTS ( hour, minute, seconds, fractions, precision )
then you can use CONVERT if you need to format it.
-- test data
declare #hour_table table(hour_number int)
while (select count(*) from #hour_table) < 24
begin
insert into #hour_table(hour_number)
select count(*) from #hour_table
end
-- return results with your conversion to time string
select
hour_number,
convert(varchar(8),timefromparts( hour_number, 0, 0, 0, 0 ),0) as time_string
from #hour_table

How to find total time difference bwteen date range

I have created a procedure which returns time difference in minutes between 2 time i.e. ShiftStartTime, ShiftEndtime.
Now problem is that if i pass 2 date ranges then how i will calculate total shiftTime between those 2 dates e.g. TimeDifference returns me 480 min for today but i want to find total ShiftDifference for 3 days or more, then how i will add TimeDifference for more than 1 day ?
CREATE PROCEDURE GetShiftTotalDuration
#ShiftID int = 9,
#FromDate DateTime,
#ToDate DateTime
AS
BEGIN
Declare #TimeDifference int
Declare #ShiftStartTime time
Declare #ShiftEndTime time
Set #ShiftStartTime = (Select DeparmentShiftsHistory.StartTime from DeparmentShiftsHistory
where DeparmentShiftsHistory.Shift_ID= 9)
Set #ShiftEndTime = (Select DeparmentShiftsHistory.EndTime from DeparmentShiftsHistory
where DeparmentShiftsHistory.Shift_ID= 9)
Set #TimeDifference = (Select DATEDIFF(mi,#ShiftStartTime,#ShiftEndTime)) --Returns time difference in seconds
END
GO
I will calculate total shiftTime between those 2 dates
You mention that you will calculate difference between two dates but in your code you declare the variables as time
Declare #ShiftStartTime time
Declare #ShiftEndTime time
Thus DATEDIFF(mi,#ShiftStartTime,#ShiftEndTime) only the difference between the times not the dates
If you want to get the difference between dates you need use datetime datatype
On a side note, you have declared input parameters which have not been used in the proocedure as mentioned by Pradeep

timezone in GetDate query is 12 hours out

I am using MS webmatrix and razor.
I have a query that uses the expression CAST(GetDate() as INT) to get the current date integer value. However, even though my server and PC are both set on GMT + 12 (Wellington, Auckland), the value returned is 12 hours out - and at 12.00 pm on my PC (and the server) it jumps ahead one day.
How do I trim 12 hours off the value, without having to set the time 12 hours wrong on my machines?
Grateful for any help.
Coercing a date directly into an INT looks quite wrong.
To properly get just the INTEGRAL value of the date, use DATEDIFF directly.
select cast(cast('20120301' as datetime) as int) -- 40967
select cast(cast('20120301 12:30' as datetime) as int) -- 40968, oh noes!
select datediff(d,0,'20120301') -- 40967
select datediff(d,0,'20120301 12:30') -- 40967, yes!

Datediff function in Sql does not give accurate hour value

start date: 2012-05-29 08:30:00.000
end date: 2012-05-29 15:00:00.000
DATEDIFF(hour,StartDateTime,EndDateTime)
This gives me 7 hours, but it is actually 6.30
How can I calculate it?
If you want accuracy, you should use this approach
declare #start_date datetime, #end_Date datetime
select #start_date='2012-05-29 08:30:00.000', #end_date='2012-05-29 15:00:00.000'
select datediff(minute,#start_date ,#end_Date)/60.0
declare #start_date datetime, #end_Date datetime
select #start_date='2012-05-29 08:30:00.000'
select #end_date='2012-05-29 15:00:00.000'
select cast(DATEDIFF(MINUTE,#start_date,#end_Date)/60 as varchar)
+'.'+CAST(DATEDIFF(MINUTE,#start_date,#end_Date)%60 as varchar)
this will give you result as you want
6.30
Get the difference in minutes and then convert the minutes into hours..
The datediff function just counts crossings of the units specified, not the actual time between the two values. So in your case the "hour" crossings between the times are 9, 10, 11, 12, 13, 14, and 15, which totals 7 "hour" crossings. So, to get more precision, you want to use a unit of time in your datediff function that represents the precision you need, then convert that to hours.
As you are using "hour" datepart it gives you a rounded value. Use minutes, it will return 390min, is the correct answer. Then transform to hours.
This link should help you to have a better understanding of what are you doing with this statement. Check MSDN too for DATEDIFF sintaxis and uses
Sample code:
DECLARE #StartDateTime DATETIME='2012-05-29 08:30:00.000'
DECLARE #EndDateTime DATETIME='2012-05-29 15:00:00.000'
SELECT DATEDIFF(MINUTE,#StartDateTime,#EndDateTime)/60.0
Code to Find Exact Time in difference in hours and minutes,
DECLARE #STARTDATE DATETIME='2015-10-03 19:49:37.000'
DECLARE #ENDDATE DATETIME='2015-10-05 07:31:28.000'
DECLARE #HourOfDiff INT=CAST(datediff(minute,#STARTDATE ,#ENDDATE)/60.0 AS INT)
DECLARE #MinofDiff INT=DATEDIFF(mi,#STARTDATE,#ENDDATE)-(#HourOfDiff*60)
SELECT CAST(#HourOfDiff AS VARCHAR(10))+':'+ CAST(#MinofDiff AS VARCHAR(10))
You may use following working examples -
SELECT DATEDIFF("mi",StartDate,EndDate)/60 AS TimeInHours FROM dbo.JobData<BR>
SELECT DATEDIFF("ss",StartDate,EndDate)/3600 AS TimeInHours FROM dbo.JobData
For Hours Sql Server does not produce correct/accurate data, so count it in Minutes or seconds and then convert to Hours.

casting odd smallint time to to datetime format

I'm working with a db (SQL server 2008), and have an interesting issue with times stored in the db.
The DBA who originally set it up was crafty and stored scheduled times as smallints in 12-hour form-- 6:00AM would be represented as 600. I've figured out how to split them into hours and minutes like thus:
select floor(time/100) as hr, right(time, 2) as min from table;
What I want to do is compare these scheduled times to actual times, which are stored in the proper datetime format. Ideally, I would do this with two datetime fields and use datediff() between them, but this would require converting the smallint time into a datetime, which I can't figure out.
Does anyone have suggestions on how to do this?
Thanks in advance.
Can think of two ways to do that. The first is to build a string in the HH:MM format, and cast that to datetime. The second is to convert the smallint format to float with the number of days as unit. The number of days is the internal time representation, so you can cast that to datetime too.
Example code:
declare #i smallint
set #i = 621
-- Cast to a string '6:21', then to a datetime
select cast(CAST(#i / 100 as varchar) + ':' + CAST(#i % 100 as varchar)
as datetime)
-- Convert to number of days, which is the interal datetime format
select cast((#i/100)/24.0 + (#i%100)/(24*60.0) as datetime)
P.S. If you divide an integer by another integer. the result is a third integer: 100 / 24 = 4. If you divide an integer by a float, the result is a float: 100 / 24.0 = 4.16666.
Since you are using SQL Server 2008, you can take advantage of the new Time data type. In order to convert the integer to a time value, we need to assume that the last two digits are minutes. To get the minute portion, divide by 100, take the integer portion and subtract it from the initial value. So in the case of 621 we get:
621 - Floor(621/100)* 100
621 - Floor(6.21)*100
621 - 6*100
621 - 600 = 21 minutes
For the hour portion, we can simply take the integer value after dividing by 100.
Create Table #Test( IntVal smallint not null )
Insert #Test Values( 621 )
Insert #Test Values( 2359 )
Insert #Test Values( 1200 )
Insert #Test Values( 1201 )
Insert #Test Values( 1159 )
Select Z.TimeVal, GetDate(), DateDiff(hh, Z.TimeVal, Cast(GetDate() As Time(0)))
From (
Select Cast(DateAdd(mi
, IntVal - Floor(IntVal/100)*100
, DateAdd(hh, Floor(IntVal/100), 0)
) As Time(0)) As TimeVal
From #Test
) As Z
Part of the trick here is to use DateAdd(hh, Floor(IntVal/100), 0) which does a DateAdd against the zero value for datetime.