如何将小数纪元时间戳(双精度)转换为 std::chrono::time_point?

发布于 2025-01-03 19:39:18 字数 418 浏览 0 评论 0原文

我有一个小数纪元时间戳,表示为 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 版本。

I have a fractional epoch timestamp, represented as double, that I would like to convert to an appropriate std::chrono::time_point. The epoch is the usual UNIX epoch since 1/1/1970. I know that there exists std::chrono::system_clock::from_time_t, but a time_t does not have a fractional part. What would be the best way to do this with C++11 means?

This question is related to unix timestamp to boost::posix_time::ptime, except that it's asking for the C++11 rather than Boost version of it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

薄暮涼年 2025-01-10 19:39:18

假设纪元与已知的时钟类型相同,您可以使用带有双精度表示的持续时间,并将其转换为该时钟使用的持续时间。

// 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);

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

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

Assuming the epoch is the same as a known clock type you can use a duration with a double representation and convert to the duration used by that clock.

// 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);

This should be ok for any calculation involving that clock, since you're using the same precision as the clock, but it may lose some of the precision in the conversion. If you don't want to lose that you'll have to use a time_point specialization that uses that double-based duration type. And then use that in your calculations (of course, with all the caveats of floating-point math).

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

However, this will complicate any calculations involving that same clock, as it will require conversions. To make this easier, you can build your own clock wrapper that does the conversions and use that:

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()
               ));
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文