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

时间:2016-09-28 14:56:38

标签: c++ chrono

我试图通过将time_point设置为秒:: max来尝试使用time_point来有效地表示,我认为,这应该代表自纪元以来的那段时间。但是,在执行此操作时,我得到-1作为生成的time_point中的纪元以来的时间。我不理解的是什么?

#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

2 个答案:

答案 0 :(得分:1)

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

#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_clock time_point的分母值为1,000,000。因此,转换后最大秒数将会溢出。

答案 1 :(得分:1)

这是一个快速而又肮脏的程序,用于探索不同精度的system_clock time_point的限制:

#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

基于2262年的纳秒溢出来表示system_clock。如果你将其缩小到微秒,那么在294,247年你就会溢出。等等。

一旦你粗糙到几秒钟,最大值就会达到一个荒谬的范围。但是当你把它转换回system_clock::time_point时,它至少可以达到微秒,也可能只有几纳秒(取决于你的平台),你可以把它从水中吹出来。

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

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