14

I have two nullable datetime objects, I want to compare both. What is the best way to do it?

I have already tried:

DateTime.Compare(birthDate, hireDate);

This is giving an error, maybe it is expecting dates of type System.DateTime and I have Nullable datetimes.

I have also tried:

birthDate > hiredate...

But the results are not as expected...any suggestions?

Rahul Nikate
  • 6,192
  • 5
  • 42
  • 54
faizanjehangir
  • 2,771
  • 6
  • 45
  • 83
  • Is null < date? What about null and null? – zmbq Jan 10 '13 at 06:32
  • 1
    How are the results different from what you expected when you use `birthDate > hireDate`, because that is the easiest way to do it. C# introduced **lifted operators** to make things easy for you. – Jeppe Stig Nielsen Jul 31 '14 at 14:47
  • 1
    Possible duplicate of [Comparing nullable DateTime?](https://stackoverflow.com/questions/13673117/comparing-nullable-datetime) – Daniel B May 28 '18 at 19:15

8 Answers8

25

To compare two Nullable<T> objects use Nullable.Compare<T> like:

bool result = Nullable.Compare(birthDate, hireDate) > 0;

You can also do:

Use the Value property of the Nullable DateTime. (Remember to check if both object Has some values)

if ((birthDate.HasValue && hireDate.HasValue) 
    && DateTime.Compare(birthDate.Value, hireDate.Value) > 0)
{
}

If both values are Same DateTime.Compare will return you 0

Something Like

DateTime? birthDate = new DateTime(2000, 1, 1);
DateTime? hireDate = new DateTime(2013, 1, 1);
if ((birthDate.HasValue && hireDate.HasValue) 
    && DateTime.Compare(birthDate.Value, hireDate.Value) > 0)
{
}
Habib
  • 219,104
  • 29
  • 407
  • 436
  • 3
    If nullable does not have value, you will get exception trying to access Value property – Sergey Berezovskiy Jan 10 '13 at 06:23
  • What integer values will be returned in each case, i.e. > < == – faizanjehangir Jan 10 '13 at 06:25
  • If either of the dates is null, .Value will be null and will throw an InvalidOperationException with "Nullable object must have a value". The OP might want to add the null checks in there. – Ravi Y Jan 10 '13 at 06:25
  • @lazyberezovsky then what do you suggest is the best method? as I do have cases where values can be null. – faizanjehangir Jan 10 '13 at 06:26
  • `var equal = Nullable.Compare(birthDate, hireDate);` – Maarten Sep 09 '13 at 08:49
  • That long expression `(birthDate.HasValue && hireDate.HasValue) && DateTime.Compare(birthDate.Value, hireDate.Value) > 0` always produces the same result as C#'s **lifted operator**, so just say `birthDate > hireDate`. Much easier when the struct overloads the `>` operator. – Jeppe Stig Nielsen Jul 31 '14 at 14:58
  • @Maarten `DateTime?` does not have a `Compare` method. You meant `Nullable.Compare(birthDate, hireDate)` instead. – Jeppe Stig Nielsen Jul 31 '14 at 15:01
12

Nullable.Equals Indicates whether two specified Nullable(Of T) objects are equal.

Try:

if(birthDate.Equals(hireDate))

The best way would be: Nullable.Compare Method

Nullable.Compare(birthDate, hireDate));
Vishal Suthar
  • 17,013
  • 3
  • 59
  • 105
4

If you want a null value to be treated as default(DateTime) you could do something like this:

public class NullableDateTimeComparer : IComparer<DateTime?>
{
    public int Compare(DateTime? x, DateTime? y)
    {
        return x.GetValueOrDefault().CompareTo(y.GetValueOrDefault());
    }
}

and use it like this

var myComparer = new NullableDateTimeComparer();
myComparer.Compare(left, right);

Another way to do this would be to make an extension method for Nullable types whose values are comparable

public static class NullableComparableExtensions
{
    public static int CompareTo<T>(this T? left, T? right)
        where T : struct, IComparable<T>
    {
        return left.GetValueOrDefault().CompareTo(right.GetValueOrDefault());
    }
}

Where you'd use it like this

DateTime? left = null, right = DateTime.Now;
left.CompareTo(right);
mlorbetske
  • 5,529
  • 2
  • 28
  • 40
4

Use the Nullable.Compare<T> method. Like this:

var equal = Nullable.Compare<DateTime>(birthDate, hireDate);
Maarten
  • 22,527
  • 3
  • 47
  • 68
1

As @Vishal stated, simply use overriden Equals method of Nullable<T>. It is implemented this way:

public override bool Equals(object other)
{
    if (!this.HasValue)    
        return (other == null);

    if (other == null)    
        return false;

    return this.value.Equals(other);
}

It returns true if either both nullable structs do not have value, or if their values are equal. So, simply use

birthDate.Equals(hireDate)
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
1

Try

birthDate.Equals(hireDate)

and do your stuff after comparison.

Or, use

object.equals(birthDate,hireDate)
Pang
  • 9,564
  • 146
  • 81
  • 122
MahaSwetha
  • 1,058
  • 1
  • 12
  • 21
1

I think you could use the condition in the following manner

birthdate.GetValueOrDefault(DateTime.MinValue) > hireddate.GetValueOrDefault(DateTime.MinValue)
V4Vendetta
  • 37,194
  • 9
  • 78
  • 82
0

You can write a generic method to calculate Min or Max for any type like below:

public static T Max<T>(T FirstArgument, T SecondArgument) {
    if (Comparer<T>.Default.Compare(FirstArgument, SecondArgument) > 0)
        return FirstArgument;
    return SecondArgument;
}

Then use like below:

var result = new[]{datetime1, datetime2, datetime3}.Max();
Rahul Nikate
  • 6,192
  • 5
  • 42
  • 54