Using date.h, it could look like this:
#include "date/date.h"
#include <iostream>
std::chrono::system_clock::time_point
to_chrono_time_point(double d)
{
using namespace std::chrono;
using namespace date;
using ddays = duration<double, days::period>;
return sys_days{December/30/1899} + round<system_clock::duration>(ddays{d});
}
int
main()
{
using date::operator<<;
std::cout << to_chrono_time_point(42968.495833333333333333333) << '\n';
}
which outputs:
2017-08-21 11:54:00.000000
This definition assumes that your mapping from 42968.4958333333 to 21/08/2017 11:54 is correct. I see in one other place that the epoch is supposed to be 1899-12-31, not 1899-12-30. In any event, once the correct epoch is found, this is how one would perform the computation.
Ah, https://en.wikipedia.org/wiki/Leap_year_bug explains the off-by-one error. The writers of Excel purposely considered 1900 a leap year for the purpose of backwards compatibility with Lotus 1-2-3.
This output was generated on macOS where system_clock::duration
is microseconds
. The output will be slightly different on other platforms where system_clock::duration
has other units.
Aside: At this range, the precision of an IEEE 64 bit double
is coarser than nanoseconds
but finer than microseconds
(on the order of half of microsecond
).