![](/img/trans.png)
[英]std::chrono::system_clock + now() to milliseconds and back different behavior
[英]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_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
我读了这样的标准:
它是实现定义的值是圆形还是截断,但自然地,舍入或截断仅发生在结果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_t
和from_time_t
之间的差异更有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.