C ++如何将std :: chrono :: time_point转换为long和back [英] C++ How do I convert a std::chrono::time_point to long and 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_cast
s 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
的路上,将 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屋!