Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTime Compare Ignores Kind?

Tags:

c#

datetime

utc

DateTime d1=new DateTime(2015, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime d2=new DateTime(2015, 1, 1, 0, 0, 0, DateTimeKind.Local);
Console.WriteLine(d1==d2);           // prints true
Console.WriteLine(d1<d2);            // prints false
Console.WriteLine(d1.CompareTo(d2)); // prints 0
Console.WriteLine(d1.ToUniversalTime()==d2.ToUniversalTime()); // prints false

This looks like a bug to me, if not color me surprised.

Do I have to call ToUniversalTime() for every comparison or is there a better alternative?

How do you avoid pitfalls like forgetting to call ToUniversalTime() or getting a wrong result because of DateTimeKind.Unspecified?

like image 550
laktak Avatar asked Feb 19 '15 09:02

laktak


People also ask

How do I compare two Datetimes in Python?

You can use equal to comparison operator = to check if one datetime object is has same value as other. In the following program, we initialize two datetime objects, and then check if both datetime objects have same date and time.

How do I check if one date is greater than another in C#?

Compare() Method in C# This method is used to compare two instances of DateTime and returns an integer that indicates whether the first instance is earlier than, the same as, or later than the second instance.


1 Answers

The MSDN documentation is quite clear that DateTimeKind is not taken into account using the Equality operator.

The Equality operator determines whether two DateTime values are equal by comparing their number of ticks. Before comparing DateTime objects, make sure that the objects represent times in the same time zone. You can do this by comparing the values of their Kind property.

MSDN - DateTime.Equality Operator

You could write your own extension method to include the DateTimeKind comparison:

public static bool EqualsWithKind(this DateTime time, DateTime other)
{
      return time.Kind == other.Kind &&
             time == other;
}

Taking into account the comments from Panagiotis Kanavos and James Thorpe about DateTimeOffset:

Use if the offsets are guaranteed to be the same as the local offset.

public static bool EqualsWithTimezone(this DateTime time, DateTime other)
{
      return new DateTimeOffset(time) == new DateTimeOffset(other);
}

Use if the offsets are NOT guaranteed to be the same:

public static bool EqualsInclTimezone(this DateTime time, TimeSpan timeOffset, DateTime other, TimeSpan otherOffset)
{
      return new DateTimeOffset(time, timeOffset) == new DateTimeOffset(other, otherOffset);
}
like image 136
toadflakz Avatar answered Sep 19 '22 16:09

toadflakz