I'm writing a Windows DLL in mostly std C++ (VS2010), which does not use MFC/ATL.
A parent module does use MFC and passes a COleDateTime.m_dt
to my DLL, which arrives as a double
. I believe this is an OLE Automation Date, also known as OADate.
I want to convert this to any type of standard struct (tm...) that has days, hours, etc without pulling MFC, OLE, etc into my DLL.
This has been asked before (Convert Date/Time (as Double) to struct* tm in C++) however, the answer is always using VariantTimeToSystemTime()
, which misses the point of that question - not using MFC / OLE, etc.
VariantTimeToSystemTime's requirements are:
Header - OleAuto.h
Library - OleAut32.lib
DLL - OleAut32.dll
My DLL has basically no dependencies at the moment, so I would prefer not to pull OleAut32.dll in for this one conversion.
The best thing I've found so far has been this C# mono code, which I may convert to C++.
I have 2 solutions, the first is working with a function that implements
gmtime_r
so that this solution will don't use any standard functions. The second solution is using the standard functiongmtime_r
.1. First solution: Own implementation of gmtime_r (
01-Jan-1601
to31-Dec-9999
):It will work for dates between
01-Jan-1601
and31-Dec-9999
. I've implemented afromOADate
function which uses theSecondsSinceEpochToDateTime
function from this answer on SO wich converts seconds before or after01-Jan-1970
to atm
structure but works only from01-Jan-1601
on.I changed the function from that answer to work also with 32 bit by adding one
ULL
suffix. That requires that thelong long
types are 64 bit wide, if that's not the case this solution will not work.If you need dates before year 1601 you could change the
SecondsSinceEpochToDateTime
as it is well documentated.To test different values this online conversion is very nice which also supports unix timestamp and the OADate type.
Full working code and example on ideone:
2. Second solution: Using gmtime_r (
01-Jan-1970
to19-Jan-2038
/31-Dec-9999
(32/64 bit)):As already said this solution has not that wide range as the variant from above but just uses a standard function (full working example at ideone):