SQL Server中的1/1/1753有什么意义?

544

为什么是1753年?他们对1752年有什么意见吗?我的曾曾曾曾曾曾曾祖父会感到非常冒犯。

6个回答

933

在SQL Server中,将1月1日1753年(1753-01-01)作为datetime的最小日期值的决定可以追溯到其Sybase起源

然而,这个日期本身的重要性可以归功于这个人。

Philip Stanhope, 4th Earl of Chesterfield

第四代切斯特菲尔德伯爵 Philip Stanhope 推动 新样式日历法案 通过英国议会。该法案规定英国及其殖民地采用公历。

1752 年,当英国从儒略历调整为公历时,英国历法中出现了一些缺失的天数(互联网档案馆链接)。1752 年 9 月 3 日至 1752 年 9 月 13 日被遗漏。

Kalen Delaney 解释 了这个选择的原因

那么,在失去 12 天后,你如何计算日期呢?例如,你如何计算 1492 年 10 月 12 日和 1776 年 7 月 4 日之间的天数?你包括那 12 天吗?为了避免解决这个问题,最初的 Sybase SQL Server 开发人员决定不允许在 1753 年之前使用日期。您可以使用字符字段存储早期日期,但是您无法使用任何日期时间函数来处理存储在字符字段中的早期日期。

选用1753年作为起始年似乎有点英国中心主义,因为欧洲许多天主教国家在英国实施之前已经使用了这个日历170年(最初由于教会的反对而推迟)。相反,许多国家直到1918年才改革他们的日历,俄罗斯更是如此。事实上,1917年的十月革命在格里高利历下是在11月7日开始的。

datetimeJoe's answer提到的新的datetime2数据类型都没有尝试考虑这些本地差异,只是使用格里高利历。

因此,使用更大范围的datetime2

SELECT CONVERT(VARCHAR, DATEADD(DAY,-5,CAST('1752-09-13' AS DATETIME2)),100)

返回
Sep  8 1752 12:00AM
< p > datetime2 数据类型的最后一点是,它使用proleptic Gregorian calendar向后推算到实际发明之前,因此在处理历史日期方面有限制。

这与其他软件实现形成对比,例如Java Gregorian Calendar类,默认遵循儒略历,直到1582年10月4日,然后跳转到新的公历1582年10月15日。在此日期之前,它正确地处理闰年的儒略模型;在此日期之后,它正确地处理公历模型。调用者可以通过调用setGregorianChange()来更改过渡日期。

一个相当有趣的文章讨论了一些有关采用日历的特殊情况,can be found here


85
对于这个非冒犯的曾祖父的伟大肖像,我给出一个加一的赞。此外,这个回答还有其他亮点属性。 - Smandoli
101
+1 表示希望得到既有技术含量又有历史背景的回答。在一个经常被理性思维者访问的论坛上,这是一篇令人愉悦的阅读材料。没错,我确实上过文科大学。 - Matt Hamsmith
1
关于this link:想象一下,如果有人在瑞典出生于1712年2月30日——他们永远都不会变老!: P还有,立陶宛和拉脱维亚究竟在那段时间里做了些什么呢!? - Isaac Reefman
1
说到这个人,切斯特菲尔德沙发也是以他的名字命名的。 - undefined

110

你的曾曾曾曾曾曾曾祖先应该升级到SQL Server 2008并使用DateTime2数据类型,该数据类型支持0001年01月01日至9999年12月31日范围内的日期。


41
告诉他你计划从5000年01月02日星期四开始着手处理Y10K兼容性问题,这样你就有将近5千年的时间来解决它。 - Jonathan Leffler
10
我猜有人错过了实际问题的答案:为什么是1753年? - sehe
1
是的...但是试图在一个拥有大量安装的SQL Server数据库和更多防御措施的公司中改变数据类型,比美国在冷战高峰期对抗俄罗斯洲际弹道导弹时所采取的防御措施还要困难。 - SebTHU
1
我认为这是一个更好的答案,简洁地说明解决方案而不是历史记录。你会使用历史记录还是数据类型进行查询? - abdul qayyum
Abdul,虽然这确实为“问题”提供了一个技术性的解决方法,但它绝对没有回答OP提出的问题,也没有给出任何进一步的解释。 - The Fluffy Robot
3
我喜欢在阅读StackOverflow时既能学习又能开怀大笑! - Tore Aurstad

28
1752年是英国从儒略历转换为格里高利历的一年。据我所知,由于这个转换,1752年9月份的两个星期实际上没有发生,这对于那个时间段的日期有一定的影响。
一个解释:(互联网档案馆版本

20
这是一个关于日期问题以及大型数据库管理系统如何处理这些问题的完整故事。
自公元1年至今,西方世界使用了两个主要的日历:朱利叶斯·凯撒的儒略日历和教皇格里高利十三世的公历。这两个日历只在一个规则上有所不同:闰年的确定规则。在儒略日历中,所有能被4整除的年份都是闰年。在公历中,所有能被4整除的年份都是闰年,但是能被100整除(但不能被400整除)的年份不是闰年。因此,1700年、1800年和1900年在儒略日历中是闰年,但在公历中不是;而1600年和2000年在两种日历中都是闰年。
当格里高利十三世在1582年推出他的日历时,他还规定了从1582年10月4日到10月15日之间的日子应该被跳过,也就是说,他说10月4日后的一天应该是10月15日。然而,许多国家推迟了改变日历的时间。英国及其殖民地直到1752年才从儒略日历转换到公历,因此对于他们来说,被跳过的日期是1752年9月4日至9月14日。其他国家在其他时间转换,但是1582年和1752年是我们正在讨论的DBMS的相关日期。
因此,当往前推算多年时,会出现两个问题。第一个问题是,应该按照儒略日历还是公历规则计算转闰年?第二个问题是,如何处理被跳过的日期以及何时处理?
以下是大型DBMS如何处理这些问题的方式:
1. 假装没有转换。这似乎是SQL标准要求的,尽管标准文档不太清楚:它只说日期“受使用公历自然规则的限制”——无论“自然规则”是什么。这是DB2选择的选项。当假设单一日历的规则始终适用于甚至没有人听说过该日历的时间时,技术术语是“预测性”日历正在生效。例如,我们可以说DB2遵循预测性公历。
2. 完全避免问题。Microsoft和Sybase将其最小日期值设置为1753年1月1日,安全地超过了美国改变日历的时间。这是可以辩护的,但是不时会有投诉称这两个DBMS缺乏其他DBMS具有且SQL标准要求的有用功能。
3. 选取1582年。这是Oracle所做的。Oracle用户会发现,日期算术表达式1582年10月15日减去1582年10月4日的值为1天(因为10月5日至14日不存在),而1300年2月29日是有效的(因为适用儒略闰年规则)。为什么Oracle要额外努力,而SQL标准似乎并不需要呢?答案是用户可能需要它。历史学家和天文学家使用这种混合系统代替预测性公历。(这也是Sun在为Java实现GregorianCalendar类时选择的默认选项——尽管名称中带有“Gregorian”,但GregorianCalendar是一个混合日历。)

来源 12


8

顺便提一下,在过去的某些三月/四月或十月/十一月中,Windows不再知道如何正确地将UTC转换为美国当地时间。这些日期的基于UTC的时间戳现在有点荒谬。操作系统拒绝处理美国政府最新的DST规则之前的任何时间戳会非常棘手,因此它只是错误地处理其中一些时间戳。SQL Server拒绝处理1753年之前的日期,因为需要处理大量特殊逻辑才能正确处理它们,而且不想处理错误。


3
“对于那些真正想要以巨大的方式被惊喜的人。
如果您使用的是基于Linux/Unix的系统,您可以尝试以下涉及cal命令的命令(如果单独使用,它会显示今天的日期)。”
cal 9 1752 ; cal

enter image description here

在线Linux终端,请点击这里

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