如何创建用于std :: chrono函数的自定义时钟?

sag*_*rgp 18 c++ c++11 c++-chrono

我有一些任意的时代,比如1988年7月13日.基本上我想测量相对于此的时间.我正在考虑编写一个自定义时钟类,以便我可以编写这样的代码:

using std::chrono;
time_point<My_Clock> tp;
std::cout << duration_cast<seconds>(tp.time_since_epoch()).count() << std::endl;
Run Code Online (Sandbox Code Playgroud)

这可能吗?如果没有,最简洁的方法是什么?

How*_*ant 31

编写这个自定义时钟的难点在于弄清楚如何编写它的now()功能.在下面的例子中我基地now()的关闭system_clocknow().首先,我做了一些侦探工作,发现我system_clock有一个1970年的新时代,忽略了闰秒.这称为unix时间.事实证明,我所知道的每一个实现(我认为我已经检查过它们)都有这个相同的时代(但是C++ 11标准没有指定).

接下来我计算1988-07-13是1970-01-01之后的6768天.使用这两个事实,其余的很容易:

#include <chrono>

struct My_Clock
{
    typedef std::chrono::seconds              duration;
    typedef duration::rep                     rep;
    typedef duration::period                  period;
    typedef std::chrono::time_point<My_Clock> time_point;
    static const bool is_steady =             false;

    static time_point now() noexcept
    {
        using namespace std::chrono;
        return time_point
          (
            duration_cast<duration>(system_clock::now().time_since_epoch()) -
            hours(6768*24)
          );
    }
};
Run Code Online (Sandbox Code Playgroud)

MyClock需要嵌套的类型定义来描述它duration,rep,period,和time_point.根据你的问题,我选择secondsduration,但你可以选择你想要的任何东西.

对于now()函数我只需调用system_clock::now()和以秒为单位减去纪元.通过编写所有内容MyClock::duration,我对这个计算有点聪明,这样我就可以更容易地改变duration.请注意,我能够减去时代hours,隐含地转换为duration(这是seconds).或者我可以为自己建立一个习惯duration的日子:

typedef std::chrono::duration<int, std::ratio_multiply<std::chrono::hours::period,
                                                       std::ratio<24>>> days;
Run Code Online (Sandbox Code Playgroud)

然后now()可以写回来:

        return time_point
          (
            duration_cast<duration>(system_clock::now().time_since_epoch()) -
            days(6768)
          );
Run Code Online (Sandbox Code Playgroud)

无论如何,现在你可以使用它:

#include <iostream>

int
main()
{
    using namespace std::chrono;
    time_point<My_Clock> tp = My_Clock::now();
    std::cout << tp.time_since_epoch().count() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

对我来说只打印出来:

786664963
Run Code Online (Sandbox Code Playgroud)

这表明今天(2013-06-16)在1988-07-13之后大约是24.9年.