【问题标题】:C# - .net core DateTime conversion to UTC minutes offsetC# - .net 核心 DateTime 转换为 UTC 分钟偏移量
【发布时间】:2021-06-02 21:32:33
【问题描述】:

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

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;

使用评估值编写 sn-p 代码

【问题讨论】:

  • 你是通过设置断点来运行的吗?

标签: c# .net datetime .net-core


【解决方案1】:

58 分钟大约是捷克共和国布拉格local mean time (Wikipedia) 与 UTC 的偏移量。我猜你当地的时区是Europe/Prague

TimeZoneInfo 从您计算机上的时区数据库中查找时区数据。在 Linux 机器上(以及所有 POSIX 机器,我认为)默认是 IANA tz Database。在 Windows 计算机上,您将默认查询 Windows 时区数据库。

无论如何,重要的是,根据 IANA 数据库,DateTime.MinValue 的本地时区的 UTC 偏移量加上 61 分钟,就是加上 58 分钟。

// prints 00:58:00
Console.WriteLine(TimeZoneInfo.FindSystemTimeZoneById("Europe/Prague").GetUtcOffset(DateTime.MinValue));

另见this post

IANA 数据库实际上说偏移量是 57 分 44 秒,但 .NET Core 实际上将它作为实现细节四舍五入,因为它不支持秒。我找到了解释它的源代码的line

    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;
    }

【讨论】:

  • 如果有人需要 +0:57:44,他们总是可以使用我的 Noda Time 项目 - 我刚刚检查过,并且报告正确:)
猜你喜欢
  • 2011-03-22
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 2012-08-02
相关资源
最近更新 更多