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?
CodePudding user response:
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