我当前的模式(针对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
获取当前日期毫秒?
答案 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_time
是time_zone
和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
答案 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_t
和from_time_t
之间的差异更有效。