Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert int64_t to time_duration

Tags:

c++

time

boost

I would like to transfer a boost::posix_time::ptime over the network as a boost::int64_t. According to A way to turn boost::posix_time::ptime into an __int64, I can easily define my own epoch and only transfer the time_duration from that reference epoch as a 64 bits integer. But how to convert back to a ptime?

#include <iostream>
#include <cassert>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian/greg_month.hpp>

using namespace std;

using boost::posix_time::ptime;
using boost::posix_time::time_duration;
using boost::gregorian::date;

int main(int argc, char ** argv){
    ptime t = boost::posix_time::microsec_clock::local_time();

    // convert to int64_t
    ptime myEpoch(date(1970,boost::gregorian::Jan,1));
    time_duration myTimeFromEpoch = t - myEpoch;
    boost::int64_t myTimeAsInt = myTimeFromEpoch.ticks();

    // convert back to ptime
    ptime test = myEpoch + time_duration(myTimeAsInt);

    assert(test == t);
    return 0;
}

This is not working since the time_duration constructor taking a tick count as argument is private. I am also interested in any other way to simply transfer that ptime over simple data types.

like image 734
tibur Avatar asked Jan 28 '11 14:01

tibur


3 Answers

Working solution with millisecond resolution:

int main(int argc, char ** argv){
    ptime t = boost::posix_time::microsec_clock::local_time();

    // convert to int64_t
    ptime myEpoch(date(1970,boost::gregorian::Jan,1));
    time_duration myTimeFromEpoch = t - myEpoch;
    boost::int64_t myTimeAsInt = myTimeFromEpoch.total_milliseconds();

    // convert back to ptime
    ptime test = myEpoch + boost::posix_time::milliseconds(myTimeAsInt);

    cout << test << endl;
    cout << t << endl;

    time_duration diff = test - t;

    assert(diff.total_milliseconds()==0);
    return 0;
}

Thanks 12a6.

like image 163
tibur Avatar answered Sep 28 '22 09:09

tibur


Works with whatever max resolution your boost::datetime library is compiled to (typically micros/nanos):

time_duration time_duration_from_ticks(time_duration::tick_type ticks)
{
    return time_duration(
        0,                                           // hours
        0,                                           // minutes
        ticks / time_duration::ticks_per_second(),   // seconds
        ticks % time_duration::ticks_per_second());  // fractional_seconds
}

(Note that time_duration::tick_type is your int64_t if you have set up boost datetime with only microsecond resolution, which is the default.)

like image 42
Alastair Maw Avatar answered Sep 28 '22 09:09

Alastair Maw


With microsecond resolution time_duration:

boost::posix_time::microseconds( _ts / TICKS_PER_MICROSECOND )

where TICKS_PER_MICROSECOND is the number of ticks per microsecond (e.g., 10 if ticks are hectonanoseconds, like in Windows FILETIME).

The reason why the milliseconds constructor seems to work for some people is that it accepts a parameter type of long, which is 64 bits in some compilers. In MSVC, it is 32 bits on 32 bit platforms, so it won't work. The microseconds constructor accepts a 64 bit integer, which should be "enough for everyone".

like image 40
Florian Winter Avatar answered Sep 28 '22 08:09

Florian Winter