繁体   English   中英

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

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

我当前的模式(对于unix)是调用gettimeofday ,将tv_sec字段转换为time_t ,将其传递给localtime ,并将结果与tv_usec 这给了我一个完整的日期(年,月,日,小时,分钟,秒,纳秒)。

我正在尝试将我的代码更新为C ++ 11,以实现可移植性和一般的良好实践。 我能够做到以下几点:

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.

但我坚持毫秒/纳秒。 首先, to_time_t声称舍入是实现定义的(!)所以我不知道22.6秒的最终读数是否应该实际为21.6,而对于另一个我不知道如何获得自上一次以来的毫秒数第二个(标准保证的规则是常规的吗?也就是说,我可以获得自纪元以来的总毫秒数,只是模数吗?即使这样可以感觉很难看)。

我怎么能用毫秒来从std::chrono::system_clock获取当前日期?

我意识到我可以使用from_time_t来获得“舍入”值,并检查发生了哪种舍入。 这也不依赖于每秒正好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( );

使用这个免费的开源库,您可以获得毫秒精度的本地时间,如下所示:

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

这只是输出给我:

2016-09-06 12:35:09.102 EDT

make_zoned是一个工厂函数,用于创建zoned_time<milliseconds> 工厂功能为您推断出所需的精度。 zoned_timetime_zonelocal_time的配对。 您可以通过以下方式获取当地时间:

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

local_time是一个chrono::time_point 如果你想这样,你可以将其分解为日期和时间字段类型:

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

我读了这样的标准:

它是实现定义的值是圆形还是截断,但自然地,舍入或截断仅发生在结果time_t的最详细部分。 也就是说:从time_t获得的组合信息绝不会比0.5的粒度更错误。

如果你的系统上的time_t仅支持秒,那么你可能会有0.5秒的系统不确定性(除非你发现事情是如何实现的)。

tv_usec不是标准的C ++,而是posix上time_t访问器。 总而言之,您不应期望任何舍入效应大于系统支持的最小时间值差异的一半,因此肯定不超过0.5微秒。

最直接的方法是使用boost ptime 它有方法,如fractional_seconds() http://www.boost.org/doc/libs/1_53_0/doc/html/date_time/posix_time.html#date_time.posix_time.ptime_class

对于与std::chrono互操作,您可以按照此处所述进行转换: https//stackoverflow.com/a/4918873/1149664

或者,看一下这个问题: 如何将std :: chrono :: time_point转换为带有小数秒的日历日期时间字符串?

而不是使用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());

这样你就可以获得没有圆整的秒数。 它比检查to_time_tfrom_time_t之间的差异更有效。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM