3

When I compare a DateTime variable with SqlDateTime.MinValue:

if (StartDate > SqlDateTime.MinValue)
{
  // some code
}

I get the following runtime exception if StartDate is < SqlDateTime.MinValue:

SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

This can be easy solved with a small change:

if (StartDate > SqlDateTime.MinValue.Value)
{
  // some code
}

I understand that in the first code snippet I'm comparing apples to oranges. What I don't understand is the exception message. It seems like I'm assigning a DateTime value to a SqlDateTime variable.

What am I missing?

2
  • I forgot to state that that happened when StartDate was lower than SqlDateTime.MinValue Commented Oct 18, 2016 at 17:24
  • 2
    The compiler looks for a way to compare two completely different classes. The only way it can do it is by using the operator overload that SqlDateTime provides. But that requires it to convert the DateTime to a SqlDateTime. And that throws. The alternative you found uses the operator overload that DateTime provides. Commented Oct 18, 2016 at 21:34

2 Answers 2

2

The .NET native DateTime type (to be specific, its a structure) holds a broader range of possible values than the SqlDateTime data type can support. More specifically, a DateTime value can range from 01/01/0000 to a theoretical 12/31/9999.

When the compiler tries to coerce the types for comparison, it attempts to put a DateTime value (MinValue.Value) that's outside (below or 'before' in context) the range supported by SqlDateTime - hence the overflow.

Sign up to request clarification or add additional context in comments.

3 Comments

Why should it try to coerce the first operand into the second one and not the other way around?
I believe the compiler interprets the comparison operator as an operator defined by the SqlDataType, and thus attempts to convert the compared element to a SqlDateTime via implicit conversion.
I thought perhaps @Gnomo's question deserved a better response than I offered. In particular, the overflow happens because C#'s scope resolution mechanism chose the overload for the "less-than" operator < associated with that in the 'closest' class - 'SqlDateTime' - and the parameters for that overload are, naturally, two SqlDateTime objects. C# then notices the implicit conversion from a DateTime to SqlDateTime, and tries to assign the provided value, which then overflows. See Eric Lippert's great commentary on 'closeness' at ericlippert.com/2013/12/23/closer-is-better
0

From SqlDateTime Structure on MSDN:

SqlDateTime structure

Represents the date and time data ranging in value from January 1, 1753 to December 31, 9999 to an accuracy of 3.33 milliseconds to be stored in or retrieved from a database. The SqlDateTime structure has a different underlying data structure from its corresponding .NET Framework type, DateTime, which can represent any time between 12:00:00 AM 1/1/0001 and 11:59:59 PM 12/31/9999, to the accuracy of 100 nanoseconds. SqlDateTime actually stores the relative difference to 00:00:00 AM 1/1/1900. Therefore, a conversion from "00:00:00 AM 1/1/1900" to an integer will return 0.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.