Mendes
Mendes

Reputation: 18451

Convert C# DateTime to C++ std::chrono::system_clock::time_point

I need, in a C++/CLR code, convert a DateTime that is coming from C# to a C++ std::chrono::system_clock:time_point equivalent.

Will that code do the job os is there a better way to do it ?

std::chrono::system_clock::time_point ConvertDateTime(DateTime dateTime)
{
    Int32 unixTimestamp = (Int32)(dateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
    std::chrono::system_clock::time_point ret = std::chrono::system_clock::from_time_t(unixTimestamp );

    return ret;
}

Upvotes: 1

Views: 3217

Answers (1)

Howard Hinnant
Howard Hinnant

Reputation: 218740

I don't think your code works, though I don't have DateTime available to test (I'm not on Windows). UtcNow is a "static" function that returns the current expressed as "the current UTC time", which likely means: time duration past 1970-01-01 00:00:00 UTC. I believe your formulation is independent of the value of your parameter dateTime.

I recommend trafficking in terms of DateTime.Ticks which is the number of 100-nanosecond ticks past 0001-01-01 00:00:00 UTC where UTC is defined proleptically.

Using this free, open source, header-only library, you can easily find the difference between the DateTime epoch and the system_clock epoch in terms of the 100-nanosecond ticks that VS uses:

It is first convenient to define ticks as 100-nanoseconds units:

using ticks = std::chrono::duration<std::int64_t,
                 std::ratio_multiply<std::ratio<100>, std::nano>>;

And then ConvertDateTime can be written:

std::chrono::system_clock::time_point
ConvertDateTime(DateTime dateTime)
{
    using namespace date;
    using namespace std::chrono;
    return system_clock::time_point{ticks{dateTime.Ticks}
                - (sys_days{1970_y/jan/1} - sys_days{0001_y/jan/1})};
}

If you really dislike the idea of using this date library, then you can hard code a magic constant in the above function like so:

std::chrono::system_clock::time_point
ConvertDateTime(DateTime dateTime)
{
    using namespace std::chrono;
    return system_clock::time_point{ticks{dateTime.Ticks - 621355968000000000}};
}

Either one of these gets you a system_clock::time_point with the exact same precision as the DateTime (on VS).

Upvotes: 8

Related Questions