根据Microsoft文档,FILETIME
structure从1601年1月1日开始计算(可能是当天的开始),但这是否包括闰秒?
答案 0 :(得分:14)
问题不应该是FILETIME
包含闰秒。
应该是:
解释
FILETIME
(即FileTimeToSystemTime
)的人,函数和库在计算持续时间时是否包含闰秒?
简单的答案是“no”。 FileTimeToSystemTime
以0..59
的形式返回秒数。
更简单的答案是:“当然不是,怎么可能?”。
我的Windows 2000机器不知道自发布以来十年内增加了2个闰秒。它对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。
原始海报可能不喜欢它,但上帝故意操纵它,以便一年不能被一天整除。他这样做只是为了搞砸程序员。
答案 1 :(得分:9)
Here提供了有关为何选择特定日期的更多信息。
FILETIME结构记录时间 100纳秒间隔的形式 从1601年1月1日起。为什么会这样 选择日期?
格里高利历是以a为准 400年周期,1601是第一个 活跃的周期年份 Windows NT的时间 设计的。换句话说,它是 选择让数学出来 很好。
我实际上收到了戴夫的电子邮件 卡特勒证实了这一点。
答案 2 :(得分:8)
如果没有先决定,这个问题就没有单一答案:Windows FILETIME实际上是在计算什么?微软的文档称自1601年UTC以来它的间隔为100纳秒,但这是有问题的。
在1960年以前,没有任何形式的国际协调时间。在1964年以前的任何文献中都没有出现UTC这个名称。作为官方名称的UTC名称直到1970年才存在。但它变得更糟。皇家格林威治天文台直到1676年才建立起来,所以即使试图将FILETIME解释为格林威治标准时间也没有明确的含义,只有在那时,精确擒纵机构的摆钟开始给出1秒的精度。
如果FILETIME被解释为平均太阳秒,则自1601以来的闰秒数为零,因为UT没有闰秒。如果FILETIME被解释为有原子计时器那么自1601以来的闰秒数约为-60(这是负60闰秒)。
那是古代历史,那么自原子计时器以来的时代呢?这并不好,因为各国政府没有区分平均太阳秒和SI秒。十年来,ITU-R一直在讨论放弃闰秒,但尚未达成国际共识。部分原因可以从中看到 javascript on this page(另请参阅该页面上的delta-T链接以了解古代历史的情节)。由于各国政府尚未明确区分,因此根据某些司法管辖区的法律,任何定义自1972年以来的秒数的企图都存在无效的风险。 ITU-R的代表也意识到了这种复杂性,POSIX委员会的成员也是如此。在制定外交问题之前,在国家政府和国际标准在平均太阳能和SI秒之间作出明确的区分和选择之前,计算机标准几乎没有希望效仿。
答案 3 :(得分:2)
IERS不可预测地添加了闰秒。自1972年以来,已经定义了23秒,当时定义了UTC和闰秒。维基百科说“因为从长远来看地球的轮换速度是不可预测的,所以不可能提前六个月预测它们的需要。”
由于您必须保留插入闰秒的历史记录,并不断更新操作系统以保留插入时间的参考,并且差异非常小,所以不要指望一般性 - 用于补偿闰秒的操作系统。
此外,与UTC相比,PC中简单电子钟的常规时钟漂移远大于闰秒所需的补偿。如果您需要这种精度来补偿闰秒,则不应使用高度不准确的PC时钟。
答案 4 :(得分:1)
此问题的答案曾经是“否”,但已更改为:是,有时, ...
每the Windows Networking team blog article:
从Server 2019和Windows 10 October [2018]更新时间开始,API现在将考虑操作系统在将FILETIME转换为SystemTime时意识到的所有leap秒。
由于自添加此功能以来没有发布过leap秒,因此操作系统仍然不知道任何any秒。但是,当下一个正式的leap秒进入世界时,启用了此新功能的Windows计算机将对其进行跟踪,因此FILETIME
的值将被计算机上的leap秒数所抵消。解释它们的时间。
博客文章继续描述:
未更改FILETIME。自历元开始以来,它仍然代表100 ns的间隔数。改变的是该数字在转换为SYSTEMTIME并返回时的解释。以下是受影响的API的列表:
- GetSystemTime
- GetLocalTime
- FileTimeToSystemTime
- FileTimeToLocalTime
- SystemTimeToFileTime
- SetSystemTime
- SetLocalTime
在此版本之前,SYSTEMTIME的wSecond的有效值介于0到59之间。现在,SYSTEMTIME已更新为允许值60,条件是年,月和日表示a秒的有效日期。 / p>
...
为了在SYSTEMTIME结构中接收60秒,必须显式选择进程。
请注意,选择加入适用于在如何将FILETIME
映射到SYSTEMTIME
上列出的功能内的行为。无论您是否选择加入,操作系统仍然会根据其知道的the秒来偏移FILETIME
的值。
关于兼容性,文章指出:
依赖于第三方框架的应用程序应确保其框架在Windows上的实现也调用正确的API以计算正确的时间,否则应用程序将报告错误的时间。
并且还提供了指向an earlier post的链接,该链接描述了如何禁用整个功能,如下所示:
...您可以恢复到以前的操作系统行为,并通过添加以下注册表项全面禁用leap秒:
HKLM:\SYSTEM\CurrentControlSet\Control\LeapSecondInformation
- 类型:“ REG_DWORD”
- 名称:已启用
- 值:
0
禁用系统范围的设置- 值:
1
启用系统范围的设置下一步,重新启动系统。
答案 5 :(得分:0)
非常粗略的总结:
UTC =(原子时间)+(闰秒)~~(平均太阳时)
MS文档特别指出“UTC”,因此应包括闰秒。与MS一样,您的里程可能会有所不同。
答案 6 :(得分:0)
根据这个comment窗口完全没有意识到闰秒。如果你向今天1:39:45的FILETIME添加24 * 60 * 60秒,你将获得一个代表明天1:39:45的FILETIME,无论如何。