genxgeek
genxgeek

Reputation: 13357

Comparing nullable DateTime?

Looking for a better way to compare a nullable date time than the following:

Any suggestions?

// myobject.ExpireDatetime is of DateTime?
//
if (!myobject.ExpireDateTime.IsNull() && DateTime.Compare((DateTime)myobject.ExpireDateTime, DateTime.Now.ToUniversalTime()) < 0)
{ //error! }    

Edited: Sorry for confusion...myobject.ExpireDatetime is of type DateTime.

Upvotes: 45

Views: 68846

Answers (6)

SomeGenericDev
SomeGenericDev

Reputation: 651

If like me you ended up on this question because you realized that equality semantics for nullable DateTimes don't make sense at all in C#, I made a Nuget package to fix this mess.

Consider giving it a look instead of going insane over it.

DateTime? dt = DateTime.Now;
DateTime? dt2 = null;
bool isGreater = dt > dt2; //false
bool isGreater2 = dt.IsGreater(dt2); //true

Upvotes: 0

Patrick
Patrick

Reputation: 764

The compiler lifts variables and generates code to check for nulls.

> new DateTime?()
null
> DateTime.Now > null
false
> DateTime.Now < null
false

> new int?()
null
> 10 >= null
false
> 10 =< null
false
> 10 == null
false
> 10 != null
true

Knowing this you can write simple code.

// d is a DateTime? 
DateTime now = DateTime.Now;

bool after = d > now;
bool before = d < now;
bool today = d?.Date == now.Date;

If d is null everything will be false, else it will work like normal DateTime comparison.

Upvotes: 13

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61952

Your question is not quite clear to me, but if we have

DateTime? ExpireDateTime;  // could be a variable or a property

it's OK to say just

if (ExpireDateTime < DateTime.UtcNow)
{
  ...
}

This will be OK if ExpireDateTime is null (HasValue is false). Some inexperienced developers will struggle to understand lifted operators, so to make it more clear, you could write

if (ExpireDateTime < (DateTime?)DateTime.UtcNow)
{
  ...
}

It's the same, but easier to read and understand.

Never write .Value if the nullable might be null, of course. You will get an InvalidOperationException "Nullable object must have a value" if you do so.

Upvotes: 57

labroo
labroo

Reputation: 2961

I would recommend you to use the following:

int y = Nullable.Compare<DateTime>(DateTime.UtcNow, x); 

// x is the nullable date time object.
// y will be '-1' if x is greater than DateTime.UtcNow

Upvotes: 42

Tim Schmelter
Tim Schmelter

Reputation: 460158

If ExpireDateTime is a Nullable<DateTime>i would do following instead:

if (ExpireDateTime.HasValue && ExpireDateTime < DateTime.Now.ToUniversalTime())
{ 
}

Upvotes: 3

Oded
Oded

Reputation: 499062

Use the Value property of the nullable:

objet.ExpireDateTime.Value

if (!object.ExpireDateTime.IsNull() 
    && DateTime.Compare(objet.ExpireDateTime.Value, 
                        DateTime.Now.ToUniversalTime()) < 0)
{ 
}    

Upvotes: 1

Related Questions