用chrono存储毫秒的便携方式

时间:2016-09-29 06:42:00

标签: c++ date c++11 c++14 chrono

我的代码如下 -

int main(){
    ....

    auto time = std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);

    ....
    return 0;
}

此处的变量time使用l方法将输出作为typeid().name()输出,但可以安全地假设如果我用long类型替换auto,则变量仍然是在不同的机器上存储正确的毫秒数?

我需要它,因为我不能将auto指定为类成员中的类型,因为它们不是constexpr或静态的,它可能是可能的。我的目的是将数据发送到我可以var d = new Date(time)的浏览器,并显示正确的时间。通信部分已通过json格式计算出来,我只是坚持如何在不同系统中正确存储它。

3 个答案:

答案 0 :(得分:5)

  

[...]可以安全地假设如果我用long类型替换auto,变量仍会在不同的机器上存储正确的毫秒数吗?

不,您需要至少45位的有符号整数类型,long不能保证。{1}}。您应该使用std::chrono::milliseconds::rep

using namespace std::chrono;
milliseconds::rep time = 
    duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();

另请注意,就可移植性而言,system_clock的纪元不能保证是标准的1970年1月1日00:00:00 UTC(即使大部分时间都是这种情况)。

答案 1 :(得分:3)

您的方法可行且可移植,但我建议使用更简单的方法来计算毫秒数:

std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()

这肯定会有效,因为.count()返回一个std :: chrono :: milliseconds :: rep,它是“至少45位的有符号整数类型”并且应该长整齐。

注意:不能保证system_clock具有毫秒级的分辨率。但无论如何,你会得到毫秒的结果。

附注:我可以很好地利用using namespace std::chrono;,因为这会显着缩短代码长度。

答案 2 :(得分:3)

现有的两个答案都很好。但只要您使用C ++,我建议您创建类型为

的数据成员
std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>

我知道这是一个丑陋的嘴巴,但它可以很容易变得更漂亮。它也很容易使用。它有助于防止C ++代码中的运行时错误。

让它更漂亮

我推荐这个模板使用:

template <class Duration>
    using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;

现在,您可以使您的数据成员具有类型:

sys_time<std::chrono::milliseconds> time_;

这更具可读性,完全保留了存储时间点的语义,而不是任意数字,或葡萄柚中卡路里的数量。

类型安全

让我们说,从现在起六个月后,您将重新访问此代码并写下:

auto z = x.time_ + y.time_;

如果您之前已决定提供time_类型std::int64_tstd::chrono::milliseconds::rep,则上述新代码行会编译并产生运行时错误。及时添加两个点是没有意义的。明天+今天是荒谬的。

但是,如果您之前已决定按照我的建议提供time_类型sys_time<milliseconds>,那么创建z 的上述代码行将无法编译。类型系统在编译时检测到逻辑错误 。现在你被迫立即重新访问你的逻辑,并发现你为什么试图添加两个时间点。也许它只是一个类型o并且你打算减去它们(这是合乎逻辑的,编译并产生类型为duration的{​​{1}})。

易于使用

您可以使用以下简单语法将milliseconds分配给now()数据成员:

time_

现在using namespace std::chrono; time_ = time_point_cast<milliseconds>(system_clock::now()); 只是另一个基于time_的{​​{1}},但精度为system_clock。要输出到json,您可以使用以下内容获取内部有符号整数值:

time_point

要从json解析,你可以:

milliseconds