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);
Output:
-00:00:00.0020002
-00:00:00.0020001
01:59:59.9989999
To my surprise, DateTime.Now - DateTime.UtcNow
does not make the appropriate conversion automatically. At the same time, DateTime.UtcNow
is the same as DateTime.UtcNow.ToUniversalTime()
, 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 ToUniversalTime()
safe for both UTC and non-UTC datetimes, i.e. an already UTC datetime will not be incorrectly corrected by ToUniversalTime()
?
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.
The framework does nothing with the date if it is already UTC:
internal static DateTime ConvertTimeToUtc(DateTime dateTime, TimeZoneInfoOptions flags)
{
if (dateTime.Kind == DateTimeKind.Utc)
{
return dateTime;
}
CachedData cachedData = s_cachedData;
return ConvertTime(dateTime, cachedData.Local, cachedData.Utc, flags, cachedData);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With