持久化std :: chrono time_point实例 [英] Persisting std::chrono time_point instances

查看:239
本文介绍了持久化std :: chrono time_point实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

保存std :: chrono time_point实例,然后将它们读回另一个相同类型的实例的正确方法是什么?

  typedef std :: chrono :: time_point< std :: chrono :: high_resolution_clock> time_point_t; 

time_point_t tp = std :: chrono :: high_resolution_clock :: now();
serializer.write(tp);



time_point_t another_tp;
serializer.read(another_tp);

调用write / read,假设类型为time_point_t的实例可以以某种方式转换为



Alf建议的可能解决方案如下:

  std :: chrono :: high_resolution_clock :: time_point t0 = std :: chrono :: high_resolution_clock :: now 

//生成POD以写入磁盘
unsigned long long ns0 = t0.time_since_epoch()。count();

//从磁盘读取POD并尝试实例化time_point
std :: chrono :: high_resolution_clock :: duration d(ns0)

std :: chrono: :high_resolution_clock :: time_point t1(d);

unsigned long long ns1 = t1.time_since_epoch()。count();

if((t0!= t1)||(ns0!= ns1))
{
std :: cout< 错误时间点不匹配!\\\
;
}


上面的代码有一个错误,因为最终的实例化时间点与原始的时间点不匹配。



在旧式的time_t的情况下,

解决方案

time_point 构造函数需要一个 duration ,你可以得到 duration 来自成员 time_since_epoch 。因此问题减少为序列化 duration 值。和 duration 有一个构造函数,它接受多个ticks,并且一个成员函数 count 产生tick的数量。



所有这些只需通过googling std :: chrono :: time_point ,并查看cppreference文档google登陆我



这通常是一个好主意,请阅读 文档

:一个例子。

  #include< chrono> 
#include< iostream>
#include< typeinfo>
using namespace std;

auto main() - > int
{
using Clock = chrono :: high_resolution_clock;
using Time_point = Clock :: time_point;
using Duration = Clock :: duration;

Time_point const t0 = Clock :: now();

//生成POD以写入磁盘
Duration :: rep const ns0 = t0.time_since_epoch()。count();

//从磁盘读取POD并尝试实例化time_point
持续时间const d(ns0);
Time_point const t1(d);

cout<< 基本号码类型是< typeid(ns0).name()<< 。 << endl
if(t0!= t1)
{
cout< 错误时间点不匹配! << endl
}
else
{
cout< 重组时间OK。 << endl
}
}

使用Visual C ++ 12.0,报告的基本类型是 __ int64 ,即 long long ,而使用g ++ 4.8.2在Windows中报告的类型是 x ,这可能意味着相同。



对于两个编译器,重构时间与原始时间相同。



附录:由于 Dina在注释中注释,在C ++ 14中,C ++标准没有指定时期,所以为了使它跨机器或不同的时钟工作,需要添加额外的步骤来标准化时期对于序列化数据,最自然的是 Posix时间,即自00:00:00以来的时间世界协调时间(UTC) ),1970年1月1日,星期四。


What is the correct way to persist std::chrono time_point instances and then read them back into another instance of the same type?

   typedef std::chrono::time_point<std::chrono::high_resolution_clock> time_point_t;

   time_point_t tp = std::chrono::high_resolution_clock::now();
   serializer.write(tp);
   .
   .
   .
   time_point_t another_tp;
   serializer.read(another_tp);

The calls to write/read, assume that the instance of type time_point_t, can be somehow converted to a byte representation, which can then be written to or read from a disk or a socket etc.

A possible solution suggested by Alf is as follows:

   std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();

   //Generate POD to write to disk
   unsigned long long ns0 = t0.time_since_epoch().count();

   //Read POD from disk and attempt to instantiate time_point
   std::chrono::high_resolution_clock::duration d(ns0)

   std::chrono::high_resolution_clock::time_point t1(d);

   unsigned long long ns1 = t1.time_since_epoch().count();

   if ((t0 != t1) || (ns0 != ns1))
   {
      std::cout << "Error time points don't match!\n";
   }

Note: The above code has a bug as the final instantiated time point does not match the original.

In the case of of the old style time_t, one typically just writes the entire entity to disk based on its sizeof and then reads it back the same way - In short what would be the equivalent for the new std::chrono types?

解决方案

the time_point constructor takes a duration, and you can get a duration from member time_since_epoch. thus the question reduces to serialize a duration value. and duration has a constructor that takes a number of ticks, and a member function count that produces the number of ticks.

all this just by googling std::chrono::time_point and looking at the cppreference documentation google landed me on.

it's often a good idea to read the documentation.


Addendum: an example.

#include <chrono>
#include <iostream>
#include <typeinfo>
using namespace std;

auto main() -> int
{
    using Clock = chrono::high_resolution_clock;
    using Time_point = Clock::time_point;
    using Duration = Clock::duration;

    Time_point const t0 = Clock::now();

    //Generate POD to write to disk
    Duration::rep const ns0 = t0.time_since_epoch().count();

    //Read POD from disk and attempt to instantiate time_point
    Duration const d(ns0);
    Time_point const t1(d);

    cout << "Basic number type is " << typeid( ns0 ).name() << "." << endl;
    if( t0 != t1 )
    {
        cout << "Error time points don't match!" << endl;
    }
    else
    {
        cout << "Reconstituted time is OK." << endl;
    }
}

With Visual C++ 12.0 the reported basic type is __int64, i.e. long long, while with g++ 4.8.2 in Windows the reported type is x, which presumably means the same.

With both compilers the reconstituted time is identical to the original.

Addendum: As noted by Dina in the comments, as of C++14 the C++ standard doesn't specify the epoch, and so to make this work across machines or with different clocks it's necessary to add additional steps that normalize the epoch for the serialized data, e.g. and most naturally to Posix time, i.e. time since since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970.

这篇关于持久化std :: chrono time_point实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆