C# - .net core DateTime 转换为 UTC 分钟偏移量

Fra*_*ceq 5 .net c# datetime .net-core

我正在测试代码并发现一个非常奇怪的行为。当我使用DateTime.MinValue,为其添加分钟并将其转换为 UTC 时,我的本地时区和 UTC 之间似乎存在 58 分钟的差异。我在中欧(冬天+1,夏天+2)。怎么会是58分钟?我预计会有 1 小时的偏移,而不是 58 分钟。我在 Linux 上使用 .net core。

var x1 = DateTime.MinValue.AddMinutes(61);
var x1ticks = x1.Ticks;
var x1kind = x1.Kind;
var y1 = x1.ToUniversalTime();
var y1tickes = y1.Ticks;
var y1kind = y1.Kind;

var z1 = TimeZoneInfo.ConvertTimeToUtc(x1, TimeZoneInfo.Local);
var z1ticks = z1.Ticks;
var z1kind = z1.Kind;
Run Code Online (Sandbox Code Playgroud)

带有评估值的代码片段带有评估值的代码片段

Swe*_*per 5

58 分钟大约是捷克共和国布拉格当地时间维基百科)与 UTC 的偏移量。我的猜测是您当地的时区是Europe/Prague

TimeZoneInfo从计算机上的时区数据库查找时区数据。在 Linux 机器上(我认为是所有 POSIX 机器),默认值是 IANAtz数据库。在 Windows 计算机上,默认情况下您将查询 Windows 时区数据库。

无论如何,重要的是,根据 IANA 数据库,您当地时区的 UTC 偏移量+ DateTime.MinValue61 分钟,是+ 58 分钟。

// prints 00:58:00
Console.WriteLine(TimeZoneInfo.FindSystemTimeZoneById("Europe/Prague").GetUtcOffset(DateTime.MinValue));
Run Code Online (Sandbox Code Playgroud)

另请参阅这篇文章

IANA 数据库实际上表示偏移量是 57 分 44 秒,但 .NET Core 实际上将其舍入为实现细节,因为它不支持秒。我找到了这源代码来解释它:

    private static TimeSpan TZif_CalculateTransitionOffsetFromBase(TimeSpan transitionOffset, TimeSpan timeZoneBaseUtcOffset)
    {
        TimeSpan result = transitionOffset - timeZoneBaseUtcOffset;

        // TZif supports seconds-level granularity with offsets but TimeZoneInfo only supports minutes since it aligns
        // with DateTimeOffset, SQL Server, and the W3C XML Specification
        if (result.Ticks % TimeSpan.TicksPerMinute != 0)
        {
            result = new TimeSpan(result.Hours, result.Minutes, 0);
        }

        return result;
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果有人需要 +0:57:44,他们可以随时使用我的 Noda Time 项目 - 我刚刚检查过,并且报告正确:) (2认同)