1601年1月1日的意义是什么?

54
这个结构体是一个64位的值,表示自1601年1月1日以来的100纳秒间隔数。
为什么要设置“自1601年”?为什么不是Unix时间1970或甚至2000年?
对于如此遥远的日期兼容性,我该怎么办? 参考:http://msdn.microsoft.com/en-us/library/aa915351

回答自己。

ANSI日期将1601年1月1日定义为第1天,并用作COBOL整数日期的起点。这个纪元是公历闰年的前400年周期的开始,该周期以2000年结束。您可以在维基百科的儒略日词条中找到相关信息。

此外:


http://stackoverflow.com/a/2866147/829571 - assylias
4个回答

61

因为1601年1月1日是时代的开始。

引用Raymond Chen的话:

为什么Win32时代是1601年1月1日?

FILETIME 结构以自 1601 年1月1日起的100纳秒间隔形式表示时间。为什么选择这个日期?

公历采用400年一个循环,而1601年是该循环在 Windows NT 设计时处于活动状态的第一年。换句话说,这个日期被选择是为了使计算更方便。

我还有Dave Cutler确认的电子邮件。

额外的闲聊

RFC4122 UUIDs也使用100ns的滴答来衡量时间,但它们从1582年10月15日开始(与FILETIME的1/1/1601不同):

Date                    Ticks               Uuid Epoch ticks
----------------------  ------------------  ------------------
1582-10-15              -5748192000000000   0                    Start of uuid epoch
1601-01-01              0                   0x00146BF33E42C000   Start of Windows epoch
1899-12-30              0x014F35A9A90CC000  0x0163A19CE74F8000   Lotus 123/Excel/Access/COM zero date
1900-01-01              0x014F373BFDE04000  0x0163A32F3C230000   SQL Server zero date
1970-01-01              0x019DB1DED53E8000  0x01B21DD213814000   Unix epoch timestamp
2000-01-01              0x01BF53EB256D4000  0x01D3BFDE63B00000
2010-01-01              0x01CA8A755C6E0000  0x01DEF6689AB0C000
2020-01-01              0x01D5C03669050000  0x01EA2C29A747C000

//FILETIME eras
1972-01-21 11:43:51 PM  0x01A0000000000000  0x01B46BF33E42C000   Start of 0x01A era
1986-04-30 11:43:13 AM  0x01B0000000000000  0x01C46BF33E42C000   Start of 0x01B era
2000-08-06 11:42:36 PM  0x01C0000000000000  0x01D46BF33E42C000   Start of 0x01C era
2014-11-14 11:41:59 AM  0x01D0000000000000  0x01E46BF33E42C000   Start of 0x01D era
2029-02-20 11:41:22 PM  0x01E0000000000000  0x01F46BF33E42C000   Start of 0x01E era
2043-05-31 11:40:44 AM  0x01F0000000000000  0x02046BF33E42C000   Start of 0x01F era

//UUID eras
1968-02-11 11:43:13 AM  0x019B940CC1BD4000  0x01B0000000000000   Start of uuid 0x01B era
1982-05-20 11:42:36 PM  0x01AB940CC1BD4000  0x01C0000000000000   Start of uuid 0x01C era
1996-08-27 11:41:59 AM  0x01BB940CC1BD4000  0x01D0000000000000   Start of uuid 0x01D era
2010-12-04 11:41:22 PM  0x01CB940CC1BD4000  0x01E0000000000000   Start of uuid 0x01E era
2025-03-13 11:40:44 AM  0x01DB940CC1BD4000  0x01F0000000000000   Start of uuid 0x01F era

额外内容

Excel使用1899年12月30日作为零日期,以便与Lotus 1-2-3完全兼容。这也是Excel认为1900年2月是闰年的原因(因为Lotus 1-2-3的开发人员这样认为)。这就是为什么在Excel中无法表示1900年3月1日之前的日期。


1
在全球论坛中,使用RFC规定的明确日期格式(例如1582年10月15日)更加合理。 - RobG
@RobG 一旦微软发明了时间机器,他们会回到过去实现你的想法。但这是个糟糕的想法;因为1600年1月1日有其优势。这就像Unix决定1970年1月1日是任何事情的有效零日期一样。 - Ian Boyd
我是在评论日期格式,而不是日期本身。是的,1970年1月1日也是一个随机日期。各种微软应用程序使用1900年1月1日(例如Excel)。 :-) - RobG
顺便提一句,大卫·卡特勒是个很好的参考,我想NT可能从他与VAX/VMS的联系中得到了启示。 - RobG
@RobG 哦,我明白你的意思了。我选择使用一个明确的日期格式,符合ISO标准。标准的好处在于有很多可以选择的。但在全球论坛中,使用“Oct”假定您理解英语及其月份名称的缩写。对于我们在加拿大的朋友,您需要说“ᐅᑐᐱ 15, 1582”。 - Ian Boyd

11

1601年1月1日是17世纪的第一天。在17世纪发明了摆钟,允许测量时间精度达到1秒1。因此(理论上)可能会在当时的现存文献中有对测量该精度的时间点的参考。

但实际上选择是任意的。必须有一个“纪元”,只要

  1. 远古的“负时间”价值很少,

  2. 周长时间距离足够远,可以推迟几代人,

任何选择都可以。

但是,如果你非常担心这个问题,请给Steve Balmer2写信。


我倾向于相信Ian Boyd的答案,因为他声称来源可靠。其中的原因是它使得公历闰年计算变得更加容易。然而,由于这种简化非常微小,而且其背后的原因也不充分,所以选择(我认为)本质上是任意的。(并不是说它是错的...)


1 - 好吧...可能没有那么准确。

2 - 或Satya Nadella。


但是这个结构覆盖了整个17、18和19世纪。以100纳秒为间隔。 - zakrzak
2
那又怎样?当你想要给过去的某个事件打上时间戳时,它就很有用了。 - Oleg V. Volkov
1
@Oleg -- 保险公司和政府是COBOL的主要用户。你可能有一个出生日期回溯到1900年的活着的公民,并且肯定会记录下1850年以前出生的已故公民的记录。建筑物通常有120年的租约,因此对现有租约的抵押贷款或保单需要记录1890年代的开始日期,任何历史记录都需要更早的日期。 - James Anderson
1
但实际上选择是任意的。确切地说,可以选择任意数量的里程碑日期。可能最初选择它的人只是想要一个在历史上足够遥远的点,使时间值很可能始终为正,并且不要选择太久以至于超过了方便的整数大小,同时还能保持合理的精度,例如毫秒,并且允许一定合理的将来时间。鉴于现代计算机的强大性能,它们应该没有问题以纳秒级准确度回溯到地球历史的开始,并向前延伸同样长的时间。 :-) - RobG

8

这是一个务实的选择。

直到1752年,英国(及其殖民地)采用了公历格里高利历法,这个现代西方日历在1582年以来已被大多数天主教欧洲国家采用。

这是一种现代日历,它包括闰年等,以保持1月1日与冬至对齐。

那么为什么不从1752年1月1日开始呢?因为基本的闰年规则“如果二位数字年份可被4整除,且四位数字世纪年份也可被4整除,则该年为闰年”,建立了一个400年的周期。第一个完整的周期始于1601年1月1日(至少在罗马)。

闰年和日期计算已经足够繁琐,而在四百年周期的中途开始还会更加复杂,所以1600年是一个相当不错的起点,只要记得在1752年之前任何日期都需要加上地理位置说明,因为此时英国的日期比罗马的晚了10天。


这是带有闰年等功能的现代日历,以保持1月1日与冬至对齐。嗯,这失败了,因为北半球的冬至通常发生在12月21日。 :-) - RobG

4
正如之前提到的,我认为普遍的答案是因为公历是以400年为一个循环周期运作的。1601年是该周期中第一个活跃的年份,在Windows NT设计时期也正是该周期的第一年。
1601年1月1日是COBOL整数日期的起点。
它也是按照ANSI日期格式计算的第1天。
如果您根据ISO8601进一步推测,可以发现在1583年之前的时间是基于朔日格里历计算的,每年有366天。也许他们只是四舍五入到下一个世纪。

普罗莱普提克格里高利历与标准格里高利历没有什么不同,除了该历法被应用于其纪元之前的日期。 - Chris Charabaruk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接