MSExcel和SQL Server中的date时间转换之间的区别

我已经发现了一些非常奇怪的事情,同时做一个工作将date时间转换为Excel中的文本,并使用它生成的数字转换为SQL Server中的date时间。

有什么奇怪的呢? 不同的结果。 两天的差别是确切的。

我在Excel中假设了今天的date 2014年5 20日dd / MM / yyyy) ,结果为41779。

日期时间输入

转换为文本

我得到的文本值,我使用SQL转换为datetime时间检索值作为date,我没有得到我想要的结果。

SQL转换为日期时间

我什至用datetime2testing,但我知道我不能将int转换为datetime2

在这里输入图像描述

我不是MS Excel专家,也不是SQL Server专家,但发生了什么? 我可以通过使用MS Excel生成的数字来删除2,但仍对我没有意义。

呵呵;)几天前,我想知道同样的事情…做一个简单的练习:

比较Select Cast(0 as DateTime) vs =DATEVALUE("1900-01-01") ,这解释了1天的差异

并通过阅读VBA的父亲Joel Spolsky的解释find一个额外的闰年

TL;博士

检查差异 – 这是第二天

=DateValue("1900-02-28")=DateValue("1900-03-01")

特别要注意DATETIME,在这里允许int的强制转换,这种差异有两个原因。

  1. Excel使用date为1的基数,SQL Server使用0,即01/01/1900转换为Excel中的数字时为1,但在SQL中它是0: SELECT CAST(CAST('19000101' AS DATETIME) AS INT); 会给0。

  2. 在excel中有一个故意的错误,以允许从Lotus那里转移错误不是故意的。 Excel认为1900年2月29日是有效的date,但1900年不是闰年。 SQL没有这个问题,所以这意味着在Excel日历中还有一天。

*( 进一步阅读表明,这可能是故意的,或被认为是无关紧要的)


附录

有一个微软支持项目 :

当Lotus 1-2-3首次发布时,该计划假定1900年是一个闰年,即使它实际上不是一个闰年。 这使得程序更容易处理闰年,并且几乎不会影响Lotus 1-2-3中的所有date计算。

当Microsoft Multiplan和Microsoft Excel发布时,他们也认为1900年是一个闰年。 这个假设允许Microsoft Multiplan和Microsoft Excel使用Lotus 1-2-3使用的相同的序列date系统,并提供与Lotus 1-2-3更好的兼容性。 1900年作为一个闰年,也使用户更容易将工作表从一个程序移动到另一个程序。

我search这个网站,发现解决scheme在这里看代码。 你需要检查60以下的任何数字,如果它不到60,不要减1,因为你还没有进入bug。 如果结束,你必须从date减去一个,因为02/29/1900的错误

DECLARE @days INT = 41779

DECLARE @StartDate DATETIME ='1899-12-31'

如果(@days> 59)SET @days = @days -1;

SELECT DATEADD(day,@ days,@ StartDate)

这是我find解决schemehttps://stackoverflow.com/a/727495/1692632