假设我有一纳秒,1614601874317571123。
这表示从纪元(1970-01-01(开始的纳秒。
这就是";2021-03-01T12:31:14.317571123";ISO格式
我想把它转换成boost::posix_time::ptime
。
我知道我可以定义一个函数,比如
#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);
}
但这需要我定义一个将分辨率从微秒更改为纳秒的宏BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
。
我想避免这种情况。
还有更强大的解决方案吗?
您已经有了"正确的";解决方案(尽管显示的代码不正确,但定义必须在任何可能包括Boost Datetime内容的标头之前(。
还要注意
return pt::ptime(gr::date(1970, 1, 1)) + pt::time_duration(0, 0, 0, nanos);
应该只是
return pt::ptime({1970, 1, 1}, pt::time_duration(0, 0, 0, nanos));
甚至
return {{1970, 1, 1}, {0, 0, 0, nanos}};
如果不能使用define,则可以执行两步操作:添加秒,并在之后添加小数秒。这样就不会遇到默认表示类型的溢出问题。
下面是一个测试人员:Live-On-CompilerExplorer
#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.317571123n";
#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";
}
带-DBOOT_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
无输出
Expected: 2021-Mar-01 12:31:14.317571123
Manual: 2021-Mar-01 12:31:14.317571