2012年,SO出现了一个问题,.NET的DateTime是否能够识别leap秒。 [1]答案是否定的。
文档仍然明确指出不是。 [2]
但是,Windows Server 2019和Windows 10 October 2018更新使 Windows本身跃居第二位。 [3]
这引出了一个问题:.NET现在天生就知道了吗?更具体地说:我是否可以通过选择加入来使我的DateTime
结构跃升为秒?
编辑:
摘自MS Word文档,标题为“任务:在Windows上编写一个跃升的第二感知应用程序” [4](我强调):
已知问题:某些框架已知会错误地计算时间 second秒发生后。例如,.NET Framework使用其 自己的内部逻辑来确定现在几点。它的逻辑不 占leap秒。因此,将a秒引入 操作系统的“ System.DateTime.Now.ToString()”的输出将 比本地系统时间提前一秒。 (我们正在与 .NET框架小组对此。)
从[5]开始:
已知某些应用程序通过假设错误地计算时间 一分钟总有60秒。由于leap秒可以 更改此行为,他们会在此期间错误地记录时间 事件。例如(在撰写本文时):
.NET Framework使用 它自己的内部逻辑来确定现在和现在的时间 占leap秒。因此,PowerShell依赖于 .NET Framework,在使用时不会报告第61秒(数字60) 获取日期
事件查看器:事件的日期将不正确 记录下来。但是,事件元数据将正确记录系统 时间(显示60秒)。
注意:这些团队正在努力更新其软件以供使用 处理leap秒时更合适的数学。
因此,.NET似乎将在未来的某个时候leap之以鼻。因此,我不会将其发布为解决方案。
[1] Are .Net's DateTime methods capable of recognising a Leap Second?
[3] https://support.microsoft.com/en-us/help/2722715/support-for-the-leap-second
[4] https://aka.ms/Dev-LeapSecond(MS Word)
[5] https://aka.ms/ITPro-LeapSecond(MS Word)
答案 0 :(得分:2)
[H] ere是对.NET(4.7.2版)如何在 支持the秒的Windows版本(即Windows 10 RS5 发布):
DateTime(DT)和DateTimeOffset(DTO)的更改方式不变 存储时间单位以及如何在这些单位上进行操作。这些类型只是 存储刻度,刻度为100纳秒。在之间转换时 刻度和日期/时间部分(例如,年月,日,小时,分钟,秒, 毫秒),它始终假设分钟为60秒,不能为 61秒即no或秒中没有计算count秒 转换。
在DT和DTO上调用Now属性时,我们最终会 调用Windows API(例如GetSystemTimeAsFileTime)。 GetSystemTimeAsFileTime在那里计算了the秒。因此,.NET 在启用the秒的系统上运行时,正在执行额外的步骤 通过调用更多Windows API来获取准确的时间,该API可以报告 系统时间以确保.NET报告的时间与 系统。为了.NET,.NET仍在调用GetSystemTimeAsFileTime 获得更精确的时间(准确度为100纳秒)。
以防万一 Windows向我们报告第二个数字60(这是a秒),. NET 会假设这是该分钟的最后一秒,并将其用作 第二个59,以使其与DT和DTO无缝协作 不知道leap秒。
如果有人尝试使用以下命令创建DT或DTO: second秒(60),. NET将首先通过调用Windows API进行检查 是有效的leap秒,然后将其转换为第二个数字59。如果是 valid秒无效,那么我们将抛出异常。
.NET不变 DT和DTO如何工作以实现应用程序兼容性 知道许多用户在他们的代码中做相同的假设 始终有分钟是60秒。并在不同的系统中打勾 不能表示不同的时间。让我知道您是否还有其他问题 或者您需要更多说明
来源:https://github.com/dotnet/dotnet-api-docs/issues/966#issuecomment-434440807
答案 1 :(得分:0)
通过提供更多可能感兴趣的细节来扩展已接受的答案。
虽然UTC知道偶尔(且有争议的[1])会插入,秒,但Windows Server 2019之前的.NET DateTime
结构却并非Windows 10 October 2018更新[2],因为Windows本身都不是。[3] [4]
但是,即使Window的内核现在可以感知leap秒了,除非采取特定措施,应用程序仍然不知道。[5] .NET框架本身尚不支持leap秒。[6]
但是,Windows系统通过NTP(使用UTC)来更新时间,这是leap秒。[7]这可能会导致Windows系统的时间中断,因为充当NTP客户端的Windows时间服务可能希望在the秒之后的下一次同步时立即同步系统时间,从而可能导致时钟向后跳1秒。[8] < / p>
当然,负时间值的发生可能会导致(并且在Linux系统上确实发生[9] [10]),从而导致不良或不可预测的行为,这就是Windows不允许这种情况发生的原因。
调用DateTime.Now
方法时,将调用具有aware秒意识的Windows API函数GetSystemTimeAsFileTime
。当获得the秒23:59:60 UTC时,它将被视为23:59:59 UTC的第二次出现,而无需重新计算100 ns的滴答声,而是将该秒的所有1000万滴答声保持在最大滴答声计数下而是将计时有效地暂停了一秒钟。[11]
请注意,在DateTime
结构中输入23:59:60作为时间会导致.Net按照到目前为止发生的leap秒执行检查。如果确实如此,它将被接受(但转换为23:59:59)。[11]
[1]国际地球自转和参考系统服务(IERS);协调世界时(UTC)保持“ le秒” – https://www.iers.org/SharedDocs/Publikationen/EN/IERS/Publications/messages/IERS_Message_No_282.html
[2]微软; DateTime.Ticks属性– https://docs.microsoft.com/en-us/dotnet/api/system.datetime.ticks?redirectedfrom=MSDN&view=netframework-4.8#System_DateTime_Ticks
[3]微软; Windows时间服务如何处理a秒– https://support.microsoft.com/en-us/help/909614/how-the-windows-time-service-treats-a-leap-second
[4]微软;支持the秒– https://support.microsoft.com/en-us/help/2722715/support-for-the-leap-second
[5]微软;对开发人员的第二次验证-https://aka.ms/Dev-LeapSecond
[6]微软;面向IT专业人员的飞跃秒验证– https://aka.ms/ITPro-LeapSecond
[7] D. Mills(特拉华大学); Second秒处理– https://www.eecis.udel.edu/~mills/ntp/html/leap.html
[8]微软; Windows时间服务如何处理a秒– https://support.microsoft.com/en-us/help/909614/how-the-windows-time-service-treats-a-leap-second
[9]有线; “ Le秒”错误在整个Web上造成严重破坏– https://www.wired.com/2012/07/leap-second-bug-wreaks-havoc-with-java-linux/
[10] /root.in;飞跃在Linux内核中的第二个错误– https://www.slashroot.in/leap-second-bug-linux-kernel
[11] GitHub;飞跃的第二句话令人困惑– https://github.com/dotnet/dotnet-api-docs/issues/966#issuecomment-434440807