Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从64位整数秒计数创建boost::posix_time::ptime对象_C++_Boost_Unix Timestamp_Boost Date Time - Fatal编程技术网

C++ 从64位整数秒计数创建boost::posix_time::ptime对象

C++ 从64位整数秒计数创建boost::posix_time::ptime对象,c++,boost,unix-timestamp,boost-date-time,C++,Boost,Unix Timestamp,Boost Date Time,我有一个32位的Linux系统,在这个系统中,我必须记录时间戳为UINT32秒的数据,从1901-01-01 00:00:00的历元开始偏移 计算时间戳对我来说没问题,因为我可以使用64位的ticks()计数器和ticks\u per\u second()函数生成自历元以来的秒数,如下所示(我只需要二级分辨率) 这对我来说很有用,因为我知道作为一个无符号整数,秒数不会超过最大UINT32值(至少在很多年内不会超过) 我遇到的问题是,我的应用程序可以接收包含UINT32值的modbus消息,我必须

我有一个32位的Linux系统,在这个系统中,我必须记录时间戳为UINT32秒的数据,从1901-01-01 00:00:00的历元开始偏移

计算时间戳对我来说没问题,因为我可以使用64位的
ticks()
计数器和
ticks\u per\u second()
函数生成自历元以来的秒数,如下所示(我只需要二级分辨率)

这对我来说很有用,因为我知道作为一个无符号整数,秒数不会超过最大UINT32值(至少在很多年内不会超过)

我遇到的问题是,我的应用程序可以接收包含UINT32值的modbus消息,我必须使用
RTC\u set\u TIME
调用
ioctl
设置硬件和系统时钟。这UINT32也是自我的纪元1901-01-01 00:00:00以来的偏移量(以秒为单位)

我现在的问题是,我无法使用64位整数创建对象
ptime
时间持续时间
对象的
滴答声
部分是私有的,我只能使用
,在我的32位系统上,它只是一个4字节有符号整数,不足以存储秒偏移量从我的时代开始

我无法控制epoch的值,因此我真的很难从我拥有的数据中创建所需的
boost::posix_time::ptime
对象。 我可能可以通过计算特定时间间隔的硬秒计数并使用额外的历元建立桥接来获得一个肮脏的解决方案,但我想知道
boost
代码中是否有什么东西可以让我完全使用boost datetime库来解决问题。 我已经阅读了所有我能找到的文档,但我看不到任何明显的方法来做到这一点


编辑:我发现了这个相关的问题,但接受的答案对我的历元不起作用

您可以以最大允许增量(即
std::numeric\u limits::max()
)应用时间持续时间,因为
total\u 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";
}

查看

虽然如果秒代表大于32位的数字(截至2014年10月),则不能使用
boost::posix_时间::seconds
,但事实证明
boost::posix_时间::毫秒
可以轻松使用(无需解决办法),如下所示:

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;

谢谢你的回答。我自己也做了类似的事情,我只是希望通过boost而不是变通解决方案。我想这里没有回复说明没有回复。我会接受你的答案,如果没有其他东西在几天内出现。这是惊人的,这必须在2014年10月,在C++(甚至与Boost)。“为什么这些类型在很久以前没有切换到64位呢?”DanNissenbaum我用你的答案测试了一下,事实上,它更优雅了!
uint64_t offset = 113ul*365ul*24ul*60ul*60ul*1000ul; // 113 years give or take some leap seconds/days etc.?
uint64_t offset = uint64_t(113ul)*365*24*60*60*1000;