#include <iostream>
#include <ctime>

struct tm* fromOADate(struct tm* p_Tm, double p_OADate)
{
   static const int64_t OA_UnixTimestamp = -2209161600; /* 30-Dec-1899 */

   if (!(   25569 <= p_OADate              /* 01-Jan-1970 00:00:00 */
         &&          p_OADate <= 2958465)) /* 31-Dec-9999 00:00:00 */
   {
      throw std::string("OADate must be between 25569 and 2958465!");
   }

   time_t OADatePassedDays = p_OADate;
   double OADateDayTime    = p_OADate - OADatePassedDays;
   time_t OADateSeconds    = OA_UnixTimestamp
                           + OADatePassedDays * 24LL * 3600LL
                           + OADateDayTime * 24.0 * 3600.0;

   /* date was greater than 19-Jan-2038 and build is 32 bit */
   if (0 > OADateSeconds)
   {
      throw std::string("OADate must be between 25569 and 50424.134803241!");
   }

   return gmtime_r(&OADateSeconds, p_Tm);
}


int main()
{
   struct tm timeVal;

   std::cout << asctime(fromOADate(&timeVal, 25569));           /* 01-Jan-1970 00:00:00 */
   std::cout << asctime(fromOADate(&timeVal, 50424.134803241)); /* 19-Jan-2038 03:14:07 */

   return 0;
}