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

时间:2013-06-30 03:16:07

标签: c++ c++11 time chrono

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

我正在尝试将我的代码更新为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获取当前日期毫秒?

4 个答案:

答案 0 :(得分:2)

我意识到我可以使用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( );

答案 1 :(得分:2)

使用此free, open-source library,您可以获得毫秒精度的本地时间,如下所示:

#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_timechrono::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

答案 2 :(得分:0)

我读了这样的标准:

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

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

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

最直接的方法是使用提升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

或者,看看这个问题:How to convert std::chrono::time_point to calendar datetime string with fractional seconds?

答案 3 :(得分:0)

而不是使用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之间的差异更有效。