C ++如何将std :: chrono :: time_point转换为long和back [英] C++ How do I convert a std::chrono::time_point to long and back

查看:1227
本文介绍了C ++如何将std :: chrono :: time_point转换为long和back的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将 std :: chrono :: time_point 转换为类型(整数64位)。我开始使用 std :: chrono ...

I need to convert std::chrono::time_point to and from a long type (integer 64 bits). I´m starting working with std::chrono...

这是我的代码:

int main ()
{
     std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();

    auto epoch = now.time_since_epoch();
    auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);
    long duration = value.count();


    std::chrono::duration<long> dur(duration);

    std::chrono::time_point<std::chrono::system_clock> dt(dur);

    if (dt != now)
        std::cout << "Failure." << std::endl;
    else
        std::cout << "Success." << std::endl;
}

此代码编译,但不显示成功。为什么dt不同于现在结束?该代码缺少什么?

This code compiles, but does not show success. Why is dt different than now at the end ? What is missing on that code ?

感谢您的帮助。

推荐答案

std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();

这是 auto

auto now = std::chrono::system_clock::now();

由于您想以 millisecond ,可以在 time_point 中进行隐藏:

Since you want to traffic at millisecond precision, it would be good to go ahead and covert to it in the time_point:

auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);

now_ms time_point ,基于 system_clock ,但精度为 milliseconds 您的 system_clock 有。

now_ms is a time_point, based on system_clock, but with the precision of milliseconds instead of whatever precision your system_clock has.

auto epoch = now_ms.time_since_epoch();

epoch 现在有 std :: chrono :: milliseconds 。下面的语句基本上是一个无操作(只是做一个副本,不进行转换):

epoch now has type std::chrono::milliseconds. And this next statement becomes essentially a no-op (simply makes a copy and does not make a conversion):

auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);

这里:

long duration = value.count();

在您的和我的代码中, duration system_clock 的时期开始保持毫秒的数量。

In both your and my code, duration holds the number of milliseconds since the epoch of system_clock.

This:

std::chrono::duration<long> dur(duration);

创建持续时间 c $ c> long ,精度为。这有效地 reinterpret_cast value 中保存 milliseconds code> seconds 。这是一个逻辑错误。正确的代码如下:

Creates a duration represented with a long, and a precision of seconds. This effectively reinterpret_casts the milliseconds held in value to seconds. It is a logic error. The correct code would look like:

std::chrono::milliseconds dur(duration);

此行:

std::chrono::time_point<std::chrono::system_clock> dt(dur);

基于<$ c创建 time_point $ c> system_clock ,具有保持 system_clock 的本机精度(通常比毫秒更精确)的精度的能力。然而,运行时间值将正确地反映出保持整数毫秒(假设我对 dur 的类型进行校正)。

creates a time_point based on system_clock, with the capability of holding a precision to the system_clock's native precision (typically finer than milliseconds). However the run-time value will correctly reflect that an integral number of milliseconds are held (assuming my correction on the type of dur).

即使有修正,这个测试也会(几乎总是)失败:

Even with the correction, this test will (nearly always) fail though:

if (dt != now)

因为 dt milliseconds ,但现在拥有比毫秒更小的整数刻度(例如微秒 nanoseconds )。因此,只有在 system_clock :: now()返回整数个毫秒的罕见机会才会通过测试。

Because dt holds an integral number of milliseconds, but now holds an integral number of ticks finer than a millisecond (e.g. microseconds or nanoseconds). Thus only on the rare chance that system_clock::now() returned an integral number of milliseconds would the test pass.

但您可以改为:

if (dt != now_ms)

现在,您可以可靠地获得预期的结果。

And you will now get your expected result reliably.

整合在一起:

int main ()
{
    auto now = std::chrono::system_clock::now();
    auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);

    auto value = now_ms.time_since_epoch();
    long duration = value.count();

    std::chrono::milliseconds dur(duration);

    std::chrono::time_point<std::chrono::system_clock> dt(dur);

    if (dt != now_ms)
        std::cout << "Failure." << std::endl;
    else
        std::cout << "Success." << std::endl;
}



个人我发现所有 std :: chrono 过多冗长,所以我将其编码为:

Personally I find all the std::chrono overly verbose and so I would code it as:

int main ()
{
    using namespace std::chrono;
    auto now = system_clock::now();
    auto now_ms = time_point_cast<milliseconds>(now);

    auto value = now_ms.time_since_epoch();
    long duration = value.count();

    milliseconds dur(duration);

    time_point<system_clock> dt(dur);

    if (dt != now_ms)
        std::cout << "Failure." << std::endl;
    else
        std::cout << "Success." << std::endl;
}

这将可靠地输出:

Success.



最后,我建议删除临时表以减少 time_point 和整数类型为最小。这些转换是危险的,所以你编写操作裸整数类型的代码越少越好:

Finally, I recommend eliminating temporaries to reduce the code converting between time_point and integral type to a minimum. These conversions are dangerous, and so the less code you write manipulating the bare integral type the better:

int main ()
{
    using namespace std::chrono;
    // Get current time with precision of milliseconds
    auto now = time_point_cast<milliseconds>(system_clock::now());
    // sys_milliseconds has type time_point<system_clock, milliseconds>
    using sys_milliseconds = decltype(now);
    // Convert time_point to signed integral type
    auto integral_duration = now.time_since_epoch().count();
    // Convert signed integral type to time_point
    sys_milliseconds dt{milliseconds{integral_duration}};
    // test
    if (dt != now)
        std::cout << "Failure." << std::endl;
    else
        std::cout << "Success." << std::endl;
}

上述主要危险是在返回到 time_point 的路上,将 complete_duration 作为 milliseconds 减轻这种风险的一个可能的方法是写:

The main danger above is not interpreting integral_duration as milliseconds on the way back to a time_point. One possible way to mitigate that risk is to write:

    sys_milliseconds dt{sys_milliseconds::duration{integral_duration}};

这样可以降低风险,只需确保使用 sys_milliseconds 在出口,并在两个地方在回来的路上。

This reduces risk down to just making sure you use sys_milliseconds on the way out, and in the two places on the way back in.

还有一个例子:假设你想要转换为和从一个积分它代表任何持续时间 system_clock 支持(微秒,10 th 微秒或纳秒)。然后你不必担心如上所述指定毫秒。代码简化为:

And one more example: Let's say you want to convert to and from an integral which represents whatever duration system_clock supports (microseconds, 10th of microseconds or nanoseconds). Then you don't have to worry about specifying milliseconds as above. The code simplifies to:

int main ()
{
    using namespace std::chrono;
    // Get current time with native precision
    auto now = system_clock::now();
    // Convert time_point to signed integral type
    auto integral_duration = now.time_since_epoch().count();
    // Convert signed integral type to time_point
    system_clock::time_point dt{system_clock::duration{integral_duration}};
    // test
    if (dt != now)
        std::cout << "Failure." << std::endl;
    else
        std::cout << "Success." << std::endl;
}

这是可行的,但如果你运行一半的转换一个平台和另一个平台上的另一半(从集成中),你运行的风险是 system_clock :: duration 将有两种转换的不同精度。

This works, but if you run half the conversion (out to integral) on one platform and the other half (in from integral) on another platform, you run the risk that system_clock::duration will have different precisions for the two conversions.

这篇关于C ++如何将std :: chrono :: time_point转换为long和back的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆