Click here to Skip to main content
15,890,438 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
First of all, it may not have a practical use but just want to know how/why this is happening.

When I am trying to assign a DATETIME2 value to a DATETIME variable, there happens an unexpected roundoff in the value.

Sample SQL :
SQL
DECLARE @DT DATETIME
DECLARE @DT2 DATETIME2

SET @DT2='2015-07-23 18:35:34.8815038'
SELECT @DT=@DT2

SELECT @DT2 AS [DATETIME2],@DT AS [DATETIME]

OUTPUT :
DATETIME2	                         DATETIME               
2015-07-23 18:35:34.8815038    |     2015-07-23 18:35:34.883


Now, I am not able to find the cause why 8815038 nano seconds is rounded off to 883 milliseconds against expected 881 or 882 milliseconds.

If any body knows the exact explaination to this, please share here. :)
Posted

Datetime2 is more accurate than datetime which has only accuracy for milliseconds.

From datetime2 (Transact-SQL)[^]:
When the fractional precision of the datetime2(n) value is greater than three digits, the value will be truncated.
The following example shows the results of converting a datetime2(4) value to a datetime value.
SQL
DECLARE @datetime2 datetime2(4) = '1968-10-23 12:45:37.1237';
DECLARE @datetime datetime = @datetime2;

SELECT @datetime AS '@datetime', @datetime2 AS '@datetime2';

--Result
--@datetime               @datetime2
------------------------- ------------------------
--1968-10-23 12:45:37.123 1968-10-23 12:45:37.1237
--
--(1 row(s) affected)

What comes to the value not being 881 milliseconds this happens because of the accuracy of datetime. Datetime is not accurate on millisecond level but Accuracy is rounded to increments of .000, .003, or .007 seconds;

You can visualize this with a small loop:
SQL
DECLARE @DT DATETIME
DECLARE @DT2 DATETIME2
DECLARE @counter INT = 0
 
SET @DT2='2015-07-23 18:35:34.8815038'

WHILE @counter < 10 BEGIN
   SELECT @DT=@DT2
   SELECT @DT2 AS [DATETIME2],@DT AS [DATETIME];
   SET @DT2 = DATEADD(ms, 1, @DT2)
   SET @counter = @counter + 1
END


For more information, see datetime (Transact-SQL)[^]
 
Share this answer
 
v4
Comments
Suvendu Shekhar Giri 23-Jul-15 9:46am    
Yes. You are right. I had gone through this documentation but truncating 8815038 should result in 881 and not 883. Isn't it?
Wendelius 23-Jul-15 9:59am    
I added information about the accuracy of datetime.
Suvendu Shekhar Giri 23-Jul-15 10:23am    
It's perfect now :)
Sergey Alexandrovich Kryukov 23-Jul-15 15:20pm    
5ed.
—SA
Wendelius 24-Jul-15 0:07am    
Thanks!
Here I got the solution. I have posted the same question in Stackoverflow[^]

Quote:
The reason is that in datetime type, you only have .000, .003 and .007 fraction of a second.

Try this:
SQL
select cast('2015-01-01 00:00:00.882' as datetime)
select cast('2015-01-01 00:00:00.884' as datetime)


And you'll see that both are rounded to .883
Accuracy of datetime is rounded to increments of .000, .003, or .007 seconds.

Reference:
https://msdn.microsoft.com/en-us/library/ms187819.aspx[^]
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 23-Jul-15 15:20pm    
5ed.
—SA
Suvendu Shekhar Giri 23-Jul-15 23:51pm    
Thanks :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900