我想知道为什么SqlDateTime.MinValue与DateTime.MinValue不同?
Answers:
我认为SQL和.NET的Date数据类型之间的差异源于以下事实: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的标准“日期时间”数据类型始终具有最小值01/01/1753(实际上确实具有!)。我必须承认,我也对此价值的意义感到好奇,因此进行了一些挖掘。.我发现如下:
在公元1日到今天之间,西方世界实际上使用了两个主要日历:朱利叶斯·凯撒的儒略历和教皇格里高利十三世的公历。两个日历的区别仅在于一条规则:确定:年是什么的规则。在儒略历中,所有可以被四整除的年份是leap年。在公历中,所有可被四整除的年份都是are年,但不可被100整除(但不能被400整除)的年份不是leap年。因此,年份1700、1800和1900是儒略历中的leap年,而不是公历,而1600和2000是两个历法中的leap年。
当教皇格里高利十三世在1582年提出日历时,他还指示应该跳过1582年10月4日至1582年10月15日之间的日期,也就是说,他说10月4日之后的第二天应该是10月15日。许多国家但是,延迟了转换。英格兰和她的殖民地直到1752年才从朱利安转向格里高利安,因此对他们来说,跳过的日期是在1752年9月4日至9月14日之间。其他国家/地区则在其他时间转换,但1582和1752年是该日期的相关日期。我们正在讨论的DBMS。
因此,当日期算术回溯到很多年时会出现两个问题。第一个是,应该根据朱利安规则或格里高利规则计算转换之前的leap年吗?第二个问题是,何时以及如何处理跳过的日期?
八大数据库管理系统就是这样处理以下问题的:
假装没有开关。尽管标准文档尚不清楚,但这似乎是SQL标准的要求:它只是说日期“受到使用公历的自然规则的约束”,无论“自然规则”是什么。这是DB2选择的选项。如果假装单个日历的规则即使在没人听过日历的情况下也始终适用,则技术术语是“多用”日历有效。因此,例如,我们可以说DB2遵循一个多事的公历。
完全避免该问题。 Microsoft和Sybase将其最小日期值设置为1753年1月1日,这已经安全地超过了美国转换日历的时间。这是可以辩护的,但有时会抱怨说这两个DBMS缺乏其他DBMS所具有的有用功能以及SQL Standard所要求的。
选择1582。这就是Oracle所做的。Oracle用户会发现日期算术表达式1582年10月15日减去1582年10月4日得出的值是1天(因为10月5日至14日不存在),并且日期1300年2月29日有效(因为朱利安飞跃式-年份规则适用)。当SQL标准似乎不需要Oracle时,为什么会给它带来更多麻烦呢?答案是用户可能需要它。历史学家和天文学家使用这种混合系统代替了多事的格里高利历。(这也是Sun在为Java实现GregorianCalendar类时选择的默认选项,尽管名称为GregorianCalendar,但它是一个混合日历。)
以上引用来自以下链接:
由于在SQL Server中,可以存储在datetime字段(1753/1/1)中的最小日期不等于DateTime .NET数据类型的最小值(0001/1/1)。
1753年是公历(英国)的第一个采用者。至于为什么要在01/01/0001上选择它,这无疑是从1990年代SQL Server成为Sybase以来的遗产。他们必须尽早做出设计决定,并且Microsoft SQL团队还没有找到更改它的理由。
由于.NET爆炸式增长并将其集成到Sql Server中,因此现在有了DateTime2对象以实现兼容性。如果您是NHibernate用户,则可以在类型映射中提供此类型以避免DateTime.Min
出现问题
.NET Dates可以满足除公历之外的其他日历:
朱利安·卡伦达(JulianCalendar)实际发生日期 DateTime.MinValue
SQL对DateTime使用不同的内部表示形式。