C++20 天的当前时间和日期

Current time and date in C++20 days

我快速阅读了有关 new chrono 的 C++ 参考资料 类 但我发现它们有点复杂。

那么,问题来了,如何用C++20重写这段代码,得到年月日时分秒?

有什么变化吗?我问是因为 std::localtime 这个小问题:它是线程不安全的。 tm 将在下次调用 std::localtime 后销毁。

std::time_t t = std::time(nullptr);
std::tm *tm = std::localtime(&t);
int year = tm->tm_year + 1900;
int month = tm->tm_mon + 1;
int day = tm->tm_mday;
int hour = tm->tm_hour;
int minute = tm->tm_min;
int second = tm->tm_sec;
#include <chrono>

int
main()
{
    using namespace std::chrono;

    // Get a local time_point with system_clock::duration precision
    auto now = zoned_time{current_zone(), system_clock::now()}.get_local_time();

    // Get a local time_point with days precision
    auto ld = floor<days>(now);

    // Convert local days-precision time_point to a local {y, m, d} calendar
    year_month_day ymd{ld};

    // Split time since local midnight into {h, m, s, subseconds}
    hh_mm_ss hms{now - ld};

    // This part not recommended.  Stay within the chrono type system.
    int year{ymd.year()};
    int month = unsigned{ymd.month()};
    int day = unsigned{ymd.day()};
    int hour = hms.hours().count();
    int minute = hms.minutes().count();
    int second = hms.seconds().count();
}

我试图通过注释解释每一行代码的作用。如果有任何不清楚的地方,我很乐意进一步阐述。

这都是线程安全的。

更多信息:

计算 now 的另一种可能更简洁的方法是:

auto now = current_zone()->to_local(system_clock::now());

这会导致 now.

的类型和值完全相同

我在上面使用了 zoned_time,因为它(通常)是比直接调用 time_zone 的成员函数更高级别的抽象。在这两个示例中,now 的类型都是一个简单的 std::chrono::time_point,它与 system_clock::time_point 的偏移量为此时与 time_zone 关联的 UTC 偏移量。

相比之下,zoned_time 包含更多信息。例如,它知道:

  • time_zone 的名称。
  • 此时 time_zone 的缩写。
  • time_zone此时的UTC偏移量,后续可以同时产生本地时间和UTC等效时间。
  • offset/abbreviation 对的有效范围。

因此,zoned_time 对于格式化等作业更加灵活,因为它可以显示缩写 and/or UTC 偏移量。而一个zoned_time也可以更方便地用来找出其他时区的等效时间。

然而,在这个简单的示例中实际上并没有使用所有这些额外信息,因此我公开了直接调用 time_zoneto_local() 成员函数的替代方法。

对于查找当地时间的简单情况,这两种技术具有相同的行为和性能,因此选择首选方法归结为可读性问题。