替换 chrono::time_point 的小时?

Replace hour of chrono::time_point?

如何只更改现有 std::chrono::system_clock::time_point 的小时?

比如我想实现这个功能:

void set_hour(std::chrono::system_clock::time_point& tp, int hour) {
  // Do something here to set the hour
}

std::chrono::system_clock::time_point midnight_jan_1_2022{std::chrono::seconds{1640995200}};

set_hour(midnight_jan_1_2022, 11);
// midnight_jan_1_2022 is now 11am on Jan 1 2022
....

答案完全取决于您的意思。最简单的解释是,您想获取 tp 指向的任何日期(比如 yyyy-mm-dd hh:MM:ss.fff...),并创建:yyyy-mm-dd hour:00:00.000....

另一种可能的解释是yyyy-mm-dd hh:MM:ss.fff...转化为yyyy-mm-dd hour:MM:ss.fff...

无论哪种情况,C++20 都让这一切变得简单,如果您还没有访问 C++20 <chrono>,那么存在模拟 C++20 的 a free, open-source header-only library <chrono> 并适用于 C++11/14/17。

如果你想将分、秒和亚秒字段归零,如第一个解释中所述:

void
set_hour(std::chrono::system_clock::time_point& tp, int hour)
{
    using namespace std::chrono;

    auto day = floor<days>(tp);
    tp = day + hours{hour};
}

即您只需将 time_point 降低到 days-precision,然后添加所需的时间。

第二种解释稍微复杂一点:

void
set_hour(std::chrono::system_clock::time_point& tp, int hour)
{
    using namespace std::chrono;

    auto day = floor<days>(tp);
    hh_mm_ss hms{tp - day};
    tp = day + hours{hour} + hms.minutes() + hms.seconds() + hms.subseconds();
}

在这里,您必须发现并恢复{分钟、秒、亚秒}字段,以 re-apply 将它们恢复到所需的日期(以及所需的 hour)。 hh_mm_ss 是一种 C++20 {hours, minutes, seconds, subseconds} 数据结构,可以自动将持续时间转换为字段结构,以便您可以更轻松地替换小时字段。

对于您的示例输入,这两种解决方案都会给出相同的答案:

2022-01-01 11:00:00.000000

因为输入已经将分钟、秒和亚秒字段归零。