I have created a table with columns of datatype time(7)
I want to calculate the time difference between them.
Table time:
id timefrom timeto result
--------------------------------------
1 13:50:00 14:10:00 00:20:00
2 11:10:00 11:00:00 23:50:00
For example:
Time From 13:50
Time To 14:10
Result should show 00:20.
Is there a function for this?
DATEDIFF(hour, UseTimeFrom, UseTimeTo) hourtime,
(DATEDIFF(MINUTE, UseTimeFrom , UseTimeTo)) - (((DATEDIFF(hour, UseTimeFrom, UseTimeTo)) * 60)) as mintime
You can do it this way:
select *, convert(time, convert(datetime, timeto) - convert(datetime, timefrom))
from table1
This will convert the times to datetime for day 0 (1.1.1900) and then do the calculation and in case the timeto is smaller it will get to previous day, but convert to time will get the time part from it.
Example in SQL Fiddle
There's no built-in function - but you could relatively easily write your own T-SQL stored function to calculate this - something like this:
CREATE FUNCTION dbo.TimeDifference (#FromTime TIME(7), #ToTime TIME(7))
RETURNS VARCHAR(10)
AS BEGIN
DECLARE #Diff INT = DATEDIFF(SECOND, #FromTime, #ToTime)
DECLARE #DiffHours INT = #Diff / 3600;
DECLARE #DiffMinutes INT = (#Diff % 3600) / 60;
DECLARE #DiffSeconds INT = ((#Diff % 3600) % 60);
DECLARE #ResultString VARCHAR(10)
SET #ResultString = RIGHT('00' + CAST(#DiffHours AS VARCHAR(2)), 2) + ':' +
RIGHT('00' + CAST(#DiffMinutes AS VARCHAR(2)), 2) + ':' +
RIGHT('00' + CAST(#DiffSeconds AS VARCHAR(2)), 2)
RETURN #ResultString
END
This function uses the integer division (/) and integer remainder (%) operators to calculate the number of hours, minutes and seconds that those two times are apart, and then concatenates those together into a string as you are looking for.
SELECT
dbo.TimeDifference('13:50:00', '14:10:00'),
dbo.TimeDifference('13:50:00', '15:51:05'),
dbo.TimeDifference('13:50:00', '15:35:45')
Sample output:
00:20:00 02:01:05 01:45:45
Related
I need to find time difference between two columns with hours, minutes and seconds.
These are two datetime columns in my table:
STOP_TIME Start_Time
------------------------------------------------------
2016-05-10 03:31:00.000 2016-05-10 02:25:34.000
I calculated second difference for stoptime and starttime. 3926 is the second difference.
I need to convert this to time format hh:mm:ss.
This should work for you -
DECLARE #STOP_TIME DATETIME = '2016-05-10 03:31:00.000',
#Start_Time DATETIME = '2016-05-10 02:25:34.000'
SELECT
RIGHT('0' + CAST(DATEDIFF(S, #Start_Time, #STOP_TIME) / 3600 AS VARCHAR(2)),2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, #Start_Time, #STOP_TIME) % 3600/60 AS VARCHAR(2)),2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, #Start_Time, #STOP_TIME) % 60 AS VARCHAR(2)),2)
Sql server supports adding and subtracting on Datetime data type, so you can simply do something like this:
DECLARE #StartTime datetime = '2016-05-10 02:25:34.000',
#EndTime datetime = '2016-05-10 03:31:00.000'
SELECT CAST(#EndTime - #StartTime as Time) As TimeDifference
Result: 01:05:26
Note: As TT rightfully wrote in his comment, casting to time will only work if the difference between #EndTime and #StartTime is less then 24 hours.
If you need to compare times that are further apart, you need to use one of the other solutions suggested.
I need to convert a value for example 2.54 that comes in minutes to a format like hh:mm:ss.
the value could be also zero.
DECLARE #f DECIMAL(6,2) = 2.54
SELECT CAST(DATEADD(SECOND, 60 * ROUND(#f, 0, 1) + 100 * (#f % 1), 0) AS time(0));
#f=2.54 -> 00:02:54
#f=330.42 -> 05:30:42
How it works:
ROUND(#f, 0, 1) - minutes; take only the integer part, discarding everything after the decimal point
MS Docs ROUND
100 * (#f % 1) - seconds; take the remainder of the integer division by 1
MS Docs %(Modulus)
DATEADD(SECOND, X, 0) equivalent to DATEADD(SECOND, X, '1900-01-01 00:00:00')
MS Docs DATEADD
CAST(X to time(0)) - trim date from DATETIME
MS Docs CAST
You can try like this
DECLARE #f DECIMAL = 2.54;
SELECT CONVERT(TIME(0), DATEADD(MINUTE, 60*#f, 0));
Gives result as
02:32:00
This is one of the solutions:
select
2.54 as NumericTime
,floor(2.54) as Minutes
,(2.54-floor(2.54))*100 as Seconds
,cast('00:'+cast(floor(2.54) as varchar)+':'
+cast((2.54-floor(2.54))*100 /* or 60 if this is common format */ as varchar) as time) as FullTime
But I really don't like all this additional CASTs. Maybe someone can provide better way.
I think I found it, what do you think? not very elegant but it's work.
DECLARE #number DECIMAL(12,4) = 2.54
SELECT CASE
WHEN #number >= 60 THEN CONVERT(VARCHAR(50), FLOOR(FLOOR(#number) / 60)) + ':' + CONVERT(VARCHAR(10), (FLOOR(#number) % 60)) + ':' + CONVERT(VARCHAR(10), FLOOR((#number-floor(#number)) * 60))
ELSE '00:' + CONVERT(VARCHAR(50), FLOOR(#number)) + ':' + CONVERT(VARCHAR(50), FLOOR((#number - floor(#number)) * 60))
END
Try this
SELECT Convert(time(0),CONVERT(datetime, DATEADD(MINUTE, 60*#f, 0)));
Try this:
DECLARE #Time DECIMAL(4,2) = 3.07
SELECT CAST(floor(#Time) AS VARCHAR) + ':'
+ REPLACE(REPLICATE('0',5 - LEN(CAST(#Time%1*100 AS VARCHAR)))
+ CAST(#Time%1*100 AS VARCHAR),'.',':');
This will also handle the corner cases where the Time is 2.05 sec, 4.09 sec etc.
Been struggling with this and can't seem to find the right answer, although there are plenty of mentions for converting, but nothing specific is working.
I need to convert a time with data type of float into hours and minutes. So 13.50 as 13.30. The data type as fixed as float in DB so cannot change. DB is SQL Server 2008R2
Have tried:
cast(cast(floor(fdsViewTimesheet.perStandardHours) as
float(2))+':'+cast(floor(100*(
fdsViewTimesheet.perStandardHours - floor(fdsViewTimesheet.perStandardHours)))as
float(2)) as time) AS STANDARD_HOURS
But I get error message "Explicit conversion from data type real to time is not allowed" Have tried as char instead of as float but query hangs.
What am I doing wrong? I just want to convert a float value into hours and minutes.
Would be grateful if someone could point me in the right direction.
You can try:
DECLARE #HOURS decimal(7,4) = 20.5599
SELECT CAST(CONVERT(VARCHAR,DATEADD(SECOND, #HOURS * 3600, 0),108) AS TIME)
output : 20:33:35
But remember : Type Time in MSSQL only under 24hrs
If you want greater than 24hrs, try:
DECLARE #HOURS decimal(7,4) = 25.5599
SELECT
RIGHT('0' + CAST (FLOOR(#HOURS) AS VARCHAR), 2) + ':' +
RIGHT('0' + CAST(FLOOR((((#HOURS * 3600) % 3600) / 60)) AS VARCHAR), 2) + ':' +
RIGHT('0' + CAST (FLOOR((#HOURS * 3600) % 60) AS VARCHAR), 2)
output : 25:33:35
-- Update
Decimal minutes to more than 24hrs
DECLARE #MINUTES decimal(7,4) = 77.9
SELECT
RIGHT('0' + CAST (FLOOR(COALESCE (#MINUTES, 0) / 60) AS VARCHAR (8)), 2) + ':' +
RIGHT('0' + CAST (FLOOR(COALESCE (#MINUTES, 0) % 60) AS VARCHAR (2)), 2) + ':' +
RIGHT('0' + CAST (FLOOR((#MINUTES* 60) % 60) AS VARCHAR (2)), 2);
output: 01:17:54
This should work for you
DECLARE #f [real]
SET #f = 13.50
SELECT DATEADD(mi, (#f - FLOOR(#f)) * 60, DATEADD(hh, FLOOR(#f), CAST ('00:00:00' AS TIME)))
DECLARE #f FLOAT = 13.5;
SELECT CONVERT(TIME(0), DATEADD(MINUTE, 60*#f, 0));
Or if you just want hh:mm as a string:
SELECT CONVERT(CHAR(5), DATEADD(MINUTE, 60*#f, 0), 108);
Just be careful if you have values >= 24.
How about you convert to minutes and add to the 00:00 time like so:
DECLARE #c datetime
select #c = dateadd(mi,fdsViewTimesheet.perStandardHours*60,'00:00')
If you wanted to do it in the statement with Time only:
select CONVERT(TIME,dateadd(mi,fdsViewTimesheet.perStandardHours*60,'00:00') )
If you have values that are larger than 24 hours, then the standard datetime and time types in sql cannot hold these. They are limited to holding 24 hour ranges.
What you would need to do is store the time representation in a string for example like so:
select cast(floor(fdsViewTimesheet.perStandardHours) as varchar(10)) + ':' + cast(FLOOR( (fdsViewTimesheet.perStandardHours - floor(fdsViewTimesheet.perStandardHours))*60)as varchar(2))
I have a select query that has DURATION column to calculate number of Minutes . I want to convert those minutes to hh:mm format.
Duration has values like 60, 120,150
For example:
60 becomes 01:00 hours
120 becomes 02:00 hours
150 becomes 02:30 hours
Also, this is how I retrieve DURATION (Minutes)
DATEDIFF(minute, FirstDate,LastDate) as 'Duration (Minutes)'
You can convert the duration to a date and then format it:
DECLARE
#FirstDate datetime,
#LastDate datetime
SELECT
#FirstDate = '2000-01-01 09:00:00',
#LastDate = '2000-01-01 11:30:00'
SELECT CONVERT(varchar(12),
DATEADD(minute, DATEDIFF(minute, #FirstDate, #LastDate), 0), 114)
/* Results: 02:30:00:000 */
For less precision, modify the size of the varchar:
SELECT CONVERT(varchar(5),
DATEADD(minute, DATEDIFF(minute, #FirstDate, #LastDate), 0), 114)
/* Results: 02:30 */
This function is to convert duration in minutes to readable hours and minutes format. i.e 2h30m. It eliminates the hours if the duration is less than one hour, and shows only the hours if the duration in hours with no extra minutes.
CREATE FUNCTION [dbo].[MinutesToDuration]
(
#minutes int
)
RETURNS nvarchar(30)
AS
BEGIN
declare #hours nvarchar(20)
SET #hours =
CASE WHEN #minutes >= 60 THEN
(SELECT CAST((#minutes / 60) AS VARCHAR(2)) + 'h' +
CASE WHEN (#minutes % 60) > 0 THEN
CAST((#minutes % 60) AS VARCHAR(2)) + 'm'
ELSE
''
END)
ELSE
CAST((#minutes % 60) AS VARCHAR(2)) + 'm'
END
return #hours
END
To use this function :
SELECT dbo.MinutesToDuration(23)
Results: 23m
SELECT dbo.MinutesToDuration(120)
Results: 2h
SELECT dbo.MinutesToDuration(147)
Results: 2h27m
Hope this helps!
I'm not sure these are the best options but they'll definitely get the job done:
declare #durations table
(
Duration int
)
Insert into #durations(Duration)
values(60),(80),(90),(150),(180),(1000)
--Option 1 - Manually concatenate the values together
select right('0' + convert(varchar,Duration / 60),2) + ':' + right('0' + convert(varchar,Duration % 60),2)
from #Durations
--Option 2 - Make use of the time variable available since SQL Server 2008
select left(convert(time,DATEADD(minute,Duration,0)),5)
from #durations
GO
DECLARE #Duration int
SET #Duration= 12540 /* for example big hour amount in minutes -> 209h */
SELECT CAST( CAST((#Duration) AS int) / 60 AS varchar) + ':' + right('0' + CAST(CAST((#Duration) AS int) % 60 AS varchar(2)),2)
/* you will get hours and minutes divided by : */
For those who need convert minutes to time with more than 24h format:
DECLARE #minutes int = 7830
SELECT CAST(#minutes / 60 AS VARCHAR(8)) + ':' + FORMAT(#minutes % 60, 'D2') AS [Time]
Result:
130:30
This seems to work for me:
SELECT FORMAT(#mins / 60 * 100 + #mins % 60, '#:0#')
Thanks to A Ghazal, just what I needed. Here's a slightly cleaned up version of his(her) answer:
create FUNCTION [dbo].[fnMinutesToDuration]
(
#minutes int
)
RETURNS nvarchar(30)
-- Based on http://stackoverflow.com/questions/17733616/how-to-convert-number-of-minutes-to-hhmm-format-in-tsql
AS
BEGIN
return rtrim(isnull(cast(nullif((#minutes / 60)
, 0
) as varchar
) + 'h '
,''
)
+ isnull(CAST(nullif((#minutes % 60)
,0
) AS VARCHAR(2)
) + 'm'
,''
)
)
end
select convert(varchar(5),dateadd(mi,DATEDIFF(minute, FirstDate,LastDate),'00:00'),114)
In case someone is interested in getting results as
60 becomes 01:00 hours, 120 becomes 02:00 hours, 150 becomes 02:30 hours, this function might help:
create FUNCTION [dbo].[MinutesToHHMM]
(
#minutes int
)
RETURNS varchar(30)
AS
BEGIN
declare #h int
set #h= #minutes / 60
declare #mins varchar(2)
set #mins= iif(#minutes%60<10,concat('0',cast((#minutes % 60) as varchar(2))),cast((#minutes % 60) as varchar(2)))
return iif(#h <10, concat('0', cast(#h as varchar(5)),':',#mins)
,concat(cast(#h as varchar(5)),':',#mins))
end
I would do the following (copy-paste the whole stuff below into immediate window / query window and execute)
DECLARE #foo int
DECLARE #unclefoo smalldatetime
SET #foo = DATEDIFF(minute, CAST('2013.01.01 00:00:00' AS datetime),CAST('2013.01.01 00:03:59' AS datetime)) -- AS 'Duration (Minutes)'
SET #unclefoo = DATEADD(minute, #foo, '2000.01.01')
SELECT CAST(#unclefoo AS time)
#foo stores the value you generate in your question. The "trick" comes by then:
we create a smalldatetime variable (in my case it's yyyy.mm.dd format) and increment it with your int value, then display (or store if you want) the time part only.
declare function dbo.minutes2hours (
#minutes int
)
RETURNS varchar(10)
as
begin
return format(dateadd(minute,#minutes,'00:00:00'), N'HH\:mm','FR-fr')
end
How to get the First and Last Record time different in sql server....
....
Select EmployeeId,EmployeeName,AttendenceDate,MIN(Intime) as Intime ,MAX(OutTime) as OutTime,
DATEDIFF(MINUTE, MIN(Intime), MAX(OutTime)) as TotalWorkingHours
FROM ViewAttendenceReport WHERE AttendenceDate >='1/20/2020 12:00:00 AM' AND AttendenceDate <='1/20/2020 23:59:59 PM'
GROUP BY EmployeeId,EmployeeName,AttendenceDate;
If you want a notation of XX days YY hours and ZZ min, just try:
SELECT
CAST(f.TimeAmount / 1440 AS VARCHAR(8)) + 'd ' +
CAST((f.TimeAmount % 1440) / 60 AS VARCHAR(8)) + 'h ' +
FORMAT(f.TimeAmount % 60, 'D2') + 'min' AS [TIME_TEXT]
FROM
MyTable f
Could use guru help on this one. Trying to calculate the time between two datetime values and show as time in a T-SQL query...
SELECT arrivalDate - departDate AS timeToComplete
This should always be less than 24 hours. But who knows what the user may actually input?
I have been trying something like this with no resutls.
SELECT
CAST(time(7),
CONVERT(datetime, arrivalDate - departDate) AS timeToComplete) AS newTime,
Instead of showing results as 1:23:41 as an example, is there a way to show results like:
0D, 1H, 23M, 33S.
Thanks for any guidance on this.
You could get the total difference in seconds and then keep taking the largest part out of that. I.e., start with Days, then hours, minutes and seconds.
DECLARE #arrivalDate DATETIME = '2013-01-19 23:59:59'
DECLARE #departDate DATETIME = '2013-01-25 11:52:30'
DECLARE #SecondsDifference INT = DATEDIFF(SECOND, #arrivalDate, #departDate)
DECLARE #DayDifference INT = #SecondsDifference / 86400
DECLARE #HourDifference INT = (#SecondsDifference - (#DayDifference * 86400)) / 3600
DECLARE #MinDifference INT = (#SecondsDifference - (#DayDifference * 86400) - (#HourDifference * 3600)) / 60
DECLARE #SecDifference INT = (#SecondsDifference - (#DayDifference * 86400) - (#HourDifference * 3600) - (#MinDifference * 60))
I've done it here using variables for clarity, but you could work this into a single query. DATEDIFF wont work for the smaller chunks of the difference until you remove the larger ones because you'd get the totals. For example:
DATEDIFF(HOUR, #arrivalDate, #departDate)
would return the total number of hours, not the hours less the whole days.
Just to be different :)
Try to use this approach:
declare #date1 datetime;
declare #date2 datetime;
set #date1 = '2012-05-01 12:00:000'
set #date2 = '2012-05-01 18:00:000'
SELECT
STUFF(
STUFF(
STUFF(
RIGHT(CONVERT(NVARCHAR(19), CONVERT(DATETIME, DATEADD(second, DATEDIFF(S, #date1, #date2), '20000101')), 120), 11),
3, 1, 'D, '),
8, 1, 'H, '),
13, 1, 'M, ') + ' S';
Finally found a great solution at this link,
SQL - Seconds to Day, Hour, Minute, Second
thanks for the help though folks, it got me further into this issue and searching for the right info.