通过 Win 10 Oct 2018 更新,Windows 可以感知闰秒。现在.NET 的DateTime 也是如此吗?

5 .net time datetime utc leap-second

2012年,这里有一个关于SO的问题,.NET的DateTime是否能够识别闰秒。[1] 答案是否定的。

\n

文档仍然明确指出事实并非如此。[2]

\n

然而,Windows Server 2019 和 Windows 10 October 2018 更新让Windows 本身意识到了闰秒。[3]

\n

这就引出了一个问题:.NET 现在本质上能够感知闰秒吗?更具体地说:我可以DateTime通过某种方式选择让我的结构也意识到闰秒吗?

\n

编辑:

\n

来自标题为“Quest:在 Windows 上编写闰秒感知应用程序”的 MS Word 文档 [4](由我强调):

\n
\n

已知问题:已知某些框架在闰秒发生后\n会错误地计算时间。例如,.NET Framework 使用其\n内部逻辑来确定现在是什么时间。它的逻辑不\n考虑闰秒。因此,在操作系统中引入闰秒后,\n\xe2\x80\x9cSystem.DateTime.Now.ToString()\xe2\x80\x9d 的输出将\n比本地系统时间提前一秒。 (我们正在与 .NET 框架团队合作解决此问题。)

\n
\n

并来自[5]:

\n
\n

已知某些应用程序会错误地计算时间,\n假设一分钟总是 60 秒。由于闰秒可以\n改变此行为,因此它们将不正确地记录\n此事件期间的时间。例如(在撰写本文时):

\n

.NET Framework 使用自己的内部逻辑来确定现在的时间,并且不考虑闰秒。因此,依赖于\n.NET Framework 的 PowerShell 在使用\nGet-Date 时不会报告第 61 秒(数字 60)

\n

事件查看器:事件的日期将被错误\n记录。但是,事件元数据将正确记录系统时间(显示第 60 秒)。

\n

注意:这些团队正在努力更新其软件,以便在处理闰秒时\n使用更合适的数学方法

\n
\n

因此,.NET 似乎会在未来的某个时候意识到闰秒。因此我不会将此作为解决方案发布。

\n

[1] .Net 的 DateTime 方法能够识别闰秒吗?

\n

[2] https://learn.microsoft.com/en-us/dotnet/api/system.datetime.ticks?redirectedfrom=MSDN&view=netframework-4.8#System_DateTime_Ticks

\n

[3] https://support.microsoft.com/en-us/help/2722715/support-for-the-leap-second

\n

[4] https://aka.ms/Dev-LeapSecond(MS Word)

\n

[5] https://aka.ms/ITPro-LeapSecond(MS Word)

\n

小智 3

\n

[H]以下是 .NET(版本 4.7.2)如何在支持闰秒的 Windows 版本(即 Windows 10 RS5 版本)上工作的一些说明:

\n\n

DateTime (DT) 和 DateTimeOffset (DTO) 存储时间单位的方式以及对这些单位的操作方式没有改变。这些类型仅存储刻度,且刻度为 100 纳秒。当在刻度和日期/时间部分(例如年、月、日、小时、分、秒、毫秒)之间进行转换时,它始终假定分钟为 60 秒,而不能为 61 秒。即在刻度或转换中不计算闰秒。

\n\n

当调用 DT 和 DTO 上的 Now 属性时,我们最终将调用 Windows API(例如 GetSystemTimeAsFileTime)。 GetSystemTimeAsFileTime 在那里计算闰秒。因此,.NET 在支持闰秒的系统上运行时会执行额外的步骤,通过调用更多可报告系统时间的 Windows API 来获取准确的时间,以确保 .NET 报告的时间与\n 同步。系统。.NET 仍然调用 GetSystemTimeAsFileTime 以获得更精确的时间(精度为 100 纳秒)。

\n\n

如果 Windows 向我们报告第二个数字 60(这是闰秒),.NET 将假定这是该分钟的最后一秒,并将其用作第二个 59,以使其与 DT 无缝协作和 DTO 这些类型\n 不知道闰秒。

\n\n

如果有人尝试创建具有闰秒 (60) 的 DT 或 DTO,.NET 将首先通过调用 Windows API 检查这是否是有效的闰秒,然后将其转换为第二个数字 59。如果是\n无效的闰秒,那么我们将抛出异常。

\n\n

为了应用程序兼容性,.NET 没有\xe2\x80\x99 改变 DT 和 DTO 的工作方式,因为我们知道许多用户在他们的代码中做了相同的假设,即分钟总是 60 秒。并且不同系统中的刻度不能代表不同的时间。如果您还有其他问题或需要更多说明,请告诉我

\n
\n\n

来源:https ://github.com/dotnet/dotnet-api-docs/issues/966#issuecomment-434440807

\n