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_zone
的 to_local()
成员函数的替代方法。
对于查找当地时间的简单情况,这两种技术具有相同的行为和性能,因此选择首选方法归结为可读性问题。
我快速阅读了有关 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_zone
的 to_local()
成员函数的替代方法。
对于查找当地时间的简单情况,这两种技术具有相同的行为和性能,因此选择首选方法归结为可读性问题。