2016-09-29 72 views
1

移植的方式我有一个代码如下 -存储毫秒计时

int main(){ 
    .... 

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

    .... 
    return 0; 
} 

变量time这里给出的l输出与typeid().name()方法,但它是安全的假设,如果我更换自动带long类型,变量仍然会在不同的机器上存储正确的毫秒数量?

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

回答

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_; 

这是更可读,和它确切地说保留您存储一个时间点的语义,而不是一个仲裁者y数量,或柚子卡路里的数量。

类型安全

比方说,从半年后的现在,你重新访问这些代码,你写的:

auto z = x.time_ + y.time_; 

如果您以前曾决定给time_std::int64_t,或std::chrono::milliseconds::rep,那么上面的新代码行编译并创建运行时错误。添加两个时间点是没有意义的。明天+今天是无意义的。

不过,如果你之前已经决定放弃time_sys_time<milliseconds>我建议,代码创建z不会编译上面的线。类型系统在编译时间检测到逻辑错误。现在你不得不立即重新访问你的逻辑,并发现你为什么试图增加两个时间点。也许它只是一个类型o,你的意思是减去它们(这是合乎逻辑的,编译,并且产生duration类型milliseconds)。

使用

易于您可以指定now()time_数据成员用这个简单的语法:

using namespace std::chrono; 
time_ = time_point_cast<milliseconds>(system_clock::now()); 

现在time_只是另一个system_clock基础的time_point但与milliseconds精度。对于输出到JSON,你可以得到与内部整型值:

json_stream << time_.time_since_epoch().count(); 

对于从JSON可以在分析中:

std::int64_t temp; 
json_stream >> temp; 
time_ = sys_time<milliseconds>{milliseconds{temp}}; 
+0

是的,我是你的btw的忠实粉丝:D会反过来使用你的日期库。 –

+0

@hg_git:太棒了,谢谢。 'date :: sys_time '是在date.h中预制的。 –

3

你的方法将工作和便携,但我建议用更简单的方法,用于计算毫秒:

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

这肯定会工作,因为.Count之间的()返回一个std ::计时::毫秒:: rep是“至少有45位的有符号整型”,并且应该适用于很长时间。

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

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

5

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

不,你需要一个符号整型至少45位,这long是不能保证是。您应该使用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通过标准的(即使是这样最的时间)。

+0

waaiiit什么? 'system_clock的时代不能保证是标准的1970年1月1日00:00:00 UTC,那么我该如何检查?我的意思是它依赖于编译器及其版本,操作系统或机器的体系结构? –

+1

@hg_git您可以使用'to_time_t'和'gmtime'从'system_clock'获得'std :: tm',并检查这是否是正确的日期,如果不是,那么您需要做一些额外的计算。时代依赖于系统,而不依赖于编译器,参见[wikipedia [(https://en.wikipedia.org/wiki/Epoch_%28reference_date%29#Computing))。这个时期不可能与UNIX时代不同,但在标准的观点上,这是不能保证的。 – Holt

+0

目前,1970-01-01 00:00:00 UTC是事实上的标准(但未被C++标准指定)。我打算试着用不久的将来建议来说明它。另请参阅有关这种狭义避难灾难的信息:https://twitter.com/StephanTLavavej/status/780816381394550784 –