我认为SQL和.NET的日期数据类型之间的差异源于SQL Server的datetime数据类型,它的最小值、最大值和精度比.NET的DateTime数据类型早得多。随着.NET的出现,团队决定DateTime数据类型应该有一个更自然的最小值,而01/01/0001似乎是一个相当合理的选择,从编程语言的角度而言,而不是数据库的角度,这个值更自然。顺便说一下,在SQL Server 2008中,有许多基于日期的新数据类型(
Date,
Time,
DateTime2,
DateTimeOffset),实际上提供了增加的范围和精度,并且与.NET中的DateTime数据类型密切匹配。例如,DateTime2数据类型的日期范围为0001-01-01到9999-12-31。SQL Server的标准"datetime"数据类型始终具有01/01/1753的最小值(事实上仍然如此!)。我必须承认,我也很好奇这个值的意义,所以进行了一些挖掘...我发现如下内容:
公元1年至今,西方世界使用了两种主要的日历:朱利叶斯·凯撒的儒略日历和教皇格里高利十三世的公历。这两种日历只有一个规则不同:闰年的确定方法。在儒略日历中,所有能被4整除的年份都是闰年。在公历中,所有能被4整除的年份都是闰年,但是能被100整除而不能被400整除的年份不是闰年。因此,1700年、1800年和1900年是儒略日历中的闰年,但不是公历中的闰年,而1600年和2000年都是两种日历中的闰年。
当格里高利十三世在1582年引入他的日历时,他还指示应跳过10月4日至10月15日之间的日期——也就是说,他说10月4日的下一天应该是10月15日。然而,许多国家推迟了转换时间。英国及其殖民地直到1752年才从儒略日历转换为公历,因此对于他们来说,跳过的日期是1752年9月4日至9月14日。其他国家在不同时期转换,但对于我们正在讨论的数据库管理系统来说,1582年和1752年是相关的日期。
因此,当向前回溯多年时,会出现两个日期算术问题。第一个是,应根据儒略日历还是公历规则计算转换之前的闰年?第二个问题是,如何处理跳过的日期以及何时处理?
这就是大型八大数据库管理系统(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类时选择的默认选项——尽管名称为GregorianCalendar,但它是一种混合日历。)
这句引言摘自以下链接:
SQL性能调优:SQL中的日期