Need hour min and sec in a query - sql

I am calculating the time difference between 2 times, I want to print the hour min and sec. Can anyone please tell me how to do it.
My query
SELECT
CONVERT(VARCHAR(8), DATEADD(ms, DATEDIFF(ms, CONVERT(VARCHAR(8), GETDATE(), 114), CONVERT(VARCHAR(8), VCTime, 114)), 0), 114) AS TImeDifference
FROM
Test
Output:
TimeDifference
---------------
10:51:37
20:51:37
21:51:37
22:21:37
08:51:37
00:51:37
Expected Output
TimeDifference
---------------
10h:51m:37s
20h:51m:37s
21h:51m:37s
22h:21m:37s
08h:51m:37s
00h:51m:37s

One way is to use sub query and concatenation operator + for 2008 with DATEPART function as below:
SELECT (
CAST(DATEPART(HOUR,(TImeDifference)) AS VARCHAR) + 'h:' +
CAST(DATEPART(MINUTE,(TImeDifference)) AS VARCHAR) + 'm:' +
CAST(DATEPART(SECOND,(TImeDifference)) AS VARCHAR) + 's')
FROM(
SELECT
CONVERT(varchar(8), DATEADD(ms, DATEDIFF(ms, convert(varchar(8),getdate(),114),
convert(varchar(8),VCTime,114)), 0), 114) as TImeDifference
FROM test
) t
Yes I realized concat is introduced in 2012 so we can use + instead

you can follow below way
DECLARE #x int,
#dt1 smalldatetime = '2018-08-17 03:24:16',
#dt2 smalldatetime = getdate()
SET #x = datediff (s, #dt1, #dt2)
SELECT convert(varchar, #x / (60 * 60 * 24)) + ':'
+ convert(varchar, dateadd(s, #x, convert(datetime2, '0001-01-01')), 108)
this will return 1:05:57:00

Try this:
select cast(date_diff / 3600 as varchar(4)) + 'h:' +
cast((date_diff % 3600) / 60 as varchar(4)) + 'm:' +
cast(date_diff % 60 as varchar(4)) + 's'
from (
select datediff(second, getdate(), VCTime) date_diff from my_table
) a

First, you should not be converting to strings to get the difference. I think this should be fine:
SELECT CONVERT(VARCHAR(8),
DATEDIFF(ms, CAST(GETDATE() as TIME), CAST(VCTime as TIME)),
114
) as TImeDifference
FROM Test;
Then you want to add "h", "m", and "s". You can use the STUFF() function. But let me do this using APPLY so the code doesn't look quite so messy:
SELECT ( STUFF(STUFF(TimeDifference_str, 6, 0, 'm'), 3, 0, 'h') + 's' ) as TimeDifference_hms
FROM test t CROSS APPLY
(VALUES (CONVERT(VARCHAR(8),
DATEDIFF(ms, CAST(GETDATE() as TIME), CAST(VCTime as TIME)),
114
)
)
) v(TimeDifference_str)

Related

Unable to get difference between 2 dates in required format

My start and finish columns are in the format Yyyy-mm-dd HH:mm:ss.ms I want the difference between the two in HH:mm:ss.ms format. How do I go about this?
My query looks like this:
select *, convert(time,
Dateadd(s,
Datediff(s, A.Finish, A.Start),
Cast('1900-01-01 00:00:00.000000' as datetime2)
)
) as dif
from (
select *,
dateadd(s,convert(int,left(start,10)),'1970-01-01') as Start,
dateadd(s,convert(int,left(finish,10)),'1970-01-01') as Finish,
from tableB
) A
order by dif asc
I've converted unix time stamps to standard format in inner query. When I run this the start date and start time appear as '2019-12-11 15:45:20.000' and '2019-12-12 15:45:17.000' but my dif appears as '00:00:03',which is wrong.
Any help would be appreciated
I have used two sources to try to help you:
https://www.rodolforodarte.com/2011/05/using-datediff-to-display-hhmmss/
AND
Show datediff as seconds, milliseconds
Here is my result code:
DECLARE #START_DATE DATETIME
DECLARE #END_DATE DATETIME
SET #START_DATE = '2011-01-01 16:00:22.000'
SET #END_DATE = '2011-01-01 22:47:21.022'
SELECT CONVERT(varchar(6), DATEDIFF(MILLISECOND, #START_DATE, #END_DATE)/3600000)
+ ':'
+ RIGHT('0' + CONVERT(varchar(2), (DATEDIFF(MILLISECOND, #START_DATE, #END_DATE) % 3600000) / 60000), 2)
+ ':'
+ RIGHT('0' + CONVERT(varchar(2), ((DATEDIFF(MILLISECOND, #START_DATE, #END_DATE) % 3600000) % 60000) / 1000), 2)
+ ':'
+ RIGHT('000' + CONVERT(varchar(2), (((DATEDIFF(MILLISECOND, #START_DATE, #END_DATE) % 3600000) % 60000) % 1000)), 3) AS 'HH:MM:SS:MS'
And here is a small demo

Sql Server select datetime without seconds

I have datetime column value below
2015-01-04 20:37:00.000
I tried below
cast(cast(MyDateColumn as date) as datetime)+cast(datepart(hour,MyDateColumn ) as float)/24
as MyDateColumn
and
CAST(CONVERT(CHAR(16),MyDateColumn,113) AS datetime) as MyDateColumn
These are did not work for me
How can i get above datetime as 01-04.2015 20:37 ?
Since MS SQL 2012, you can use FORMAT,
SELECT FORMAT([MyDateColumn], 'dd-MM.yyyy HH:mm')
In MYSQL it will work
SELECT DATE_FORMAT(date, '%Y-%m-%d %H:%i') AS formated_date FROM table;
In MS SQL It will work
SELECT FORMAT(getdate(), 'dd-mm-yyyy HH:mm')
In SQL Server this will work:
DECLARE #now [datetime];
SET #now = GETDATE();
SELECT
CONVERT([varchar](10), #now, 105) + ' ' +
RIGHT('0' + CONVERT([varchar](2), DATEPART(HOUR, #now)), 2) + ':' +
RIGHT('0' + CONVERT([varchar](2), DATEPART(MINUTE, #now)), 2);
In SQL Server this should do the trick:
declare #dt datetime = '2015-01-04 20:37:00.000'
select right('0' + cast(DATEPART(MM, #dt) as varchar), 2) + '-'
+ right('0' +cast(DATEPART(DAY, #dt) as varchar), 2) + '.'
+ cast(DATEPART(YEAR, #dt) as varchar) + ' '
+ right('0' +cast(DATEPART(HOUR, #dt) as varchar), 2) + ':'
+ right('0' +cast(DATEPART(MINUTE, #dt) as varchar), 2)
Simply,
SELECT CAST(CONVERT(varchar, GETDATE(), 100) as datetime)
Here's another way and you get a datetime in return.
SELECT DATEADD(
MILLISECOND,
DATEPART(MILLISECOND, '2016-02-16 13:45:24.573') * -1,
DATEADD(SECOND, DATEPART(SECOND,'2016-02-16 13:45:24.573') * -1,
'2016-02-16 13:45:24.573')
)
this is the way i do it. I needed to get -2 minutes
select CONVERT(datetime, CONVERT(CHAR(18), DATEADD(minute, -2, getdate()) , 113) + '00')
Format(Cast(Convert(varchar(15),Cast(timeval as Time),100) as DateTime),'hh:mm tt') As newtime
This will remove seconds from time as well as add AM,PM with time.

SQL SELECT HH:MM - HH:MM

I am trying to write an SQL query that will return the current time as follows:
HH:MM - HH:MM (+1)
E.g. if the time is 14:00 it would return 14:00 - 15:00
I have managed to get as far as follows:
SELECT TOP (30)
DATEADD(HOUR, DATEDIFF(HOUR, 0, QUEUE_TIME.QueueDate), 0) AS 'DateAdded',
CAST(CONVERT(VARCHAR(2), DATEPART(HH, QUEUE_TIME.QueueDate), 108) AS VARCHAR(2)) + ' - ' +
CAST(CONVERT(VARCHAR(2), DATEPART(HH, QUEUE_TIME.QueueDate), 108) + 1 AS VARCHAR(2)) AS Interval,
QUEUE_TYPE.Name, QUEUE_TIME.QueueTypeId,
MAX(QUEUE_TIME.QueuedTimeInSec / 60) AS 'WaitingTimeInSec',
CAST(ROUND(AVG(QUEUE_TIME.FlowRateWhenJoinedPerMin), 1) AS numeric(36, 2)) AS AvgFlowRate
FROM
QUEUE_TIME
INNER JOIN
QUEUE_TYPE ON QUEUE_TIME.QueueTypeId = QUEUE_TYPE.Id
WHERE
(QUEUE_TIME.QueueDate >= '11/07/2014 00:00')
AND (QUEUE_TIME.IsFreeFlowing = '0')
AND (QUEUE_TIME.QueueTypeId = '3')
GROUP BY
DATEADD(HOUR, DATEDIFF(HOUR, 0, QUEUE_TIME.QueueDate), 0),
DATEPART(HOUR, QUEUE_TIME.QueueDate), QUEUE_TYPE.Name, QUEUE_TIME.QueueTypeId
ORDER BY
'DateAdded'
This will return as follows, e.g. if it is 8am it will return 8-9. But i need it to be in the format 08:00 - 09:00.
Any assistance would be appreciated.
I am using SQL Server 2008.
Thanks
This is an example, you can replace #now variable with column name:
declare #now datetime = getdate()
select convert(varchar(5), #now, 114) + ' - ' +
convert(varchar(5), dateadd(hour, 1, #now), 114) yourColumn
SQL Fiddle demo
Try with FORMAT for SQL Server 2012+:
SELECT FORMAT(GETDATE(), 'HH:mm') + '-' + FORMAT(DATEADD(HH, 1, GETDATE()), 'HH:mm')

how to convert nvarchar(50) to datetime in sqlserver 2008

hi i wrote this query in SqlServer 2008
but some thing goes wrong
select * from News_Table
where (DATEDIFF( DAY ,convert(datetime, NewsDate) , convert(datetime,#Todaydate )) <= #Count)
that #NewsDate and #Todaydate are two nvarchar parameters that are saved like this 2014/11/16
running this query give me an error:
Conversion failed when converting date and/or time from character string
Try adding the correct style parameter to your convert function (see MSDN: link )
ie CONVERT(DATETIME, NewsDate, 111) (111 is the style for YYYY/MM/DD)
Then you get:
SELECT *
FROM News_Table
WHERE (DATEDIFF( DAY ,
CONVERT(DATETIME, NewsDate, 111) ,
CONVERT(DATETIME,#Todaydate, 111)
) <= #Count)
use Convert(datetime, #yourvalue, 111)
select * from News_Table
where (DATEDIFF( DAY ,convert(datetime, #NewsDate, 111) , convert(datetime,#Todaydate, 111 )) <= #Count)
http://www.sqlusa.com/bestpractices/datetimeconversion/
To know more click here
SELECT convert(datetime, '2014/11/16', 111) as datetime
OP
So your query would be like this
Select * from News_Table
where (DATEDIFF( DAY ,convert(datetime, '2014/11/16', 111) , convert(datetime,#Todaydate,111 )) <= #Count)
Try like this
SELECT *
FROM News_Table
WHERE (DATEDIFF(DAY,CAST(NewsDate AS Datetime),CAST(#Todaydate AS Datetime)) <= #Count)
You will need to do something like this to convert that string into DATETIME datatype
DECLARE #Date NVARCHAR(20) = '2013/11/16'
SELECT CAST((LEFT(#Date, 4) + SUBSTRING(#Date, 6 ,2) + RIGHT(#Date, 2)) AS DATETIME)
for your query
select * from News_Table
where (DATEDIFF( DAY , CAST((LEFT(NewsDate, 4) + SUBSTRING(NewsDate, 6 ,2) + RIGHT(NewsDate, 2)) AS DATETIME)
, CAST((LEFT(#Todaydate, 4) + SUBSTRING(#Todaydate, 6 ,2) + RIGHT(#Todaydate, 2)) AS DATETIME)
) <= #Count)
Note
If variable #Todaydate is actually storing today's date then why not use simply GETDATE() function.

DATEDIFF in HH:MM:SS format

I need to calculate the total length in terms of Hours, Minutes, Seconds, and the average length, given some data with start time and end time.
For example the result must be something like 45:15:10 which means 45 hours 15 min 10 sec, or 30:07 for 30 min 07 sec.
We're using SQL Server 2008 R2 and the conversion failed when time is more than 24:59:59. Any idea of how I could do this?
For information, the columns in the table are Id, StartDateTime, EndDateTime, etc. I need to make a monthly report which contains the recordings count of the month, the total length of these records, and the average length. I'd like to know if there is an easy way to perform all of this.
You shouldn't be converting to time - it is meant to store a point in time on a single 24h clock, not a duration or interval (even one that is constrained on its own to < 24 hours, which clearly your data is not). Instead you can take the datediff in the smallest interval required (in your case, seconds), and then perform some math and string manipulation to present it in the output format you need (it might also be preferable to return the seconds to the application or report tool and have it do this work).
DECLARE #d TABLE
(
id INT IDENTITY(1,1),
StartDateTime DATETIME,
EndDateTime DATETIME
);
INSERT #d(StartDateTime, EndDateTime) VALUES
(DATEADD(DAY, -2, GETDATE()), DATEADD(MINUTE, 15, GETDATE())),
(GETDATE() , DATEADD(MINUTE, 22, GETDATE())),
(DATEADD(DAY, -1, GETDATE()), DATEADD(MINUTE, 5, GETDATE())),
(DATEADD(DAY, -4, GETDATE()), DATEADD(SECOND, 14, GETDATE()));
;WITH x AS (SELECT id, StartDateTime, EndDateTime,
d = DATEDIFF(SECOND, StartDateTime, EndDateTime),
a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER()
FROM #d
)
SELECT id, StartDateTime, EndDateTime,
[delta_HH:MM:SS] = CONVERT(VARCHAR(5), d/60/60)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2),
[avg_HH:MM:SS] = CONVERT(VARCHAR(5), a/60/60)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2)
FROM x;
Results:
id StartDateTime EndDateTime delta_HH:MM:SS avg_HH:MM:SS
-- ------------------- ------------------- -------------- ------------
1 2013-01-19 14:24:46 2013-01-21 14:39:46 48:15:00 42:10:33
2 2013-01-21 14:24:46 2013-01-21 14:46:46 0:22:00 42:10:33
3 2013-01-20 14:24:46 2013-01-21 14:29:46 24:05:00 42:10:33
4 2013-01-17 14:24:46 2013-01-21 14:25:00 96:00:14 42:10:33
This isn't precisely what you asked for, as it won't show just MM:SS for deltas < 1 hour. You can adjust that with a simple CASE expression:
;WITH x AS (SELECT id, StartDateTime, EndDateTime,
d = DATEDIFF(SECOND, StartDateTime, EndDateTime),
a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER()
FROM #d
)
SELECT id, StartDateTime, EndDateTime,
[delta_HH:MM:SS] = CASE WHEN d >= 3600 THEN
CONVERT(VARCHAR(5), d/60/60) + ':' ELSE '' END
+ RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2),
[avg_HH:MM:SS] = CASE WHEN a >= 3600 THEN
CONVERT(VARCHAR(5), a/60/60) + ':' ELSE '' END
+ RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2)
FROM x;
This query changes the delta column in the 2nd row in the above result from 0:22:00 to 22:00.
I slightly modified Avinash's answer as it may end with error if difference is too big. If you need only HH:mm:ss it is sufficient to distinguish at seconds level ony like this:
SELECT CONVERT(time,
DATEADD(s,
DATEDIFF(s,
'2018-01-07 09:53:00',
'2018-01-07 11:53:01'),
CAST('1900-01-01 00:00:00.0000000' as datetime2)
)
)
SELECT CONVERT(time,
DATEADD(mcs,
DATEDIFF(mcs,
'2007-05-07 09:53:00.0273335',
'2007-05-07 09:53:01.0376635'),
CAST('1900-01-01 00:00:00.0000000' as datetime2)
)
)
If you want to do averages, then the best approach is to convert to seconds or fractions of a day. Day fractions are convenient in SQL Server, because you can do things like:
select avg(cast(endtime - starttime) as float)
from t
You can convert it back to a datetime using the reverse cast:
select cast(avg(cast(endtime - starttime as float) as datetime)
from t
The arithmetic to get the times in the format you want . . . that is a pain. You might consider including days in the final format, and using:
select right(convert(varchar(255), <val>, 120), 10)
To get the hours exceeding 24, here is another approach:
select cast(floor(cast(<val> as float)*24) as varchar(255))+right(convert(varchar(255), <val>, 120), 6)
It uses convert for minutes and seconds, which should be padded with 0s on the left. It then appends the hours as a separate value.
Starting in SQL SERVER 2012, you don't need to use DATEDIFF function. You can use FORMAT function to achieve what you want:
SELECT
FORMAT(CONVERT(TIME, [appoitment].[Start] - [appointment].[End]), N'hh\:mm') AS 'Duration'
FROM
[tblAppointment] (NOLOCK)
A way that avoids overflows and can include days and go all the way to milliseconds in the output:
DECLARE #startDate AS DATETIME = '2018-06-01 14:20:02.100'
DECLARE #endDate AS DATETIME = '2018-06-02 15:23:09.000'
SELECT CAST(DATEDIFF(day,'1900-01-01', #endDate - #startDate) AS VARCHAR) + 'd ' + CONVERT(varchar(22), #endDate - #startDate, 114)
The above will return
1d 01:03:06:900
And, off course, you can use the formatting of your choice
SQL Supports datetime substraction which outputs a new datetime relative to the MIN date (for instance 1900-01-01, you can probably get this value from some system variable) This works better than DATEDIFF, because DATEDIFF will count ONE for each "datepart boundaries crossed", even if the elapsed time is less than a whole datapart. Another nice thing about this method is that it allows you to use the date formatting conversions.
If days is the (positive) number of days, like 0.5 for 12 hours, use this expression to format it as a proper duration:
CONVERT(varchar(9), FLOOR(days * 24)) + RIGHT(CONVERT(char(19), CAST(days AS datetime), 120), 6)
Excel will understands values up to 9999:59:59 when pasted. There apply a custom format: [h]:mm:ss in the English version ([u]:mm:ss for Dutch).