在 C# 中减去 UTC 和非 UTC 日期时间

Subtracting UTC and non-UTC DateTime in C#

我假设当减去 2 个日期时间时,框架将检查它们的时区并进行适当的转换。

我用这段代码测试了它:

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

输出:

-00:00:00.0020002
-00:00:00.0020001
01:59:59.9989999

令我惊讶的是,DateTime.Now - DateTime.UtcNow 不会自动进行适当的转换。同时,DateTime.UtcNowDateTime.UtcNow.ToUniversalTime()一样,所以显然有一些内部标志表示时区。

是否正确,即使信息已经存在,该框架是否不会自动执行适当的时区转换?如果是这样,对 UTC 和非 UTC 日期时间应用 ToUniversalTime() 是否安全,即已经是 UTC 日期时间不会被 ToUniversalTime()?

错误更正

如果日期已经是 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);
}

类型System.DateTime不保存时区信息,只有一个.Kind属性指定是本地还是UTC。但是在 .NET 2.0 之前,甚至没有 .Kind 属性.

当您减去(或进行其他算术运算,例如 ==>)两个 DateTime 值时,根本不会考虑它们的 "kinds"。仅考虑刻度数。当 no kinds existed.

时,这提供了与 .NET 1.1 的兼容性

您要求(和期望)的功能在更新和更丰富的 type System.DateTimeOffset 中。特别是,如果你做减法 DateTimeOffset.Now - DateTimeOffset.UtcNow 你会得到你想要的结果。 DateTimeOffset 结构没有 local/UTC 标志;相反,它包含整个时区,例如您所在地区的 +02:00。