MSExcel和SQL Server中的date时间转换之间的区别
我已经发现了一些非常奇怪的事情,同时做一个工作将date时间转换为Excel中的文本,并使用它生成的数字转换为SQL Server中的date时间。
有什么奇怪的呢? 不同的结果。 两天的差别是确切的。
我在Excel中假设了今天的date( 2014年5 月 20日dd / MM / yyyy) ,结果为41779。
我得到的文本值,我使用SQL转换为datetime
时间检索值作为date,我没有得到我想要的结果。
我什至用datetime2
testing,但我知道我不能将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的强制转换,这种差异有两个原因。
-
Excel使用date为1的基数,SQL Server使用0,即
01/01/1900
转换为Excel中的数字时为1,但在SQL中它是0:SELECT CAST(CAST('19000101' AS DATETIME) AS INT);
会给0。 -
在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