Convert decimal time to hours and minutes - sql-server

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))

Related

Time difference with hours, minutes and seconds in SQL Server

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.

How to calculate time difference in T-SQL

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

Convert decimal minutes to hh:mm:ss

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.

INT to hh:mm:ss tt in SQL Server

I will have an integer calculated from datediff()
let's say.. it is..
declare #earliestTime int;
set #earliestTime=50000000;
I want to convert to hh:mm:ss tt
I have this code to convert that int to HH:mm:ss
CONVERT(varchar(6), (#earliestTime)/60)+ ':' + RIGHT('0' + CONVERT(varchar(2), ((#earliestTime) % 60) ), 2)+ ':' + RIGHT('0' + CONVERT(varchar(2), ((#earliestTime) %60)*0), 2)
How can I modify it to hh:mm:ss tt (AM or PM)
I modified like this..
CONVERT(varchar(6),
case
when
((#earliestTime)/60)<=12
then
((#earliestTime)/60)
else
(((#earliestTime)/60)-12)
end )
--CONVERT(varchar(6), case when((#earliestTime)/60)<=12 then (#earliestTime)/60 else ((#earliestTime)/60)-12)
+
':'
+
RIGHT('0' + CONVERT(varchar(2), ((#earliestTime) % 60) ), 2)
+
':'
+
RIGHT('0' + CONVERT(varchar(2), ((#earliestTime) %60)*0), 2
+
' '
+
convert(varchar(2),(case when ((#earliestTime)/60)<12 then 'am' else 'pm' end)))
But it gives me this error..
Conversion failed when converting the
varchar value 'pm' to data type int.
I already convert 'pm' or 'am' to varchar(2). why the system still gives me that error?
How to make it correct or is there a better way?
You don't explain what your integer represents so it is difficult to give an answer.
It's best to use a proper data type for times. I'd use DATETIME - it will allow to you to perform calculations, sort, and format as required. Storing time as text is going to cause headaches later on.
Store a time by adding the time to the SQL epoch (1900-01-01 00:00:00), like so
SELECT DATEADD(SECOND, 50000, CONVERT(DATETIME, 0.0))
SELECT DATEADD(MINUTE, 50000, CONVERT(DATETIME, 0.0))
Then format the DATETIME object accordingly.
To get HH:mm:ss, use format 108.
To get the AM/PM flag, use 100 and take the two rightmost characters.
Try the below:
DECLARE #date DATETIME
SET #date = DATEADD(SECOND, 50000, CONVERT(DATETIME, 0.0))
SELECT CONVERT(VARCHAR, DATEPART(HOUR, #date)%12)
+ ':' + RIGHT(CONVERT(VARCHAR, #date, 108),5)
+ RIGHT(CONVERT(VARCHAR, #date, 100), 2)
I should also point out that you are working in a database, not a presentation layer. There should be no need to worry about formatting dates and times in a database; it is about data storage and retrieval. Presumably you are returning this time to an application or webpage to be put onto a screen, into a report or whatever - best practice is to keep the data as a complete DATETIME and let the top layer format it. By converting to a VARCHAR you are just removing information and limiting yourself; no benefit, lots of cost.

Is there any function in SQL Server to convert a number into Time format?

I am getting a whole number for the duration of product. For example : 62, 103, 184, 4543. I want to convert it in time format. Let say , in case of 62, it would format like '00:01:02'. I am looking for a function which can resolve my problem. Is there any function in SQL Server which convert a number into time format?
declare #d datetime
Set #d = Convert(datetime, '20010101',112 )
Set #d = dateadd(s, 62, #d) --add 62 seconds to base date
Select convert(varchar,#D,108)
Well, you have two choices. You can do the division by 60 yourself like so:
SELECT RIGHT('0' + CAST(#seconds / 3600 AS varchar), 2) + ':' +
RIGHT('0' + CAST((#seconds / 60) % 60 AS varchar), 2) + ':' +
RIGHT('0' + CAST(#seconds % 60 AS varchar), 2)
Or you can do some sort of datetime-related kludge:
SELECT CONVERT(varchar,
DATEADD(second, #seconds, CAST('1-Jan-2000' AS datetime)),
8)
Format 8 is hh:mi:ss from here.

Resources