Perhaps this may help. This is a modified version my my AGE function which returns Years, Months, Days, Hours, Minutes, and Seconds.
The TimeSpan function was scaled down to Days, Hours, Minutes, Seconds, and Milliseconds.
It may look like overkill, but it is very accurate, and being a Single-Statement TVF, it is very fast.
Being a TVF, you can used as stand-alone, within a Join, or even a Cross Apply
For Example:
Select * from [dbo].[udf-Date-TimeSpan] ('2016-07-29','2016-07-30 02:03:12.345')
Returns
TimeSpan Days Hours Minutes Seconds Millisecond
1.02:03:12.348 1 2 3 12 348
The Function if Desired
ALTER FUNCTION [dbo].[udf-Date-TimeSpan] (@D1 DateTime,@D2 DateTime)
Returns Table
Return (
with cteBN(N) as (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
cteRN(R) as (Select Row_Number() Over (Order By (Select NULL))-1 From cteBN a,cteBN b,cteBN c,cteBN d,cteBN e), -- Max 100K Days or 273 Years
cteDD(N,D) as (Select Max(R),Max(DateAdd(DD,R,@D1))From cteRN R Where DateAdd(DD,R,@D1)<=@D2),
cteHH(N,D) as (Select Max(R),Max(DateAdd(HH,R,D)) From (Select Top 24 R From cteRN Order By 1) R, cteDD P Where DateAdd(HH,R,D)<=@D2),
cteMI(N,D) as (Select Max(R),Max(DateAdd(MI,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteHH P Where DateAdd(MI,R,D)<=@D2),
cteSS(N,D) as (Select Max(R),Max(DateAdd(SS,R,D)) From (Select Top 60 R From cteRN Order By 1) R, cteMI P Where DateAdd(SS,R,D)<=@D2),
cteMS(N,D) as (Select Max(R),Max(DateAdd(MS,R,D)) From (Select Top 999 R From cteRN Order By 1) R, cteSS P Where DateAdd(MS,R,D)<=@D2)
Select TimeSpan = concat(cteDD.N,'.')+Format(cteHH.N,'00:')+Format(cteMI.N,'00:')+Format(cteSS.N,'00')+'.'+Format(cteMS.N-1,'000')
,[Days] = cteDD.N
,[Hours] = cteHH.N
,[Minutes] = cteMI.N
,[Seconds] = cteSS.N
,[Millisecond] = cteMS.N-1
From cteDD,cteHH,cteMI,cteSS,cteMS
)
--Select * from [dbo].[udf-Date-TimeSpan] ('2016-07-29','2016-07-30 02:03:12.345')
Edit - Perhaps a better illustration
Declare @Table table (Date1 Datetime,Date2 DateTime)
Insert Into @Table values
('2016-01-01 00:00:00.200','2016-01-05 12:05:01.500'),
('2016-01-01 10:00:00.300','2016-01-05 12:30:30.500'),
('2016-01-01 10:00:00.800','2016-01-05 12:30:30.500')
Select A.*
,B.TimeSpan
From @Table A
Cross Apply [dbo].[udf-Date-TimeSpan] (A.Date1,A.Date2) B
Returns
Date1 Date2 TimeSpan
2016-01-01 00:00:00.200 2016-01-05 12:05:01.500 4.12:05:01.300
2016-01-01 10:00:00.300 2016-01-05 12:30:30.500 4.02:30:30.200
2016-01-01 10:00:00.800 2016-01-05 12:30:30.500 4.02:30:29.700