简体   繁体   English

DateTime.FromOADate与MSSQL转换为DateTime

[英]DateTime.FromOADate vs MSSQL Cast as DateTime

I assumed that DateTime.FromOADate in .NET and casting to a DateTime in MS SQL worked the same way. 我假定.NET 中的DateTime.FromOADate和MS SQL中的强制转换为DateTime的工作方式相同。

However, given the value : 41640 但是,给定41640
DateTime.FromOADate (value) returns: 2014-01-01 DateTime.FromOADate (值)返回: 2014-01-01
CAST (value AS DATETIME ) returns: 2014-01-03 CAST (值AS DATETIME )返回: 2014-01-03

Is this expected behaviour because of different starting days, or is something not right? 是由于开始日期不同而引起的这种预期行为,还是有些不对?

This is the third day of January in 2014 in T-SQL: 这是T-SQL在2014年1月的第三天

SELECT CAST(41640 AS DATETIME)  

and this is the first day of January in 2014 in .NET: 这是2014年1月1日的第一天

DateTime dt = DateTime.FromOADate(41640)

The reason is documented in MSDN: 原因记录在MSDN中:

CAST

The "zero"-date is 1900-01-01 “零”日期是1900-01-01

DateTime.FromOADate

base date, midnight, 30 December 1899 基本日期1899年12月30日午夜

So there is a two days difference between 01/01/1900 and 12/30/1899 . 因此,在01/01/190012/30/1899之间有两天的差异。

To investigate this you have to look into the base date first, 要对此进行调查,您必须先查看基准日期,

In MSSQL print CAST(0 AS DATETIME) will output: 在MSSQL中, print CAST(0 AS DATETIME)将输出:

Jan 1 1900 12:00AM 1900年1月1日上午12:00

In C# .Net Console.WriteLine(DateTime.FromOADate(0)); 在C#.Net Console.WriteLine(DateTime.FromOADate(0)); will output: 将输出:

12/30/1899 12:00:00 AM 1899年12月30日上午12:00:00

So you can see there are 2 days of difference between 2 base date. 因此,您可以看到两个基准日期之间相差2天 That's why you are facing such problem. 这就是为什么您面临这样的问题。

OLE Automation Dates (aka "OADates") are for compatibility with COM interfaces, and used in communicating to things like Microsoft Excel through VBA. OLE自动化日期(又名“ OADates”)用于与COM接口兼容,并用于通过VBA与Microsoft Excel之类的事物进行通信。 You shouldn't use them in communicating with SQL Server. 您不应该在与SQL Server通信时使用它们。 Just return the native SQL date , datetime , or datetime2 type in your query and cast it to a DateTime in your .NET code. 只需在查询中返回本机SQL datedatetimedatetime2类型,然后将其转换为.NET代码中的DateTime

DateTime dt = (DateTime) myDataReader["FooDateTime"];

As others have mentioned, the SQL Server epoch is not the same as the OLE Automation epoch. 正如其他人提到的,SQL Server时代与OLE Automation时代不同。 OLE Automation dates also have some quirky behaviors with negative values, and also that dates before March 1st 1900 might use an epoch of 12/30/1899 or 12/31/1899 depending on which program is using it. OLE自动化日期也具有一些带有负值的古怪行为,并且1900年3月1日之前的日期可能会使用12/30/189912/31/1899的纪元,具体取决于正在使用的程序。 SQL Server uses a fixed epoch of 1/1/1900 . SQL Server使用1/1/1900的固定纪元。

And like many of Windows and .NET types, the epoch isn't fixed to UTC, so you have to know what contextual time zone information is in play also. 与许多Windows和.NET类型一样,纪元不是固定在UTC上的,因此您还必须知道正在使用哪些上下文时区信息。 (Though this also occurs with DateTime unless you pay attention to the .Kind property.) (尽管除非注意.Kind属性,否则DateTime也会发生这种情况。)

SQL Server's base date is '19000101'; SQL Server的基准日期为“ 19000101”; try CASTing 0. 尝试投放0。

According to this: http://msdn.microsoft.com/en-us/library/system.datetime.fromoadate.aspx FromOADate starts at 1899-12-30 据此: http : //msdn.microsoft.com/en-us/library/system.datetime.fromoadate.aspx FromOADate始于1899-12-30

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM