2021-04-28 16:49:39 +02:00
The ``++chrono++`` library, introduced in {cpp}20, provides support for calendars, time zones, and i/o formatting and parsing operations on time-related objects.
``++chrono++`` is a better alternative to the C/POSIX functions that operate on ``++time_t++``, ``++tm++``, or ``++timespec++`` types. In comparison to C facilities, it provides a better integration with other components of the {cpp} standard library: (``++iostreams++`` and ``++format++``). Also, it supports compile-time computation and it is thread safe.
This rule raises an issue on any use of C/POSIX functions that can be replaced with one of the ``++std::chrono++`` components:
2021-09-20 10:47:24 +02:00
* querying for current time (``++time++``, ``++timespec_get++``, ``++clock_gettime++``)
2021-04-28 16:49:39 +02:00
* date to time-point conversion (``++mktime++``, ``++gmtime++``, ``++localtime++``)
* time serialization (``++ctime++``, ``++asctime++``, ``++strftime++``)
* time parsing (``++strptime++``)
2021-09-20 17:54:02 +02:00
== Noncompliant Code Example
2021-09-20 10:47:24 +02:00
----
int currentMonth() {
std::time_t tp;
std::time(&tp);
std::tm* date = std::gmtime(&tp);
return date->tm_mon + 1;
}
std::chrono::system_clock::time_point makeSomeDay() {
// Creates time_point corresponding to 2020-09-04
std::tm date{};
date.tm_year = 120;
date.tm_mon = 8;
date.tm_mday = 4;
std::time_t t = std::mktime(&date); // Noncompliant
return std::chrono::system_clock::from_time_t(t);
}
std::optional<int> yearOfTimePoint(std::chrono::system_clock::time_point tp) {
std::time_t t = std::chrono::system_clock::to_time_t(tp);
std::tm* date = std::gmtime(&t); // Noncompliant
if (!date)
return std::nullopt;
return date->tm_year + 1900;
}
std::string toIsoString(std::chrono::system_clock::time_point tp) {
std::time_t t = std::chrono::system_clock::to_time_t(tp);
std::tm* date = std::gmtime(&t); // Noncompliant
if (!date)
throw InvalidDate();
std::string buffer(100, ' ');
std::size_t written = std::strftime(buffer.data(), buffer.size(), "%F", date);
buffer.resize(written);
return buffer;
}
----
2021-04-28 18:08:03 +02:00
2021-04-28 16:49:39 +02:00
== Compliant Solution
----
std::chrono::month currentMonth() {
2021-09-20 10:47:24 +02:00
using namespace std::chrono;
auto dp = floor<days>(system_clock::now());
return year_month_day(dp).month();
2021-04-28 16:49:39 +02:00
}
std::chrono::system_clock::time_point makeSomeDay() {
2021-09-20 10:47:24 +02:00
using namespace std::chrono;
2021-09-20 11:09:52 +02:00
return sys_days(2020y/September/4);
2021-04-28 16:49:39 +02:00
}
2021-09-20 10:47:24 +02:00
std::optional<std::chrono::year> yearOfTimePoint(std::chrono::system_clock::time_point tp) {
using namespace std::chrono;
year_month_day date(floor<days>(tp));
if (!date.ok())
return std::nullopt;
return date.year();
2021-04-28 16:49:39 +02:00
}
std::string toIsoString(std::chrono::system_clock::time_point tp) {
2021-09-20 10:47:24 +02:00
return std::format("{:%F}", tp);
2021-04-28 16:49:39 +02:00
}
----
2021-04-28 18:08:03 +02:00