How to create a custom clock for use in std::chrono functions?

前端 未结 1 1248
北恋
北恋 2020-12-30 01:11

I have some arbitrary epoch, like July 13, 1988. Essentially I want to measure the time relative to this. I was thinking of writing a custom clock class, so that I could wri

相关标签:
1条回答
  • 2020-12-30 01:49

    The hard part of writing this custom clock is figuring out how to write its now() function. In the example below I base the now() off of system_clock's now(). First I do some detective work to discover that my system_clock has an epoch of New Years 1970, neglecting leap seconds. This is known as unix time. As it turns out, every implementation I'm aware of (and I think I've checked them all) have this very same epoch (but this is unspecified by the C++11 standard).

    Next I compute that 1988-07-13 is 6768 days after 1970-01-01. Using these two facts, the rest is easy:

    #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)
              );
        }
    };
    

    MyClock needs nested typedefs to describe its duration, rep, period, and time_point. Based on your question, I've chosen seconds as the duration, but you can choose anything you want.

    For the now() function I just call the system_clock::now() and subtract off the epoch in units of seconds. I got just a little clever with this computation by writing everything in terms of MyClock::duration so that I can more easily change duration. Note that I was able to subtract off the epoch in terms of hours, which implicitly converts to duration (which is seconds). Alternatively I could have built myself a custom duration of days:

    typedef std::chrono::duration<int, std::ratio_multiply<std::chrono::hours::period,
                                                           std::ratio<24>>> days;
    

    And then the return of now() could have been written:

            return time_point
              (
                duration_cast<duration>(system_clock::now().time_since_epoch()) -
                days(6768)
              );
    

    At any rate, now you can use this like:

    #include <iostream>
    
    int
    main()
    {
        using namespace std::chrono;
        time_point<My_Clock> tp = My_Clock::now();
        std::cout << tp.time_since_epoch().count() << '\n';
    }
    

    Which for me just printed out:

    786664963
    

    Which demonstrates that today (2013-06-16) is approximately 24.9 years after 1988-07-13.

    0 讨论(0)
提交回复
热议问题