Here is my code:
DECLARE @d1 DATETIME
DECLARE @d2 DATETIME
SET @d1 = '2015-01-01 00:00:00'
SET @d2 = '2015-12-31 23:59:59.999'
SELECT
CASE
WHEN ('2016-01-01 00:00:00' BETWEEN @d1 AND @d2)
THEN 'is between'
ELSE 'not between'
END AS BetweenOrNotBetween
The date I supplied here is 1 msec later than the range of the BETWEEN
function, yet on my SQL 2008 server instance, the result is 'is between' and not the expected 'not between'...
Is this a bug, or is it a necessary compromise in the design for some reason I'm not seeing?
And yes, as soon as I add even a fraction of a second beyond midnight of 2016-01-01, I get the expected 'not between' result.
Look at documentation for datetime type. In section Rounding of datetime Fractional Second Precision
you will find the explanation to your issue:
datetime values are rounded to increments of .000, .003, or .007 seconds, as shown in the following table.
This means that if you have 1 millisecond, it is actually rounded to 0 milliseconds, so your result is is between
. Unfortunatelly this is how datetime
data type works, there is not much you can do about this, unless you can use other data type, like datetime2
.
If you use the code below, you'll see that the problem is the datetime type. Look at the documentation about datetime and your doubt will be solved!
DECLARE @d1 datetime2
DECLARE @d2 datetime2
SET @d1 = '2015-01-01 00:00:00.00'
SET @d2 = '2015-12-31 23:59:59.999'
SELECT CASE WHEN ('2016-01-01 00:00:00.00' BETWEEN @d1 AND @d2 ) THEN 'is between'
ELSE 'not between'
END AS BetweenOrNotBetween
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With