简体   繁体   English

完全分隔的日期与std :: chrono :: system_clock的毫秒数

[英]fully separated date with milliseconds from std::chrono::system_clock

My current pattern (for unix) is to call gettimeofday , cast the tv_sec field to a time_t , pass that through localtime , and combine the results with tv_usec . 我当前的模式(对于unix)是调用gettimeofday ,将tv_sec字段转换为time_t ,将其传递给localtime ,并将结果与tv_usec That gives me a full date (year, month, day, hour, minute, second, nanoseconds). 这给了我一个完整的日期(年,月,日,小时,分钟,秒,纳秒)。

I'm trying to update my code to C++11 for portability and general good practice. 我正在尝试将我的代码更新为C ++ 11,以实现可移植性和一般的良好实践。 I'm able to do the following: 我能够做到以下几点:

auto currentTime = std::chrono::system_clock::now( );
const time_t time = std::chrono::system_clock::to_time_t( currentTime );
const tm *values = localtime( &time );
// read values->tm_year, etc.

But I'm stuck on the milliseconds/nanoseconds. 但我坚持毫秒/纳秒。 For one thing, to_time_t claims that rounding is implementation defined (!) so I don't know if a final reading of 22.6 seconds should actually be 21.6, and for another I don't know how to get the number of milliseconds since the previous second (are seconds guaranteed by the standard to be regular? ie could I get the total milliseconds since the epoch and just modulo it? Even if that is OK it feels ugly). 首先, to_time_t声称舍入是实现定义的(!)所以我不知道22.6秒的最终读数是否应该实际为21.6,而对于另一个我不知道如何获得自上一次以来的毫秒数第二个(标准保证的规则是常规的吗?也就是说,我可以获得自纪元以来的总毫秒数,只是模数吗?即使这样可以感觉很难看)。

How should I get the current date from std::chrono::system_clock with milliseconds? 我怎么能用毫秒来从std::chrono::system_clock获取当前日期?

I realised that I can use from_time_t to get a "rounded" value, and check which type of rounding occurred. 我意识到我可以使用from_time_t来获得“舍入”值,并检查发生了哪种舍入。 This also doesn't rely on every second being exactly 1000 milliseconds, and works with out-of-the-box C++11: 这也不依赖于每秒正好1000毫秒,并且与开箱即用的C ++ 11一起使用:

const auto currentTime = std::chrono::system_clock::now( );
time_t time = std::chrono::system_clock::to_time_t( currentTime );
auto currentTimeRounded = std::chrono::system_clock::from_time_t( time );
if( currentTimeRounded > currentTime ) {
    -- time;
    currentTimeRounded -= std::chrono::seconds( 1 );
}
const tm *values = localtime( &time );
int year = values->tm_year + 1900;
// etc.
int milliseconds = std::chrono::duration_cast<std::chrono::duration<int,std::milli> >( currentTime - currentTimeRounded ).count( );

Using this free, open-source library you can get the local time with millisecond precision like this: 使用这个免费的开源库,您可以获得毫秒精度的本地时间,如下所示:

#include "tz.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std::chrono;
    std::cout << make_zoned(current_zone(),
                            floor<milliseconds>(system_clock::now())) << '\n';
}

This just output for me: 这只是输出给我:

2016-09-06 12:35:09.102 EDT

make_zoned is a factory function that creates a zoned_time<milliseconds> . make_zoned是一个工厂函数,用于创建zoned_time<milliseconds> The factory function deduces the desired precision for you. 工厂功能为您推断出所需的精度。 A zoned_time is a pairing of a time_zone and a local_time . zoned_timetime_zonelocal_time的配对。 You can get the local time out with: 您可以通过以下方式获取当地时间:

local_time<milliseconds> lt = zt.get_local_time();

local_time is a chrono::time_point . local_time是一个chrono::time_point You can break this down into date and time field types if you want like this: 如果你想这样,你可以将其分解为日期和时间字段类型:

auto zt = make_zoned(current_zone(), floor<milliseconds>(system_clock::now()));
auto lt = zt.get_local_time();
local_days ld = floor<days>(lt);          // local time truncated to days
year_month_day ymd{ld};                   // {year, month, day}
time_of_day<milliseconds> time{lt - ld};  // {hours, minutes, seconds, milliseconds}
// auto time = make_time(lt - ld);        // another way to create time_of_day
auto y = ymd.year();         // 2016_y
auto m = ymd.month();        // sep
auto d = ymd.day();          // 6_d
auto h = time.hours();       // 12h
auto min = time.minutes();   // 35min
auto s = time.seconds();     // 9s
auto ms = time.subseconds(); // 102ms

I read the standard like this: 我读了这样的标准:

It is implementation defined whether the value is rounder or truncated, but naturally the rounding or truncation only occurs on the most detailed part of the resulting time_t. 它是实现定义的值是圆形还是截断,但自然地,舍入或截断仅发生在结果time_t的最详细部分。 That is: the combined information you get from time_t is never more wrong than 0.5 of its granularity. 也就是说:从time_t获得的组合信息绝不会比0.5的粒度更错误。

If time_t on your system only supported seconds, you would be right that there could be 0.5 seconds systematic uncertainty (unless you find out how things were implemented). 如果你的系统上的time_t仅支持秒,那么你可能会有0.5秒的系统不确定性(除非你发现事情是如何实现的)。

tv_usec is not standard C++, but an accessor of time_t on posix. tv_usec不是标准的C ++,而是posix上time_t访问器。 To conclude, you should not expect any rounding effects bigger than half of the smallest time value difference your system supports, so certainly not more than 0.5 micro seconds. 总而言之,您不应期望任何舍入效应大于系统支持的最小时间值差异的一半,因此肯定不超过0.5微秒。

The most straight forward way is to use boost ptime . 最直接的方法是使用boost ptime It has methods such as fractional_seconds() http://www.boost.org/doc/libs/1_53_0/doc/html/date_time/posix_time.html#date_time.posix_time.ptime_class 它有方法,如fractional_seconds() http://www.boost.org/doc/libs/1_53_0/doc/html/date_time/posix_time.html#date_time.posix_time.ptime_class

For interop with std::chrono , you can convert as described here: https://stackoverflow.com/a/4918873/1149664 对于与std::chrono互操作,您可以按照此处所述进行转换: https//stackoverflow.com/a/4918873/1149664

Or, have a look at this question: How to convert std::chrono::time_point to calendar datetime string with fractional seconds? 或者,看一下这个问题: 如何将std :: chrono :: time_point转换为带有小数秒的日历日期时间字符串?

Instead of using to_time_t which rounds off you can instead do like this 而不是使用to_time_t ,你可以这样做

auto tp = std::system_clock::now();
auto s = std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch());
auto t = (time_t)(s.count());

That way you get the seconds without the round-off. 这样你就可以获得没有圆整的秒数。 It is more effective than checking difference between to_time_t and from_time_t . 它比检查to_time_tfrom_time_t之间的差异更有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std::chrono::system_clock + now() 到毫秒并返回不同的行为 - std::chrono::system_clock + now() to milliseconds and back different behavior std :: chrono :: system_clock和持续时间<double> - std::chrono::system_clock and duration<double> std::chrono::system_clock 和 C 时间 - std::chrono::system_clock and C time std::chrono::system_clock::now() 序列化 - std::chrono::system_clock::now() serialization 如何找到纪元时间戳和 std::chrono::system_clock::now 之间的时间差(以毫秒为单位) - How to find the time difference in milliseconds between an epoch timestamp and std::chrono::system_clock::now 如何从std :: chrono :: system_clock :: time_point.time_since_epoch()。count()获取std :: chrono :: system_clock :: time_point? - How to get std::chrono::system_clock::time_point from std::chrono::system_clock::time_point.time_since_epoch().count()? 为什么此代码在std :: chrono :: system_clock上不起作用? - Why isnt't this code with std::chrono::system_clock working? 为什么std :: chrono :: system_clock :: to_time_t()不是constexpr? - Why is std::chrono::system_clock::to_time_t() not constexpr? std :: chrono :: system_clock :: now()没有自动 - std::chrono::system_clock::now() without auto 可以std :: chrono :: system_clock :: now()抛出异常吗? - Can std::chrono::system_clock::now() throw an exception?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM