David
David

Reputation: 3804

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.

However, given the value: 41640
DateTime.FromOADate(value) returns: 2014-01-01
CAST(value AS DATETIME) returns: 2014-01-03

Is this expected behaviour because of different starting days, or is something not right?

Upvotes: 3

Views: 3371

Answers (4)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241485

OLE Automation Dates (aka "OADates") are for compatibility with COM interfaces, and used in communicating to things like Microsoft Excel through VBA. You shouldn't use them in communicating with 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.

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

As others have mentioned, the SQL Server epoch is not the same as the OLE Automation epoch. 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. SQL Server uses a fixed epoch of 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. (Though this also occurs with DateTime unless you pay attention to the .Kind property.)

Upvotes: 1

Rezoan
Rezoan

Reputation: 1787

To investigate this you have to look into the base date first,

In MSSQL print CAST(0 AS DATETIME) will output:

Jan 1 1900 12:00AM

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

12/30/1899 12:00:00 AM

So you can see there are 2 days of difference between 2 base date. That's why you are facing such problem.

Upvotes: 2

Tim Schmelter
Tim Schmelter

Reputation: 460068

This is the third day of January in 2014 in T-SQL:

SELECT CAST(41640 AS DATETIME)  

and this is the first day of January in 2014 in .NET:

DateTime dt = DateTime.FromOADate(41640)

The reason is documented in MSDN:

CAST

The "zero"-date is 1900-01-01

DateTime.FromOADate

base date, midnight, 30 December 1899

So there is a two days difference between 01/01/1900 and 12/30/1899.

Upvotes: 3

Stuart Ainsworth
Stuart Ainsworth

Reputation: 12940

SQL Server's base date is '19000101'; try CASTing 0.

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

Upvotes: 0

Related Questions