【问题标题】:How to create a time point from milliseconds since Unix epoch?如何从 Unix 纪元以来的毫秒数创建时间点?
【发布时间】:2021-06-11 19:41:39
【问题描述】:

要为当前时间创建时间点,可以使用:std::chrono::system_clock::now()

但是,我不知道如何创建一个自 UNIX 纪元以来的毫秒数的时间点?

另外,std::chrono::time_point 甚至是表示“即时”的推荐方式吗?还是应该首选std::time_t

【问题讨论】:

  • en.cppreference.com/w/cpp/chrono/time_point/time_since_epoch?我个人更喜欢时间点time_point 而不是持续时间time_t
  • 谢谢特德。抱歉,我可能很愚蠢,但我仍然不知道如何使用您的链接从 Unix 纪元创建一个给定毫秒的时间点?
  • 如果您将毫秒除以 time_t 的任何值(通常是秒),您可以使用 from_time_t 得到 time_point。使用 + std::chrono::milliseconds 添加剩余的毫秒数
  • @Jack 将复选标记移到我的 HH 的答案上,它好多了。
  • 已完成,非常感谢!

标签: c++ time c++17 c++20 chrono


【解决方案1】:

这更容易/更简单:

std::chrono::system_clock::time_point tp{std::chrono::milliseconds{m}};

上面的精度为system_clock::precision(macOS 上为microseconds,Linux 系统上为nanoseconds,Windows 上为1/10 microseconds)。如果需要,您还可以创建一个精度为millisecondstime_point

std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>
    tp{std::chrono::milliseconds{m}};

在 C++20 中,这可以简化为:

std::chrono::sys_time tp{std::chrono::milliseconds{m}};

sys_time 只是system_clock 系列time_points 在任何精度下的模板类型别名。 IE。以上与之前创建的milliseconds 精度time_point 完全相同。

另外,std::chrono::time_point 甚至是表示“瞬间”的推荐方式吗?还是应该首选 std::time_t?

我推荐std::chrono::system_clock::time_point 而不是std::time_t

  • 基于system_clocktime_point 有一个明确定义的纪元(在C++20 中),这也是C++17 中的事实标准:它从1970-01-01 00 开始计算时间::00:00 UTC,不包括闰秒。这也称为Unix Time。相比之下,没有 C 或 C++ 标准指定 time_t 的纪元,尽管使用 Unix Time 是常见做法,并且由 POSIX 指定。

  • 尽管未指定,time_t 通常具有seconds 的精度。 system_clock::time_point 通常具有比这更精细的数百万或数十亿的精度。没有指定确切的精度,但它记录在 API 中,因此您可以在编译时或运行时发现它。 system_clock::periodstd::ratiosystem_clock::time_point::period 相同,表示从一个滴答到下一个滴答的编译时间分数。

  • time_t 通常只是一个 32 或 64 位有符号整数。这在通用代码中没有类型安全性。例如,您可以添加两个 time_t 并编译。但是,添加两个时间点是不合逻辑的(而减去它们是)。 chrono 库在编译时捕获此类逻辑错误。添加两个time_point 不会编译。但是您可以添加time_point 和任何durationtime_points 和 durations 的逻辑代数会在编译时为您检查。

  • 如果您需要涵盖闰秒,time_t 没有指定但很常见(通常是Unix Time)。使用system_clock,指定了Unix Time(你知道你没有计算闰秒)。然而,在 C++20 中,还有另一个计时时钟确实在其计数中包含闰秒:std::chrono::utc_clock。像所有的计时时钟一样,这个时钟有它自己的类型安全系列time_points,还有它自己的方便模板类型别名utc_time&lt;Duration&gt;。您可以使用std::chrono::clock_cast 在它们之间进行转换。

像这样:

auto tp_sys = clock_cast<system_clock>(tp_utc);

【讨论】:

  • 请注意,在c++20 之前,“system_clock 的纪元未指定,但大多数实现使用 Unix 时间(即,从 00:00:00 开始的时间)协调世界时 (UTC),星期四,1 1970 年 1 月,不包括闰秒)。” - 但我不知道是否有任何例子。在c++20 中,需要unix 时间纪元。有趣的是,我假设 time_t 在我的(劣质)答案中是 unix 时间,所以并没有更好。
  • 非常感谢霍华德。这真的很有帮助。
  • 所有实现 system_clock 在 C++17 中使用 Unix Time。这就是我们能够标准化 C++20 现有实践的方式。 :-) 虽然我们真的接近无法when one major implementation announced it was going to change its epoch.,但我能够说服他们放弃它。他们同意我get the epoch standardized的规定。他们非常亲切,我非常感激。
【解决方案2】:
auto ms_since_epoch(std::int64_t m){
  return std::chrono::system_clock::from_time_t(time_t{0})+std::chrono::milliseconds(m);
}

这会返回一个系统时钟时间点。

与大多数与日历/时间相关的事物一样,正确涵盖闰秒等事物的几率很低;赔率是你的 ms,因为例如 unix epoch 值可能会被他们关闭。

【讨论】:

    猜你喜欢
    • 2019-12-04
    • 2021-04-24
    • 1970-01-01
    • 2011-10-24
    • 2014-09-02
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    相关资源
    最近更新 更多