Search code examples
c++c++-chrono

std::chrono::system_clock::now() serialization


How can I serialize the result of std::chrono::system_clock::now() so I can then load it and compare it with a later timestamp?

I tried to serialize in the following way:

std::to_string((uint64_t)std::chrono::system_clock::now().time_since_epoch().count())

Then to unserialize it:

std::chrono::milliseconds t(<uint64 number>);
std::chrono::time_point<std::chrono::system_clock>(t); 

The deserialization is not working, the object is the first day of 1970

Minmum example:

#include <iostream>
#include <chrono>

using namespace std;


static std::string clockToStr(std::chrono::system_clock::time_point timestamp)
{
    static char buffer[64];

    std::time_t t  = std::chrono::system_clock::to_time_t(timestamp);

    ::ctime_r(&t, buffer);
    return std::string(buffer);

}

    int main()
    {
        
        uint64_t t1 = std::chrono::system_clock::now().time_since_epoch().count();
        
        std::chrono::milliseconds t(t1);
        
        auto t2 = std::chrono::time_point<std::chrono::system_clock>(t); 
        
        std::cout<<clockToStr(t2)<<std::endl;
    
        return 0;
    }

Solution

  • As noted, time_since_epoch is not necessarily in milliseconds. If you want to serialize milliseconds, use duration_cast. Otherwise something like this should work:

      using clock_t = std::chrono::system_clock;
      clock_t::time_point tp = clock_t::now();
      std::string serialized = std::to_string(tp.time_since_epoch().count());
      clock_t::time_point tp1(clock_t::duration(std::stoll(serialized)));
    

    We use the time_point constructor that uses a duration, which is the opposite of the time_since_epoch() method.

    The serialization is a bit wonky because I use long long. Better would be something that detects the type of clock_t::duration::rep. Something like this:

    std::ostringstream os;
    os << tp.time_since_epoch().count();
    std::string serialized = os.str();
    std::istringstream is(serialized);
    clock_t::rep count;
    is >> count;
    clock_t::time_point tp1{clock_t::duration{count}};