Say I have a nanoseconds, 1614601874317571123.
This represents the nanoseconds from epoch (1970-01-01).
That is "2021-03-01T12:31:14.317571123" in ISO format
I want to convert it to boost::posix_time::ptime
.
I know I could define a function like,
#include <boost/date_time/posix_time/posix_time.hpp>
#define BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
using namespace std;
namespace pt = boost::posix_time;
namespace gr = boost::gregorian;
pt::ptime from_nanos(const long long &nanos) {
return pt::ptime(gr::date(1970, 1, 1)) + pt::time_duration(0, 0, 0, nanos);
}
But this requires me to define a macro BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
that changes resolution from microseconds to nanoseconds.
I want to avoid this.
Are there any more robust solutions?
You already have the "correct" solution (although the code shown is incorrect, the define MUST precede any headers that may include Boost Datetime stuff).
Also note that
return pt::ptime(gr::date(1970, 1, 1)) + pt::time_duration(0, 0, 0, nanos);
should probably just be
return pt::ptime({1970, 1, 1}, pt::time_duration(0, 0, 0, nanos));
or indeed even
return {{1970, 1, 1}, {0, 0, 0, nanos}};
If you cannot use the define, you can always do a twostep: add seconds, and add fractional seconds later. That way you don't run into overflow issues with the default representation types.
Here's a tester: Live On Compiler Explorer
#include <boost/date_time/posix_time/posix_time.hpp>
using boost::posix_time::ptime;
ptime from_nanos_std(intmax_t nanos) {
return {{1970, 1, 1}, {0, 0, 0, nanos}};
}
ptime from_nanos_man(intmax_t nanos) {
constexpr auto NANO = 1'000'000'000;
#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
constexpr auto FRAC = 1;
#else
constexpr auto FRAC = 1'000;
#endif
return {{1970, 1, 1}, {0, 0, nanos / NANO, (nanos % NANO) / FRAC}};
}
#include <iostream>
int main() {
std::cout << "Expected: 2021-Mar-01 12:31:14.317571123\n";
#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
std::cout << "Standard: " << from_nanos_std(1614601874317571123) << "\n";
#endif
std::cout << "Manual: " << from_nanos_man(1614601874317571123) << "\n";
}
Output with -DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG:
Expected: 2021-Mar-01 12:31:14.317571123
Standard: 2021-Mar-01 12:31:14.317571123
Manual: 2021-Mar-01 12:31:14.317571123
Output without:
Expected: 2021-Mar-01 12:31:14.317571123
Manual: 2021-Mar-01 12:31:14.317571