3

我当前的模式(对于 unix)是调用gettimeofday,将tv_sec字段转换为 a 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我应该如何以毫秒为单位获取当前日期?

4

4 回答 4

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( );
于 2013-06-30T21:42:54.003 回答
2

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

#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>. 工厂函数为您推断出所需的精度。Azoned_time是 atime_zone和 a的配对local_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
于 2016-09-06T16:52:30.553 回答
1

而不是使用to_time_twhich rounds off 你可以这样做

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_t它比检查和之间的差异更有效from_time_t

于 2016-09-06T08:00:37.403 回答
0

我读了这样的标准:

值是舍入还是截断由实现定义,但自然舍入或截断只发生在结果 time_t 的最详细部分。也就是说:从 time_t 获得的组合信息永远不会超过其粒度的 0.5。

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

tv_usec不是标准 C++,而是time_ton posix 的访问器。总而言之,您不应期望任何舍入效果大于系统支持的最小时间值差的一半,因此肯定不超过 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

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

于 2013-06-30T11:13:30.777 回答