Getting the Whole Time - sql

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

Related

Convert 'mm:ss' in to time in SQL Server

I have a string which contains a duration in minutes and seconds, as '1302:47'.
I want to store this in SQL Server and I chose the time data type.
How do I convert '1302:47' in to hrs:mins:secs to a time datatype?
I tried
SELECT TRY_PARSE('1302:40' AS time)
SELECT TRY_CONVERT(time, '1302:40')
and end up with NULL both times implying the conversion failed.
I am expecting 21:7:40 as in 21hrs, 7mins and 40seconds.
Should I use a different data type?
Should I convert it all to seconds and just store as an int?
You need to split your string by ':' char, since that time in invalid. That's why you're getting a NULL value.
After that, you can try parse both the minutes and the seconds.
Finally, just add the minutes and seconds into a new empty time.
Example supporting the max of 23h:
DECLARE #date VARCHAR(20) = '1302:40';
DECLARE #min INT = ISNULL(TRY_PARSE(LEFT(#date,CHARINDEX(':',#date)-1) AS INT), 0);
DECLARE #sec INT = ISNULL(TRY_PARSE(RIGHT(#date,LEN(#date)-CHARINDEX(':',#date)) AS INT), 0);
DECLARE #time TIME = '00:00'
PRINT DATEADD(s, #sec, DATEADD(mi, #min, #time));
-- Outputs: 21:42:40.0000000
Example supporting more than 23h:
DECLARE #date VARCHAR(20) = '1302:47';
--DECLARE #date VARCHAR(20) = '3600:60';
DECLARE #min INT = ISNULL(TRY_PARSE(LEFT(#date,CHARINDEX(':',#date)-1) AS INT), 0);
DECLARE #sec INT = ISNULL(TRY_PARSE(RIGHT(#date,LEN(#date)-CHARINDEX(':',#date)) AS INT), 0);
DECLARE #time TIME = '0001-1-1 00:00'
IF #min < 1440
BEGIN
PRINT CAST(DATEADD(s, #sec, DATEADD(mi, #min, #time)) AS VARCHAR(8));
END
ELSE
BEGIN
IF #sec = 60
BEGIN
SET #sec = 0;
SET #min = #min +1;
END
PRINT CONCAT(#min/60, ':', FORMAT(#min - (#min/60) * 60,'0#'), ':', FORMAT(#sec,'0#'))
END
-- Scenario #1. Given '1302:47', outputs: 21:42:47
-- Scenario #2. Given '3600:60', outputs: 60:01:00

Data operations

I wrote a stored procedure who take a reference date, and add a hour to this element.
Here is my line doing the operation :
DATEADD(day, DATEDIFF(DAY, 0, #conductor_date), [HOUR])
For example, whith #conductor_date = '2015-10-15' and [HOUR] = 23:00 it works and generate me a date like that : '2015-10-15:23:00:00'
I face a logical issue when the value [HOUR] is more than 24. In fact, to solve my problem I need to generate '2015-10-16:00:40:00' when [HOUR] = 24:40
Actualy with this values, I face the logical following exception :
The conversion of a varchar data type to a datetime data type resulted
in an out-of-range value.
To sum up, I need to take care of hours that are more than '23:59' and switch to the next day :
DECLARE #conductor_date datetime
DECLARE #hour varchar(5)
SET #conductor_date = '2015-10-15'
SET #hour = '24:40'
SELECT DATEADD(day, DATEDIFF(DAY, 0, #conductor_date), #hour)
Expected : 2015-10-16:00:40:00
According to the documentation, date / time types don't support times larger then 23:59:59.9999999. You have to do manual string parsing for this.
First you need to extract the total hours, divide that by 24 to get total days. Then calculate leftover hours, and with that reconstruct your time offset.
With these in hand, you can build your required output value:
DECLARE #v VARCHAR(20) = '24:40'
DECLARE #start VARCHAR(20) = '2015-10-15'
DECLARE #days INT
DECLARE #leftover INT
SET #leftover = CAST(LEFT(#v, 2) AS INT)
SET #days = #leftover / 24
SET #leftover = #leftover - #days * 24
SET #v = CAST(#leftover AS VARCHAR(2)) + SUBSTRING(#v, 3, 20)
SELECT DATEADD(DAY, #days + DATEDIFF(DAY, 0, #start), #v)
Here's a working SQLFiddle.
This supports time string that start with HH (leading zeros) with any valid accuracy (HH:mm:ss.fffffff).
You can split your #hour field into hours and minutes and add them separately:
DECLARE #conductor_date datetime
DECLARE #hour varchar(5)
DECLARE #hours int
DECLARE #minutes int
DECLARE #offset datetime
SET #conductor_date = '2015-10-15'
SET #hour = '24:40'
SET #hours = cast(left(#hour, 2) as int)
SET #minutes = cast(right(#hour, 2) as int)
SET #offset = dateadd(day, datediff(day, 0,#conductor_date), 0) -- the begin of the day
SELECT DATEADD(hour, #hours, dateadd(minute, #minutes, #offset))
Of course all can be done in one line but for sake of visualization I have put it into separate statements.
You may try below query
SELECT DATEADD(MINUTE,(LEFT(#hour,2)*60+RIGHT(#hour,2)),#conductor_date)

How to create Time with Hour+Minute+Seconds in sql server 2008

I have three var char values as
#hour = '18'
#minute = '25'
#seconds = '45'
I need output in the form of '18:25:45'
Select from Convert(Time,#hour+#minute+#seconds)
values in hour minute and seconds coming from SSRS report drop down
You can 'add-up' the values from zero, like this:
declare #hour smallint = 18
declare #minute smallint = 25
declare #seconds smallint = 45
declare #result time
SELECT #result = DATEADD(hour, #hour, DATEADD(minute, #minute, DATEADD(second, #seconds, 0)))
An implicit conversion is not allowed. One solution could be to organise the format as a string and then convert to time as below.
declare #hour smallint = '18'
declare #minute smallint = '25'
declare #seconds smallint = '45'
declare #format varchar(8) = (select (CAST(#hour as varchar(2)) + ':'+ CAST(#minute as varchar(2))+':'+ CAST(#seconds as varchar(2))))
select CAST(#format as time)
Try with this 24-H date format, It will Work.
SELECT CONVERT(VARCHAR(8),GETDATE(),108) AS TimeResult

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.

Calculating timespan with t-sql

Given two date/times:
#start_date = '2009-04-15 10:24:00.000'
#end_date = '2009-04-16 19:43:01.000'
Is it possible to calculate the time elapsed between the two dates in the following format
1d 9h 19m
You can get the difference between the two dates to whatever resolution you want (in your example, minutes):
DATEDIFF(minute, #start_date, #end_date)
From there it's a simple matter of dividing minutes into hours and hours into days and modding the remainder.
I know this thread is older and the original participants are likely no longer watching, but I stumbled upon it, and had already written some code fairly recently to do something very close to what jdiaz is requesting. The result is rendered as a string in D:H:M:S format.
Step one would be to get the time span in seconds:
DECLARE #ElapsedS INT
SET #ElapsedS = DATEDIFF(second, #start_date, #end_date)
Now create the following scalar function:
CREATE FUNCTION [dbo].[udfTimeSpanFromSeconds]
(
#Seconds int
)
RETURNS varchar(15)
AS
BEGIN
DECLARE
--Variable to hold our result
#DHMS varchar(15)
--Integers for doing the math
, #Days int --Integer days
, #Hours int --Integer hours
, #Minutes int --Integer minutes
--Strings for providing the display
, #sDays varchar(5) --String days
, #sHours varchar(2) --String hours
, #sMinutes varchar(2) --String minutes
, #sSeconds varchar(2) --String seconds
--Get the values using modulos where appropriate
SET #Hours = #Seconds/3600
SET #Minutes = (#Seconds % 3600) /60
SET #Seconds = (#Seconds % 3600) % 60
--If we have 24 or more hours, split the #Hours value into days and hours
IF #Hours > 23
BEGIN
SET #Days = #Hours/24
SET #Hours = (#Hours % 24)
END
ELSE
BEGIN
SET #Days = 0
END
--Now render the whole thing as string values for display
SET #sDays = convert(varchar, #Days)
SET #sHours = RIGHT('0' + convert(varchar, #Hours), 2)
SET #sMinutes = RIGHT('0' + convert(varchar, #Minutes), 2)
SET #sSeconds = RIGHT('0' + convert(varchar, #Seconds), 2)
--Concatenate, concatenate, concatenate
SET #DHMS = #sDays + ':' + #sHours + ':' + #sMinutes + ':' + #sSeconds
RETURN #DHMS
END
Now feed your timespan into the newly created function:
SELECT TimeSpan = dbo.udfTimeSpanFromSeconds(#ElapsedS)
Should produce '1:09:19:01'
CONVERT(
varchar(8),
(
CAST(#end_date AS DATETIME)
-
CAST(#start_date AS DATETIME)
)
,108
)
This'll give it to you as HH:MM:SS
Cheers
DATEDIFF can return unintuitive values. For example, the two dates below differ by one second yet DATEDIFF with the parameters below and interpreted as others have interpreted it above returns 1 year:
SELECT DATEDIFF(year, '2005-12-31 23:59:59', '2006-01-01 00:00:00')
Look at the MSDN documentation for DATEDIFF to understand how it works.
datediff(datepart, date1, date2);
Rex's answer is more complete.
Here's how you format the datediff (50d 8h 35m) in a query:
Declare #Date1 as Datetime, #Date2 as Datetime
Set #Date1 = '2005-01-01 08:00:00'
Set #Date2 = '2005-02-20 16:35:30'
Select
CAST(DATEDIFF(Minute,#Date1, #Date2)/60/24 as Varchar(50)) ++ 'd ' ++
CAST((DATEDIFF(Minute,#Date1, #Date2)/60)-((DATEDIFF(Minute,#Date1, #Date2)/60/24)*24) as Varchar(50)) ++ 'h ' ++
CAST((DATEDIFF(Minute,#Date1, #Date2)) - (DATEDIFF(HOUR,#Date1, #Date2)*60) as Varchar(50)) ++ 'm' as FormattedDateDiff
DECLARE #FirstDate DATETIME, #SecondDate DATETIME, #result VARCHAR(MAX)
SELECT #FirstDate = '2017-03-01 09:54:00.637', #SecondDate = GETDATE()
DECLARE #Day INT,#Month INT,#Hour INT, #Minute INT,#TotalSeconds INT,#Year INT
SELECT #TotalSeconds = ABS(DATEDIFF(SECOND,#FirstDate,#SecondDate))
-- Standard values in seconds
DECLARE #YearSeconds INT, #MonthSeconds INT, #DaySeconds INT, #HourSeconds INT, #MinuteSeconds INT
SELECT #MinuteSeconds = 60
SELECT #HourSeconds = 60 * #MinuteSeconds
SELECT #DaySeconds = 24 * #HourSeconds
SELECT #MonthSeconds = 30 * #DaySeconds
SELECT #YearSeconds = 12 * #MonthSeconds
--SELECT #MinuteSeconds AS [Minutes], #HourSeconds AS [Hours], #DaySeconds AS [Day],#MonthSeconds AS [Month],#YearSeconds AS [Year]
IF #TotalSeconds < #MinuteSeconds
BEGIN
SELECT #result = CAST(#TotalSeconds AS NVARCHAR(20)) + ' seconds ago'
END
ELSE IF #TotalSeconds < #HourSeconds
BEGIN
SELECT #result = CAST(ABS(DATEDIFF(MINUTE,#FirstDate,#SecondDate)) AS NVARCHAR(20)) + ' minutes ago'
END
ELSE IF #TotalSeconds < #DaySeconds
BEGIN
SELECT #result = CAST(ABS(DATEDIFF(HOUR,#FirstDate,#SecondDate)) AS NVARCHAR(20)) + ' hours ago'
END
ELSE IF #TotalSeconds < #MonthSeconds
BEGIN
SELECT #result = CAST(ABS(DATEDIFF(DAY,#FirstDate,#SecondDate)) AS NVARCHAR(20)) + ' days ago'
END
ELSE IF #TotalSeconds < #YearSeconds
BEGIN
SELECT #result = CAST(ABS(DATEDIFF(MONTH,#FirstDate,#SecondDate)) AS NVARCHAR(20)) + ' months ago'
END
ELSE IF #TotalSeconds > #YearSeconds
BEGIN
SELECT #result = CAST(ABS(DATEDIFF(YEAR,#FirstDate,#SecondDate)) AS NVARCHAR(20)) + ' year ago'
END
SELECT #result