windows FILETIME 结构是否包含闰秒?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/130573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:18:23  来源:igfitidea点击:

Does the windows FILETIME structure include leap seconds?

windowsdatetimefiletimeleap-second

提问by smoofra

The FILETIMEstructurecounts from January 1 1601 (presumably the start of that day) according to the Microsoft documentation, but does this include leap seconds?

根据 Microsoft 文档,该FILETIME结构从 1601 年 1 月 1 日(大概是那天的开始)开始计算,但这是否包括闰秒?

采纳答案by Ian Boyd

The question shouldn't be if FILETIMEincludes leap seconds.

问题不应该是是否FILETIME包括闰秒。

It should be:

它应该是:

Do the people, functions, and libraries, who interpret a FILETIME(i.e. FileTimeToSystemTime) include leap seconds when counting the duration?

在计算持续时间时,解释 a FILETIME(ie FileTimeToSystemTime)的人员、函数和库是否包括闰秒?

The simple answer is "no". FileTimeToSystemTimereturns seconds as 0..59.

简单的答案是“不”FileTimeToSystemTime返回秒为0..59.



The simpler answer is: "of course not, how could it?".

更简单的答案是:“当然不是,怎么可能?”。

My Windows 2000 machine doesn't know that there were 2 leap seconds added in the decade since it was released. Any interpretation it makes of a FILETIMEis wrong.

我的 Windows 2000 机器不知道自发布以来的十年间增加了 2 个闰秒。它对 a 的任何解释FILETIME都是错误的。



Finally, rather than relying on logic, we can determine by direct experimental observation, the answer to the posters question:

最后,不依赖逻辑,我们可以通过直接的实验观察来确定海报问题的答案:

var
    systemTime: TSystemTime;
    fileTime: TFileTime;
begin
    //Construct a system-time for the 12/31/2008 11:59:59 pm
    ZeroMemory(@systemTime, SizeOf(systemTime));
    systemtime.wYear := 2008;
    systemTime.wMonth := 12;
    systemTime.wDay := 31;
    systemTime.wHour := 23;
    systemtime.wMinute := 59;
    systemtime.wSecond := 59;

    //Convert it to a file time
    SystemTimeToFileTime(systemTime, {var}fileTime);

    //There was a leap second 12/31/2008 11:59:60 pm
    //Add one second to our filetime to reach the leap second
    filetime.dwLowDateTime := fileTime.dwLowDateTime+10000000; //10,000,000 * 100ns = 1s

    //Convert the filetime, sitting on a leap second, to a displayable system time
    FileTimeToSystemTime(fileTime, {var}systemTime);

    //And now print the system time
    ShowMessage(DateTimeToStr(SystemTimeToDateTime(systemTime)));

Adding one second to

加一秒

12/31/2008 11:59:59pm

gives

1/1/2009 12:00:00am

rather than

而不是

1/1/2009 11:59:60pm

Q.E.D.

QED

Original poster might not like it, but god intentionally rigged it so that a year is not evenly divisible by a day. He did it just to screw up programmers.

原来的海报可能不喜欢它,但上帝故意操纵它使一年不能被一天整除。他这样做只是为了搞砸程序员。

回答by Chris Smith

Here's some more info about why that particular date was chosen.

以下是有关为什么选择该特定日期的更多信息。

The FILETIME structure records time in the form of 100-nanosecond intervals since January 1, 1601. Why was that date chosen?

The Gregorian calendar operates on a 400-year cycle, and 1601 is the first year of the cycle that was active at the time Windows NT was being designed. In other words, it was chosen to make the math come out nicely.

I actually have the email from Dave Cutler confirming this.

FILETIME 结构以 100 纳秒间隔的形式记录自 1601 年 1 月 1 日以来的时间。为什么选择那个日期?

公历以 400 年为周期运行,1601 年是在设计 Windows NT 时活跃的周期的第一年。换句话说,选择它是为了让数学表现得很好。

我实际上收到了来自 Dave Cutler 的电子邮件,证实了这一点。

回答by Chris Smith

There can be no single answer to this question without first deciding: What is the Windows FILETIME actually counting? The Microsoft docs say it counts 100 nanosecond intervals since 1601 UTC, but this is problematic.

没有首先决定这个问题就没有单一的答案:Windows FILETIME 实际上是多少?Microsoft 文档说它从 1601 UTC 开始计算 100 纳秒间隔,但这是有问题的。

No form of internationally coordinated time existed prior to the year 1960. The name UTC itself does not occur in any literature prior to 1964. The name UTC as an official designation did not exist until 1970. But it gets worse. The Royal Greenwich Observatory was not established until 1676, so even trying to interpret the FILETIME as GMT has no clear meaning, and it was only around then that pendulum clocks with accurate escapements began to give accuracies of 1 second.

1960 年之前不存在任何形式的国际协调时间。1964 年之前的任何文献中都没有出现 UTC 名称本身。作为官方名称的 UTC 名称直到 1970 年才存在。但情况变得更糟。皇家格林威治天文台直到 1676 年才成立,因此即使将 FILETIME 解释为 GMT 也没有明确的含义,直到那时,带有精确擒纵机构的摆钟才开始提供 1 秒的精度。

If FILETIME is interpreted as mean solar seconds then the number of leap seconds since 1601 is zero, for UT has no leap seconds. If FILETIME is interpreted as if there had been atomic chronometers then the number of leap seconds since 1601 is about -60 (that's negative 60 leap seconds).

如果 FILETIME 被解释为平均太阳秒,那么自 1601 年以来的闰秒数为零,因为 UT 没有闰秒。如果 FILETIME 被解释为好像有原子计时器,那么自 1601 年以来的闰秒数约为 -60(即负 60 闰秒)。

That is ancient history, what about the era since atomic chronometers? It is no better because national governments have not made the distinction between mean solar seconds and SI seconds. For a decade the ITU-R has been discussing abandoning leap seconds, but they have not achieved international consensus. Part of the reason for that can be seen in the javascript on this page(also see the delta-T link on that page for plots of the ancient history). Because national governments have not made a clear distinction, any attempt to define the count of seconds since 1972 runs the risk of being invalid according to the laws of some jurisdiction. The delegates to ITU-R are aware of this complexity, as are the folks on the POSIX committee. Until the diplomatic issues are worked out, until national governments and international standards make a clear distinction and choice between mean solar and SI seconds, there is little hope that the computer standards can follow suit.

那是古老的历史,原子计时器之后的时代呢?这并没有更好,因为各国政府没有区分平均太阳秒和 SI 秒。十年来,ITU-R 一直在讨论放弃闰秒,但并未达成国际共识。部分原因可以在此页面javascript 中看到 (另请参阅该页面上的 delta-T 链接以了解古代历史的情节)。由于各国政府尚未做出明确区分,因此根据某些司法管辖区的法律,任何自 1972 年以来定义秒数的尝试都存在无效的风险。ITU-R 的代表和 POSIX 委员会的成员都意识到了这种复杂性。在外交问题解决之前,在各国政府和国际标准在平均太阳秒和 SI 秒之间做出明确区分和选择之前,计算机标准几乎没有希望效仿。

回答by Mike Dimmick

Leap seconds are added unpredictably by the IERS. 23 seconds have been added since 1972, when UTC and leap seconds were defined. Wikipedia says "because the Earth's rotation rate is unpredictable in the long term, it is not possible to predict the need for them more than six months in advance."

IERS 不可预测地添加了闰秒。自 1972 年定义了 UTC 和闰秒以来,已添加了 23 秒。维基百科称“由于地球自转速度从长远来看是不可预测的,因此不可能提前六个月以上预测对它们的需求。”

Since you'd have to keep a history of when leap seconds were inserted, and keep updating the OS to keep a reference of when they had been inserted, and the difference is so small, it's fair not to expect a general-purpose OS to compensate for leap seconds.

由于您必须保留闰秒插入时间的历史记录,并不断更新操作系统以保留插入时间的参考,并且差异如此之小,因此不要期望通用操作系统补偿闰秒。

In addition, regular clock drift, of the simple electronic clock in your PC compared to UTC, is so much larger than the compensation required for leap seconds. If you need the kind of precision to compensate for leap seconds, you shouldn't use the highly-inaccurate PC clock.

此外,与 UTC 相比,PC 中简单电子时钟的常规时钟漂移远大于闰秒所需的补偿。如果您需要那种精度来补偿闰秒,则不应使用高度不准确的 PC 时钟。

回答by Matt Johnson-Pint

The answer to this question used to be no, but has changed to: YES, sort of, sometimes...

这个问题的答案曾经是否定的,但现在变成了:是的,有点,有时......

Per the Windows Networking team blog article:

根据Windows 网络团队博客文章

Starting in Server 2019 and the Windows 10 October [2018] update time APIs will now take into account all leap seconds the Operating System is aware of when it translates FILETIME to SystemTime.

从 Server 2019 和 Windows 10 October [2018] 更新时间 API 开始,现在将考虑操作系统在将 FILETIME 转换为 SystemTime 时知道的所有闰秒。

As there have been no leap seconds issued since the time of this feature being added, the operating system is still unaware of any leap seconds. However, when the next official leap second makes its way into the world, Windows computers that have this new feature enabled will keep track of it, and thus FILETIMEvalues will be offset by the number of leap seconds on the computer at the time they are interpreted.

由于自添加此功能以来一直没有发布闰秒,因此操作系统仍然不知道任何闰秒。但是,当下一个官方闰秒出现时,启用了此新功能的 Windows 计算机将对其进行跟踪,因此这些FILETIME值将被解释时计算机上的闰秒数所抵消.

The blog post goes on to describe:

博文继续描述:

No change is made to FILETIME. It still represents the number of 100 ns intervals since the start of the epoch. What has changed is the interpretation of that number when it is converted to SYSTEMTIME and back. Here is a list of affected APIs:

  • GetSystemTime
  • GetLocalTime
  • FileTimeToSystemTime
  • FileTimeToLocalTime
  • SystemTimeToFileTime
  • SetSystemTime
  • SetLocalTime

Previous to this release, SYSTEMTIME had valid values for wSecond between 0 and 59. SYSTEMTIME has now been updated to allow a value of 60, provided the year, month, and day represents day in which a leap second is valid.

...

In order receive the 60 second in the SYSTEMTIME structure a process must explicitly opt-in.

没有对 FILETIME 进行任何更改。它仍然代表自纪元开始以来 100 ns 间隔的数量。改变的是该数字在转换为 SYSTEMTIME 并返回时的解释。以下是受影响的 API 列表:

  • 获取系统时间
  • 获取本地时间
  • 文件时间到系统时间
  • 文件时间到本地时间
  • 系统时间到文件时间
  • 设置系统时间
  • 设置本地时间

在此版本之前,SYSTEMTIME 的 wSecond 有效值介于 0 和 59 之间。SYSTEMTIME 现在已更新为允许值为 60,前提是年、月和日表示闰秒有效的日期。

...

为了在 SYSTEMTIME 结构中接收 60 秒,进程必须明确选择加入。

Note that the opt-in applies to the behavior within the functions listed on how a FILETIMEis mapped to a SYSTEMTIME. Regardless of whether you opt-in or not, the operating system will still offset FILETIMEvalues according to the leap seconds it is aware of.

请注意,选择加入适用于列出的关于如何将 aFILETIME映射到 a的函数中的行为SYSTEMTIME。不管你是否选择加入,操作系统仍然会FILETIME根据它知道的闰秒来偏移值。

With regard to compatibility, the article states:

关于兼容性,文章指出:

Applications that rely on 3rd party frameworks should ensure their framework's implementation on Windows is also calling into the correct APIs to calculate the correct time, or else the application will have the wrong time reported.

依赖 3rd 方框架的应用程序应确保其框架在 Windows 上的实现也调用正确的 API 来计算正确的时间,否则应用程序将报告错误的时间。

And also provides a links to an earlier postwhich describes how to disable the entire feature, as follows:

并且还提供了一个之前的帖子的链接,该帖子描述了如何禁用整个功能,如下所示:

... you can revert to the prior operating system behavior and disable leap seconds across the board by adding the following registry key:

  • HKLM:\SYSTEM\CurrentControlSet\Control\LeapSecondInformation
  • Type: "REG_DWORD"
  • Name: Enabled
  • Value: 0Disables the system-wide setting
  • Value: 1Enables the system-wide setting

Next, restart your system.

...您可以通过添加以下注册表项来恢复到以前的操作系统行为并全面禁用闰秒:

  • HKLM:\SYSTEM\CurrentControlSet\Control\LeapSecondInformation
  • 类型:“REG_DWORD”
  • 名称:已启用
  • 值:0禁用系统范围的设置
  • 值:1启用系统范围的设置

接下来,重新启动系统。

回答by smoofra

According to this commentwindows is totally unaware of leap seconds. If you add 24 * 60 * 60 seconds to a FILETIME that represents 1:39:45 today, you get a FILETIME that represents 1:39:45 tomorrow, no matter what.

根据此评论,windows 完全不知道闰秒。如果您将 24 * 60 * 60 秒添加到代表今天 1:39:45 的 FILETIME,无论如何您都会得到一个代表明天 1:39:45 的 FILETIME。

回答by Brent.Longborough

A very crude summary:

一个非常粗略的总结:

UTC = (Atomic Time) + (Leap Seconds) ~~ (Mean Solar Time)

UTC =(原子时)+(闰秒)~~(平均太阳时)

The MS documentation says, specifically, "UTC", and so should include the leap seconds. As always with MS, your mileage may vary.

MS 文档特别说明了“UTC”,因此应该包括闰秒。与 MS 一样,您的里程可能会有所不同。