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.
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.
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.)
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".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With