DateTime.FromOADate和MSSQL Cast as DateTime的区别

3
我原以为在.NET中,DateTime.FromOADate和在MS SQL中的casting to a DateTime的工作方式相同。然而,当给定: 41640时,DateTime.FromOADate(value)返回:2014-01-01,而CAST(value AS DATETIME)返回:2014-01-03。这是因为起始日期不同导致的预期行为,还是有什么问题?

感谢您先到这里来;我得到了完全相同的数字。 - user1499731
4个回答

3

这是2014年1月的第三天在T-SQL中:

SELECT CAST(41640 AS DATETIME)  

这是2014年1月的第一天在.NET中:

DateTime dt = DateTime.FromOADate(41640)

原因在MSDN中有详细说明:CAST。 "零"日期是1900年1月1日DateTime.FromOADate 基准日期是1899年12月30日的午夜。所以,01/01/190012/30/1899之间相差两天。

2
要调查这个问题,首先需要查看基准日期。在MSSQL中,print CAST(0 AS DATETIME)将输出:

Jan 1 1900 12:00AM

在C# .Net中,Console.WriteLine(DateTime.FromOADate(0));将输出:

12/30/1899 12:00:00 AM

因此,您可以看到两个基准日期之间相差2天。这就是为什么您会遇到这样的问题。

1
OLE自动化日期(也称为“OADates”)用于与COM接口兼容,并用于通过VBA与Microsoft Excel等事物进行通信。您不应在与SQL Server通信时使用它们。只需在查询中返回本机SQL datedatetimedatetime2类型,并将其转换为DateTime在您的.NET代码中。
DateTime dt = (DateTime) myDataReader["FooDateTime"];

正如其他人所提到的,SQL Server的纪元与OLE Automation的纪元不同。OLE Automation日期也具有一些奇怪的行为,如负值以及在1900年3月1日之前的日期可能会使用12/30/189912/31/1899的纪元,这取决于使用它的程序。SQL Server使用固定的纪元1/1/1900
像Windows和.NET类型中的许多类型一样,纪元并没有固定为UTC,因此您还必须知道当前上下文时区信息。 (尽管这也发生在DateTime中,除非您关注.Kind属性。)

0

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