在seconds::max处创建time_point,结果为负值

Create a time_point at seconds::max results in negative value

本文关键字:结果 point time max seconds 创建      更新时间:2023-10-16

我试图使用time_point通过将其设置为seconds::max来有效地表示永远,我认为它应该表示自epoch以来的那么多时间。但是,当这样做时,我得到-1作为结果time_point中自epoch以来的时间。我有什么不明白的吗?

#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main() {
    auto tp1 = system_clock::time_point( seconds::zero() );
    auto tp2 = system_clock::time_point( seconds::max() );
    cout << "tp1: " << duration_cast<seconds>(tp1.time_since_epoch()).count() << endl;
    cout << "tp2: " << duration_cast<seconds>(tp2.time_since_epoch()).count() << endl;
    return 0;
}

运行的输出是:

tp1: 0
tp2: -1

这里有一个简单的程序来探索system_clock time_point s在不同精度下的极限:

#include <chrono>
#include <iostream>
using days = std::chrono::duration
    <int, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>;
using years = std::chrono::duration
    <double, std::ratio_multiply<std::ratio<146097, 400>, days::period>>;
template <class Rep, class Period>
void
max_limit(std::chrono::duration<Rep, Period> d)
{
    std::cout << "[" << Period::num << '/' << Period::den << "] ";
    std::cout << years{d.max()}.count() + 1970 << 'n';
}
int
main()
{
    using namespace std;
    using namespace std::chrono;
    max_limit(nanoseconds{});
    max_limit(microseconds{});
    max_limit(milliseconds{});
    max_limit(seconds{});
}

这将输出time_point<system_clock, D>D任意持续时间内达到最大值的年份(以浮点数表示)。该程序输出:

[1/1000000000] 2262.28
[1/1000000] 294247
[1/1000] 2.92279e+08
[1/1] 2.92277e+11

表示基于纳秒溢出的system_clock在2262年。如果你把它粗化到微秒,就会在294247年溢出。等等。

一旦你粗化到秒,最大值就会变成一个可笑的范围。但是当你把它转换回system_clock::time_point时,这至少是微秒级的,也许是纳秒级的(取决于你的平台),你只是把它吹出了水。

为了解决你的问题,我建议:

auto M = system_clock::time_point::max();

添加更多的诊断显示问题(在我的系统上):

#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;
int main() {
    auto tp1 = system_clock::time_point( seconds::zero() );
    auto tp2 = system_clock::time_point( seconds::max() );
    using type = decltype(system_clock::time_point(seconds::zero()));
    cout << type::duration::max().count() << endl;
    cout << type::duration::period::den << endl;
    cout << type::duration::period::num << endl;
    cout << seconds::max().count() << endl;
    cout << milliseconds::max().count() << endl;
    cout << "tp1: " << duration_cast<seconds>(tp1.time_since_epoch()).count() << endl;
    cout << "tp2: " << duration_cast<seconds>(tp2.time_since_epoch()).count() << endl;
    return 0;
}

对于我来说,system_clocktime_point的分母值是1,000,000。因此,max seconds在转换时将溢出。