Windows FILETIME结构是否包含leap秒?
根据Microsoft文档," FILETIME"结构的计数从1601年1月1日开始(大概是那天的开始),但这是否包括leap秒?
注意:虽然花一些时间在互联网上回答一个陌生人的问题很慷慨;如果我们实际上不知道答案,那么它对我们没有太大帮助。同样,23秒也不是一件值得担心的短短的时间。许多Windows机器的时钟精确到23秒。
解决方案
一个非常粗略的总结:
UTC =(原子时间)+(飞跃秒)~~(平均太阳时间)
MS文档特别指出" UTC",因此应包括the秒。与MS一样,行驶里程可能会有所不同。
IERS会意外地增加跳跃秒数。自1972年定义UTC和leap秒以来,已经增加了23秒。维基百科说:"由于从长远来看,地球的自转速度是不可预测的,因此不可能提前六个月以上预测它们的需要。"
由于我们必须保留插入leap秒的时间的历史记录,并不断更新操作系统以保留插入leap秒的时间的参考,而且差别是如此之小,因此不要指望通用操作系统能够做到这一点。补偿leap秒。
此外,与UTC相比,PC中简单的电子时钟的常规时钟漂移远大于leap秒所需的补偿。如果我们需要某种精度来补偿leap秒,则不应使用高度不准确的PC时钟。
根据此评论,windows完全不知道leap秒。如果我们今天将24 * 60 * 60秒添加到表示1:39:45的FILETIME中,那么无论如何,明天我们将得到表示1:39:45的FILETIME。
这是有关为什么选择该特定日期的更多信息。
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.
如果不首先确定以下内容,就不会有一个单独的答案:Windows FILETIME实际上是什么?微软文档说,自1601 UTC以来,它的计数间隔为100纳秒,但这是有问题的。
在1960年之前,没有任何形式的国际协调时间。在1964年之前,UTC本身在任何文献中都没有出现过。UTC这个正式名称直到1970年才出现。皇家格林威治天文台直到1676年才建立,因此即使试图将FILETIME解释为格林尼治标准时间也没有明确的含义,只有在那时,带有精确擒纵装置的摆钟才开始具有1秒的精确度。
如果将FILETIME解释为平均太阳秒,则自1601开始的of秒数为零,因为UT没有leap秒。如果将FILETIME解释为好像已经存在原子计时器,那么自1601年以来的of秒数约为-60(即负60 leap秒)。
那是古老的历史,那自原子计时器开始的那个时代呢?这不是更好,因为各国政府没有在平均太阳秒和SI秒之间进行区分。十年来,ITU-R一直在讨论放弃leap秒,但尚未达成国际共识。部分原因可以在
此页面上的javascript(另请参见该页面上的delta-T链接以了解古代历史图)。由于各国政府尚未明确区分,因此自1972年以来定义秒数的任何尝试都可能会因某些管辖区的法律而无效。 ITU-R的代表以及POSIX委员会的成员都知道这种复杂性。在解决外交问题之前,直到各国政府和国际标准在平均太阳秒和SI秒之间做出明确区分和选择之前,几乎没有希望计算机标准能效仿这一标准。
问题不应该是" FILETIME"是否包含leap秒。
它应该是:
Do the people, functions, and libraries, who interpret a FILETIME (i.e. FileTimeToSystemTime) include leap seconds when counting the duration?
简单回答是不"。 FileTimeToSystemTime返回秒为0..59.
比较简单的答案是:"当然不会,怎么可能?"。
我的Windows 2000计算机不知道自发布以来的十年间增加了2个leap秒。它对" FILETIME"所做的任何解释都是错误的。
最后,我们可以通过直接的实验观察而不是依靠逻辑来确定张贴者问题的答案:
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)));
加上一秒钟
12/31/2008 11:59:59pm
给
1/1/2009 12:00:00am
而不是
1/1/2009 11:59:60pm
Q.E.D.
原始的海报可能不喜欢它,但上帝故意将其操纵,以使一年不会被一天均匀地整除。他这样做只是为了弄糟程序员。