【问题标题】:How to convert a fractional epoch timestamp (double) to an std::chrono::time_point?如何将分数纪元时间戳(双精度)转换为 std::chrono::time_point?
【发布时间】:2012-02-10 00:01:34
【问题描述】:

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

这个问题与unix timestamp to boost::posix_time::ptime 相关,只是它要求的是 C++11 而不是 Boost 版本。

【问题讨论】:

  • 你读过N2661吗?
  • "(...) 小数纪元时间戳,表示为double" 什么单位?你知道时代吗?
  • @R.MartinhoFernandes:它是自 1970 年 1 月 1 日以来的标准 UNIX 时代。
  • 如果纳秒足够好,试试std::chrono::system_clock::from_time_t(x) + std::chrono::nanoseconds(1e9*std::fmod(x,1)) ?

标签: c++ c++11 unix-timestamp boost-date-time chrono


【解决方案1】:

假设 epoch 与已知的 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);

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

typedef std::chrono::time_point<clock, d_seconds> d_time_point;

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

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

【讨论】:

  • 感谢您的回答。您介意详细说明精度损失的根源吗?另外,d_time_point 中的时钟类型可以任意吗?
  • @Matthias:精度损失是因为时钟的本机持续时间类型可能无法将您的确切持续时间表示为double。例如,如果时长为 10.5 秒,但时钟使用周期为 1 秒的整数时长,则转换后将变为 10 秒或 11 秒。理想情况下,d_time_point 中的时钟类型应该是具有相同纪元的时钟类型。
  • @R.MartinhoFernandes:感谢您的澄清。
  • @DeadMG: 324324.342 是一个示例性的分数时间戳。
猜你喜欢
  • 2013-01-08
  • 1970-01-01
  • 2018-07-27
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 2016-04-23
相关资源
最近更新 更多