sashoalm sashoalm - 10 months ago 66
C# Question

Subtracting UTC and non-UTC DateTime in C#

I assumed that when subtracting 2 datetimes the framework will check their timezone and make the appropriate conversions.

I tested it with this code:

Console.WriteLine(DateTime.Now.ToUniversalTime() - DateTime.UtcNow.ToUniversalTime());
Console.WriteLine(DateTime.Now.ToUniversalTime() - DateTime.UtcNow);
Console.WriteLine(DateTime.Now - DateTime.UtcNow);



To my surprise,
DateTime.Now - DateTime.UtcNow
does not make the appropriate conversion automatically. At the same time,
is the same as
, so obviously there is some internal flag that indicates the time zone.

Is that correct, does that framework not perform the appropriate timezone conversion automatically, even if the information is already present? If so, is applying
safe for both UTC and non-UTC datetimes, i.e. an already UTC datetime will not be incorrectly corrected by

Answer Source

The type System.DateTime does not hold time zone information, only a .Kind property that specifies whether it is Local or UTC. But before .NET 2.0, there was not even a .Kind property.

When you subtract (or do other arithmetic, like == or >, on) two DateTime values, their "kinds" are not considered at all. Only the numbers of ticks are considered. This gives compatibility with .NET 1.1 when no kinds existed.

The functionality you ask for (and expect) is in the newer and richer type System.DateTimeOffset. In particular, if you do the subtraction DateTimeOffset.Now - DateTimeOffset.UtcNow you get the result you want. The DateTimeOffset structure does not have a local/UTC flag; instead, it holds the entire time zone, such as +02:00 in your area.