Given the following components
DECLARE @D DATE = '2013-10-13'
DECLARE @T TIME(7) = '23:59:59.9999999'
What is the best way of combining them to produce a DATETIME2(7)
result with value '2013-10-13 23:59:59.9999999'
?
Some things which don't work are listed below.
SELECT @D + @T
Operand data type date is invalid for add operator.
SELECT CAST(@D AS DATETIME2(7)) + @T
Operand data type datetime2 is invalid for add operator.
SELECT DATEADD(NANOSECOND,DATEDIFF(NANOSECOND,CAST('00:00:00.0000000' AS TIME),@T),@D)
The datediff function resulted in an overflow. The number of dateparts
separating two date/time instances is too large. Try to use datediff
with a less precise datepart.
* The overflow can be avoided in Azure SQL Database and SQL Server 2016, using DATEDIFF_BIG
.
SELECT CAST(@D AS DATETIME) + @T
The data types datetime and time are incompatible in the add operator.
SELECT CAST(@D AS DATETIME) + CAST(@T AS DATETIME)
Returns a result but loses precision
2013-10-13 23:59:59.997
Best Answer
This seems to work and keep the precision as well:
The
CAST
toDATETIME2(7)
converts theTIME(7)
value (@T
) to aDATETIME2
where the date part is'1900-01-01'
, which is the default value of date and datetime types (seedatetime2
and the comment* atCAST
andCONVERT
page at MSDN.)* ... When character data that represents only date or only time components is cast to the datetime or smalldatetime data types, the unspecified time component is set to 00:00:00.000, and the unspecified date component is set to 1900-01-01.
The
DATEADD()
andDATEDIFF()
function take care of the rest, i.e. adding the difference in days between the1900-01-01
and theDATE
value (@D
).Test at: SQL-Fiddle
As noticed by @Quandary, the above expression is considered not-determninistic by SQL Server. If we want a deterministic expression, say because it is to be used for a
PERSISTED
column, the'19000101'
** needs to be replaced by0
orCONVERT(DATE, '19000101', 112)
:**:
DATEDIFF(day, '19000101', d)
isn't deterministic as it does an implicit conversion of the string toDATETIME
and conversions from strings to datetime are deterministic only when specific styles are used.