Home > database >  How to convert nanoseconds to ptime in boost C
How to convert nanoseconds to ptime in boost C

Time:08-22

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
  • Related