以下是我的简单帮手的操作,其行为应与std::chrono::system_clock相似,但纪元为1.1。 2000年,我可以轻松地将持续时间转换为秒(或毫秒或毫秒),并将它们存储在某些记录(源自小型设备)中。

所有这些都从一个constexpr开始:

/// 1.1.2000 0:00
    static constexpr time_point<system_clock> epoch
      = time_point<system_clock>(seconds(946681200))


哪个帮助我获得了例如像这样从1.1.2000开始的毫秒数:

duration_cast<milliseconds>( system_clock::now() - epoch ).count()


问题是,没有合同/规范是什么纪元,但通常是1.1。 1970.

(我曾经选择使用单位为RTC的1.1。2000,并且将固件设计为可以工作到1.1。2100,直到我可能已经死了,或者非常老头,不会有要注意...在设计协议时,记录大小和传输的数据量更为重要。)

(该标头中有一些using std::chrono::system_clock,例如在namespace firda内部)

#include "basics.hpp"
using namespace firda;

/// Clock with altered epoch
template<class Clock = system_clock
  , typename Clock::rep Epoch = 946681200>
  struct adapted_clock {

    using rep        = typename Clock::rep;
    using period     = typename Clock::period;
    using duration   = typename Clock::duration;
    using time_point = typename firda::time_point<adapted_clock>;

    static constexpr bool is_steady
      = Clock::is_steady;
    static constexpr typename Clock::time_point epoch
      = typename Clock::time_point(seconds(Epoch));

    static time_point now() {
        return time_point(Clock::now() - epoch);
    }

    static time_t to_time_t(const time_point& t) {
        return Clock::to_time_t(epoch + t.time_since_epoch());
    }

    static time_point from_time_t(time_t t) {
        return time_point(Clock::from_time_t(t) - epoch);
    }
};

using y2k_clock = adapted_clock<>;

int main() {
    auto now1 = system_clock::now();
    auto now2 = y2k_clock::now();
    cout << "now1.count: " << duration_cast<seconds>(now1
      .time_since_epoch()).count() << '\n';
    cout << "now2.count: " << duration_cast<seconds>(now2
      .time_since_epoch()).count() << '\n';
    time_t time1 = system_clock::to_time_t(now1);
    time_t time2 = y2k_clock::to_time_t(now2);
    cout << "time1: " << std::ctime(&time1) << '\n';
    cout << "time2: " << std::ctime(&time2) << '\n';
}


评论

于1970年1月1日00:00:00过去的946681200s是1999年12月31日23:00:00。您是说946684800s吗?

@HowardHinnant:是的,我可能将其与当地时间(CET〜GMT + 1)混为一谈。 946681200/3600 = 262967,这很奇怪。 946684800/3600/24 = 10957 = 30 * 365 + 7(30 * 365.25 = 10957.5)

#1 楼

坦白地说,关于此类的内容不多,因为它足够简单并且依赖于另一个简单的时钟。类型别名,静态成员和静态方法似乎都依赖于模板参数Clock,因此没有问题。我相信firda::time_point根本不是std::chrono::time_point的全部内容,这也不是问题。

我唯一的评论是关于模板参数:我不确定将Clock缺省设置为std::chrono::system_clock是否有意义。这真的是三个标准时钟中的默认时钟吗?如果您这样认为,为什么。但坦率地说,默认Epoch没有意义:adapted_clock<>不会向用户告知任何有关时代的信息,并且您已经提供了有意义的类型别名y2k_clock(请注意,使用默认值始终等同于使用y2k_clock,这使它们无用)。虽然您不能更改模板参数的顺序,但不能默认Clock,因为您无法更改模板参数的顺序。

我认为最好的解决方案是将未默认的模板参数保留在Epoch中,但应将adapted_clock设置为具有可能默认的y2l_clock模板参数的别名模板:

template<typename Clock=std::chrono::system_clock>
using y2k_clock = adapted_clock<Clock, 946681200>;


如果您不喜欢此别名模板解决方案,我仍然建议不要默认Clock的模板参数而是这样写:

using y2k_clock = adapted_clock<std::chrono::system_clock, 946681200>;


评论


\ $ \ begingroup \ $
我会考虑您的提示。如果在标题中选择了firda :: time_point = std :: time_point(默认情况下)。我使用它来根据需要进行增强或其他任何实现。设计和默认模板参数均朝着目标迈进-y2k_clock(2000年时钟)和Adapted_clock因此更喜欢这个时代(并允许使用其他时钟)。但是我认为我应该从相反的角度思考:谁以及如何使用它;)制作另一个专门针对Y2K的模板听起来不错。
\ $ \ endgroup \ $
–user52292
2014年12月19日上午10:29