【问题标题】:std::chrono::system_clock and C timestd::chrono::system_clock 和 C 时间
【发布时间】:2021-02-24 07:24:49
【问题描述】:

我在我的项目中普遍使用以下时间点定义:

using time_point = std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long, std::ratio<1,1000>>>

有了这个定义,我在精度和范围之间得到了合理的权衡,不幸的是,纳秒分辨率的默认值给了我一个太短的范围。

不幸的是,我似乎无法使用chrono::system_clock::from_time_t()chrono::system_clock::to_time_t 函数在std::time_t 和非默认分辨率的时间点之间进行转换。有没有办法可以将to_time_tfrom_time_t 函数与“我的”time_point 类一起使用?

【问题讨论】:

  • 纳秒带符号的 64 位数字在 1970 年的情况下工作到 2262,这还不够吗?

标签: c++ chrono


【解决方案1】:

如果您假设std::chrono::system_clocktime_t 具有相同的纪元(通常是这样),那么to_time_tfrom_time_t 本质上只是std::duration_cast

例如,此代码应打印两次相同的值(请注意,to_time_t 是舍入还是截断未指定,duration_cast 总是截断,因此可能存在 1 秒的差异):

const auto now = std::chrono::system_clock::now();
time_t time = std::chrono::system_clock::to_time_t(now);
std::cout << time << "\n";
std::cout << std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count() << "\n";
std::cout << std::chrono::system_clock::from_time_t(time).time_since_epoch().count() << "\n";
std::cout << std::chrono::system_clock::time_point(std::chrono::seconds(time)).time_since_epoch().count() << "\n";

因此,您可以相当轻松地编写自己的 to/from_time_t 函数:

constexpr time_point  my_point_from_time_t(time_t value)
{
    return time_point(std::chrono::seconds(value));
}

constexpr time_t my_point_to_time_t(const time_point & value)
{
    return std::chrono::duration_cast<std::chrono::seconds>(value.time_since_epoch()).count();
}

如果system_clock 不使用与time_t 相同的纪元,那么您可以简单地调整值:

const time_t system_clock_epoch = std::chrono::system_clock::to_time_t({});

time_point  my_point_from_time_t(time_t value)
{
    return time_point(std::chrono::seconds(value - system_clock_epoch));
}

time_t my_point_to_time_t(const time_point & value)
{
    return std::chrono::duration_cast<std::chrono::seconds>(value.time_since_epoch()).count() + system_clock_epoch;
}

【讨论】:

  • 幸运的是,std::chrono::system_clock 将被强制使用 C++20 标准中的 Unix 纪元。但std::time_t 的纪元和分辨率仍未指定。在符合 POSIX 的系统(和 MSVC)中,std::time_t 计算自 Unix 纪元以来的秒数。因此,从 C++20 开始,时期只能在非 POSIX 系统上有所不同。因此,假设 std::time_t 可能不使用 Unix 纪元,您就已经假设系统不兼容 POSIX。这很好,但在这种情况下,不能保证std::time_t 在这样的系统上使用秒(而不是毫秒或其他)。
猜你喜欢
  • 2014-03-23
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 2013-12-05
  • 1970-01-01
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多