Skip to content

Conversation

@roooodcastro
Copy link

From MS SQL docs, the datetime type has a millisecond precision of 1/300th of a second, or more specifically:

Rounded to increments of .000, .003, or .007 seconds

The current implementation tries to round values passed as datetime to this standard, however the implementation is giving wrong values that do not end in either 0, 3 or 7. For example, if we pass a date ending in, say, .8666667 seconds, it will incorrectly round to .865 instead of .867, which would be the correct rounding for SQL Server, and also the correct rounding anywhere.

What I did was to eliminate a couple of inversions that were being done without any good reason (in fact they only made the result stray further from the right value), and increase the precision of the divider being applied (to make the overall precision 1/300th of a second).

Now milliseconds ending in 9 are being rounded to 10, or more precisely, to 0. This means that a date of 2017-11-25 10:05:38.999499 should be rounded to 2017-11-25 10:05:39.000, but was instead being rounded to 2017-11-25 10:05:38.000. There's actually an open issue about this. The second part of this PR addresses this. We now detect if there's a "carry second", and add it to the final date, after manually changing the microseconds to the rounded value.

Overall, because of the removed inversion logic, this conversion does not add any extra execution time, and this can demonstrated with a benchmark (which I will soon add here).

@wpolicarpo
Copy link
Member

Thanks for your contribution. This was probably introduced by 67317b3.

@wpolicarpo wpolicarpo added the bug label Jan 10, 2019
@wpolicarpo wpolicarpo merged commit 20cdb9b into rails-sqlserver:master Jan 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants