将C#DateTime转换为C ++ std :: chrono :: system_clock :: time_point

时间:2016-09-12 22:04:20

标签: c# c++ datetime

我需要在C ++ / CLR代码中将来自C#的DateTime转换为C ++ std::chrono::system_clock:time_point等价物。

该代码是否可以完成工作?是否有更好的方法可以做到这一点?

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;
}

1 个答案:

答案 0 :(得分:5)

我认为您的代码无效,但我没有DateTime可供测试(我不在Windows上)。 UtcNow是一个"静态"返回表示为"当前UTC时间"的电流的函数,这可能意味着:持续时间超过1970-01-01 00:00:00 UTC。我相信您的公式与参数dateTime的值无关。

我建议使用DateTime.Ticks进行广告投放,这是经过1900-01-01 00:00:00 UTC的100纳秒标记的数量,其中UTC是按比例定义的。

使用此free, open source, header-only library,您可以根据VS使用的100纳秒刻度,轻松找到DateTime纪元与system_clock纪元之间的差异:

首先将ticks定义为100纳秒单位是非常方便的:

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

然后可以写ConvertDateTime

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{1900_y/jan/1})};
}

如果您真的不喜欢使用this date library的想法,那么您可以在上面的函数中硬编码一个魔术常量,如下所示:

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

其中任何一个都会获得一个system_clock::time_point,其精度与DateTime完全相同(在VS上)。