Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does this cast to DATETIME2 contain extra granularity?

I am trying to cast the following DATETIME to DATETIME2:

DECLARE @x DATETIME = '2021-12-10 19:58:41.333'
SELECT CAST(@x AS DATETIME2)

The result is 2021-12-10 19:58:41.3333333. Why does the cast add 0.0003333s?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Contrary to what some understand, datetime is not accurate to 1/1000th of a second, it is accurate to 1/300th of a second. This is why the last digit of a datetime is always 0, 3, or 7, as they represent 0/300th, 1/300th and 2/300th respectively of a second (3/300th would be 0 again).

For datetime2, however, the datatype can have a precision of 07. 0 meaning accurate to 1 second, and 7 being 100 nanoseconds or 1/10 microseconds.

When you convert a datetime to a datetime2 the fact that datetime is only accurate to 1/300th of a second is reflected in the converted value (Note that for older versions of SQL Server this is not true) and so will show the 1/300th to a the new degree of accuracy.

Let’s take the value you have 2021-12-10 19:58:41.333. Here the .333 is infinite, it’s more .3333333333~. This is because you can’t represent 1/3rd (or 1/300th) accurately with a base 10 number. You then convert (CAST) your value to a datetime2. You omit the precision, so this defaults to a precision of 7. This gives you 2021-12-10T19:58:41.3333333, as the 1/300th is now displayed up to a precision of 7 (note that the above is accurate to 100 nanoseconds, not 100/3 nanoseconds).

Had you had a time like 2021-12-10 19:58:41.357 and converted it to a datetime2(4) you would have got 2021-12-10 19:58:41.3567. If you were to then convert that to a datetime2(7) you would get 2021-12-10 19:58:41.3567000 as the "1/300th-ness" accuracy was lost when it was converted to a datetime2(4).

As alluded to, in older versions of SQL Server (2014 prior if I recall correctly) the above is not true. In these older versions, the datetime value 2021-12-10 19:58:41.333 would be less accurately converted to the datetime2(7) value 2021-12-10 19:58:41.3330000. If you are on an older version and rely on this behaviour, you need to explicitly convert/cast your datetime value to a datetime2(3) to avoid a likely breaking change.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading