我有一个32位的Linux系统,我必须在其中记录带有时间戳的数据,该时间戳是从1901-01-01 00:00:00的纪元开始的UINT32秒偏移。
计算时间戳对我来说没问题,因为我可以使用64位ticks()
计数器和ticks_per_second()
函数来生成自纪元以来的秒数,如下所示(我只需要秒等级分辨率)
const ptime ptime_origin(time_from_string("1901-01-01 00:00:00"));
time_duration my_utc = microsec_clock::universal_time() - ptime_origin;
boost::int64_t tick_per_sec = my_utc.ticks_per_second();
boost::int64_t tick_count = my_utc.ticks();
boost::int64_t sec_since_epoch = tick_count/tick_per_sec;
这对我有用,因为我知道作为无符号整数,秒数不会超过最大UINT32值(反正很多年都没有)。
我遇到的问题是我的应用程序可以接收包含UINT32值的modbus消息,我必须使用ioctl
通过RTC_SET_TIME
调用来设置硬件和系统时钟。此UINT32再次是自我的纪元1901-01-01 00:00:00以来的秒数偏移量。
我现在的问题是我无法使用64位整数创建 ptime
对象 - ticks
对象的time_duration
部分是私有的我被限制使用long
,它在我的32位系统上只是一个4字节的有符号整数,不足以存储我的纪元的秒数。
我无法控制时代的价值,所以我真的很难过如何从我拥有的数据中创建所需的boost::posix_time::ptime
对象。
我可以通过计算特定时间间隔的硬第二次计数并使用额外的时间来建立一个允许这样的桥接来获得一个肮脏的解决方案,但我想知道boost
代码中是否有某些内容可以让我解决完全使用boost datetime库的问题。
我已经阅读了所有可以找到的文档,但是我看不出任何明显的方法。
编辑:我发现了这个相关问题Convert int64_t to time_duration,但那里接受的答案对我的纪元不起作用
答案 0 :(得分:2)
您可以以允许的最大增量(std::numeric_limits<long>::max()
)应用time_durations,因为total_seconds
字段仅限于long
(已签名)。
注意:我将其描述为int32_t
,以便在64位平台上进行编译时仍能正常工作。
这是一个小型演示:
#include "boost/date_time.hpp"
#include <iostream>
using namespace boost::gregorian;
using namespace boost::posix_time;
int main()
{
uint64_t offset = 113ul*365ul*24ul*60ul*60ul; // 113 years give or take some leap seconds/days etc.?
static const ptime time_t_epoch(date(1901,1,1));
static const uint32_t max_long = std::numeric_limits<int32_t>::max();
std::cout << "epoch: " << time_t_epoch << "\n";
ptime accum = time_t_epoch;
while (offset > max_long)
{
accum += seconds(max_long);
offset -= max_long;
std::cout << "accumulating: " << accum << "\n";
}
accum += seconds(offset);
std::cout << "final: " << accum << "\n";
}
打印:
epoch: 1901-Jan-01 00:00:00
accumulating: 1969-Jan-19 03:14:07
final: 2013-Dec-04 00:00:00
答案 1 :(得分:2)
如果秒表示大于32位的数字(截至2014年10月),则boost::posix_time::seconds
无法使用,但boost::posix_time::milliseconds
可以< / strong>易于使用(无需解决方法),如下所示:
inline std::string convertMsSinceEpochToString(std::int64_t const ms)
{
boost::posix_time::ptime time_epoch(boost::gregorian::date(1970, 1, 1));
boost::posix_time::ptime t = time_epoch + boost::posix_time::milliseconds(ms);
return boost::posix_time::to_simple_string(t);
}
所以,只需将你的64位秒转换为(64位)毫秒,你就可以了!
注意能够/非常/了解编译器相关的行为以及构建整数类型的能力:
uint64_t offset = 113ul*365ul*24ul*60ul*60ul*1000ul; // 113 years give or take some leap seconds/days etc.?
可以在GCC或Clang上运行,但它只会溢出MSVC2013中的计算。您需要明确地将计算强制转换为64位:
uint64_t offset = uint64_t(113ul)*365*24*60*60*1000;