boost::posix_time::time_duration overflow?

boost::posix_time::time_duration overflow?

本文关键字:time overflow duration posix boost      更新时间:2023-10-16

我有以下代码可以从posix_time中获取UNIX时间

boost::posix_time::ptime time1(boost::gregorian::date(9999,12,31));
boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1));
boost::posix_time::time_duration diff = time1-epoch;
cout<<"A: "<<time1<<endl;
cout<<"B: "<<epoch<<endl;
cout<<"C: "<<diff<<endl;
unix_time = diff.total_seconds()

给我这个输出

9999-Dec-31 00:00:00
1970-Jan-01 00:00:00
-1347834:03:51.933722624

现在diff不应该是一个负数。我怎样才能正确计算?有溢出吗?

(顺便说一句 - 我在下面的输出中使用了 coliru,我的本地 gcc 5.3.1 和 boost 1.60 重现)

问题是你想要在几秒钟内得到这个数字,所以让我们尝试一些基本的数学(看看我是否做对了!):)

A: 9999-Dec-31 00:00:00
B: 1970-Jan-01 00:00:00
C: 70389504:00:00

因此,差异(以小时表示)为 70389504 小时。以秒为单位是:

70389504 * 60

* 60 => 253402214400 秒

现在,在库的内部,有一个用于sec_type的类型 def,默认为 boost::int32_t 。因此,除非将其设置为 int64_t ,否则上述值将溢出。

至于如何覆盖它,除非您破解date_time库,并将time_resolution_traits.h中的默认值从boost::int32_t更改为boost::int64_,否则是不可能的。(可能还有另一种方法,但我还没有详细调查代码来告诉你那会是什么。

现在对于您的真正问题,您似乎有这套-DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG - 我怀疑您想要纳秒级精度?如果是这样,我认为您必须减少支持的日期范围。

这是 boost::d ate_time: https://svn.boost.org/trac/boost/ticket/3109 中的一个已知问题

time_duration可以表示比 boost::time_duration::total_seconds() 类型可以表示的秒数更大的间隔。

如果您需要总秒数,最好使用

time_duration td = ...
auto seconds = td.ticks() / time_duration::ticks_per_seconds();

您始终可以通过从零中减去正/负来反转正/负。

diff = 0 - diff; // if diff was negative it will be positive now.

编辑1:额外信息;

此外,您公式 time1-epoch 将计算 2 个时间点之间的差异。您应该将差异添加到当前时间,这应该应该符合您的喜好。(负面结果是逻辑差异)。

如果您有

C++11,也许<chrono>加上这个免费的开源日期库,它可以扩展<chrono>会有所帮助?

#include "date.h"
#include <iostream>
int
main()
{
    using namespace date::literals;
    auto time1 = 9999_y/dec/31;
    auto epoch = 1970_y/jan/1;
    std::chrono::seconds diff = date::sys_days{time1} - date::sys_days{epoch};
    std::cout << "A: " << time1 << 'n';
    std::cout << "B: " << epoch << 'n';
    std::cout << "C: " << diff.count() << 'n';
}

输出:

A: 9999-12-31
B: 1970-01-01
C: 253402214400