Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing DateTimes with Unspecified and UTC kinds

Tags:

c#

datetime

I have 2 DateTime values:

date1 <- {15-07-13 20:45:10} with Kind = Unspecified

date2 <- {15-07-13 20:45:10} with Kind = UTC

When comparing these 2 dates, the 2 dates are equal.

if (DateTime.Compare(date1, date2)!=0)
    ...

Can someone can explain why?

A little bit more strange to me: when converting the date1 (which is Unspecified kind) to UTC, I clearly see that the date is different:

date1.ToUniversalTime() --> {15-07-13 18:45:10} with Kind = UTC

like image 790
Bronzato Avatar asked Jul 15 '13 18:07

Bronzato


People also ask

How can I compare two Datetimes?

For comparing the two dates, we have used the compareTo() method. If both dates are equal it prints Both dates are equal. If date1 is greater than date2, it prints Date 1 comes after Date 2. If date1 is smaller than date2, it prints Date 1 comes after Date 2.

What is DateTimeKind UTC?

The DateTime. SpecifyKind() method in C# is used to create a new DateTime object that has the same number of ticks as the specified DateTime but is designated as either local time, Coordinated Universal Time (UTC), or neither, as indicated by the specified DateTimeKind value.

Should you use DateTimeOffset?

DateTime values lack any knowledge of time zone, or lack thereof. If you need to know when things actually occurred, with more precision than just the approximate date, and you can't be 100% sure that your dates are ALWAYS stored in UTC, then you should consider using DateTimeOffset to represent your datetime values.


2 Answers

Does someone can explain me why?

Yup. It's because DateTime is a fundamentally broken type, IMO. Basically the Kind isn't used in comparisons. Doing so would quite possibly have broken old code, and it's not always what you want. It was added on for .NET 1.1, and not always in a great way - it definitely wasn't fully integrated in every way you might have expected, as you've seen for comparisons.

As another example, even for a Kind of Local (which is meant to be the system local time zone) it's ignored for arithmetic, which means a call of AddHours(1) really only adds to the local time, rather than it representing elapsed time (which could end up being the same local time or two hours later in local time, around DST transitions).

My advice is just to avoid comparing DateTime values of different kinds in the first place. It's almost never what you want to do.

(Of course I'd also recommend using Noda Time, but that's a slightly different matter.)

like image 112
Jon Skeet Avatar answered Nov 15 '22 22:11

Jon Skeet


From the documentation on DateTimeKind (emphasis is mine):

The members of the DateTimeKind enumeration are used in conversion operations between local time and Coordinated Universal Time (UTC), but not in comparison or arithmetic operations.

like image 38
Tim Avatar answered Nov 15 '22 21:11

Tim