c++excelc++20excel-dates

How to convert in modern C++ a double into a datetime


How to convert in modern C++ (C++11/14/17) a double into a date time using the date.h library, when the double has been generated while exporting an Excel worksheet as a CSV file?

For instance, the datetime appearing in Excel:

21/08/2017 11:54

has been converted by Excel into the CSV file as the double:

42968.4958333333

Thanks.

EDIT on 11/07/2019: This questions is about the use of the date.h library. The other questions pointed out as "possible duplicates" does not require the use of this library (see also the comment below by the author of the date.h library)


Solution

  • 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).