如何将分数纪元时间戳(double)转换为std :: chrono :: time_point?

mav*_*vam 8 c++ boost-date-time unix-timestamp c++11 c++-chrono

我有一个小数纪元时间戳,表示为double,我想转换为适当的std::chrono::time_point.这个时代是自1970年1月1日以来的常见UNIX时代.我知道存在std::chrono::system_clock::from_time_t,但是time_t没有一个小部分.使用C++ 11的最佳方法是什么?

这个问题与boost :: posix_time :: ptime的unix时间戳有关,除了它要求的是C++ 11而不是Boost版本.

R. *_*des 13

假设纪元与已知clock类型相同,您可以使用具有double表示的持续时间并转换为该时钟使用的持续时间.

// change period to appropriate units - I'm assuming seconds
typedef std::chrono::duration<double, std::ratio<1>> d_seconds;

d_seconds since_epoch_full(324324.342);
auto since_epoch = std::chrono::duration_cast<clock::duration>(since_epoch_full);
clock::time_point point(since_epoch);
Run Code Online (Sandbox Code Playgroud)

这适用于任何涉及该时钟的计算,因为您使用与时钟相同的精度,但它可能会失去转换中的某些精度.如果您不想丢失,则必须使用time_point使用double基于持续时间类型的专业化.然后在计算中使用它(当然,还有浮点数学的所有注意事项).

typedef std::chrono::time_point<clock, d_seconds> d_time_point;
Run Code Online (Sandbox Code Playgroud)

但是,这会使涉及同一时钟的任何计算复杂化,因为它需要转换.为了使这更容易,您可以构建自己的时钟包装器来执行转换并使用:

template <typename Clock>
struct my_clock_with_doubles {
    typedef double rep;
    typedef std::ratio<1> period;
    typedef std::chrono::duration<rep, period> duration;
    typedef std::chrono::time_point<my_clock_with_doubles<Clock>> time_point;
    static const bool is_steady = Clock::is_steady;

    static time_point now() noexcept {
        return time_point(std::chrono::duration_cast<duration>(
                   Clock::now().time_since_epoch()
               ));
    }

    static time_t to_time_t(const time_point& t) noexcept {
        return Clock::to_time_t(typename Clock::time_point(
                             std::chrono::duration_cast<typename Clock::duration>(
                                 t.time_since_epoch()
                             )
                        ));
    }
    static time_point from_time_t(time_t t) noexcept {
        return time_point(std::chrono::duration_cast<duration>(
                   Clock::from_time_t(t).time_since_epoch()
               ));
    }
};
Run Code Online (Sandbox Code Playgroud)