C++ 打印 chrono::duration 的天、小时、分钟等
C++ Print days, hours, minutes, etc. of a chrono::duration
我有以下代码:
// #includes for <chrono>, <iostream>, etc.
using namespace std;
using namespace chrono;
int main(int argc, char* argv[]) {
auto sysStart = system_clock::now();
LogInit(); // Opens a log file for reading/writing
// Last shutdown time log entry is marked by a preceding null byte
logFile.ignore(numeric_limits<streamsize>::max(), '[=11=]');
if (logFile.fail() || logFile.bad()) {
// Calls GetLastError() and logs the error code and message
LogError("main");
}
// Parse the timestamp at the start of the shutdown log entry
tm end = { 0 };
logFile >> get_time(&end, "[%d-%m-%Y %T");
if (logFile.fail() || logFile.bad()) {
// Same as above. Param is name of function within which error occurred
LogError("main");
}
// Finally, we have the last shutdown time as a chrono::time_point
auto sysEnd = system_clock::from_time_t(mktime(&end));
// Calculate the time for which the system was inactive
auto sysInactive = sysStart - sysEnd;
auto hrs = duration_cast<hours>(sysInactive).count();
auto mins = duration_cast<minutes>(sysInactive).count() - hrs * 60;
auto secs = duration_cast<seconds>(sysInactive).count() - (hrs * 3600) - mins * 60;
auto ms = duration_cast<milliseconds>(sysInactive).count() - (hrs * 3600000)
- (mins * 60000) - secs * 1000;
return 0;
}
它可以工作,但它非常难看,而且对我来说太冗长了。 仅使用 STL 函数有更简单的方法吗? MTIA :-)
编辑:我意识到完整的代码毕竟不是那么复杂,所以根据@idclev463035818 的评论,我添加了缺少的内容。
当您不能使用 fmtlib 或等待 C++20 <format>
时,您至少要尽可能延迟对持续时间的 cout()
调用。另外,让 <chrono>
为您处理计算。这两项措施都提高了代码段的简洁性:
const auto hrs = duration_cast<hours>(sysInactive);
const auto mins = duration_cast<minutes>(sysInactive - hrs);
const auto secs = duration_cast<seconds>(sysInactive - hrs - mins);
const auto ms = duration_cast<milliseconds>(sysInactive - hrs - secs);
并且输出:
cout << "System inactive for " << hrs.count() <<
":" << mins.count() <<
":" << secs.count() <<
"." << ms.count() << endl;
请注意,您还可以定义实用程序模板,
template <class Rep, std::intmax_t num, std::intmax_t denom>
auto chronoBurst(std::chrono::duration<Rep, std::ratio<num, denom>> d)
{
const auto hrs = duration_cast<hours>(d);
const auto mins = duration_cast<minutes>(d - hrs);
const auto secs = duration_cast<seconds>(d - hrs - mins);
const auto ms = duration_cast<milliseconds>(d - hrs - secs);
return std::make_tuple(hrs, mins, secs, ms);
}
结合结构化绑定有一个很好的用例:
const auto [hrs, mins, secs, ms] = chronoBurst(sysInactive);
我有以下代码:
// #includes for <chrono>, <iostream>, etc.
using namespace std;
using namespace chrono;
int main(int argc, char* argv[]) {
auto sysStart = system_clock::now();
LogInit(); // Opens a log file for reading/writing
// Last shutdown time log entry is marked by a preceding null byte
logFile.ignore(numeric_limits<streamsize>::max(), '[=11=]');
if (logFile.fail() || logFile.bad()) {
// Calls GetLastError() and logs the error code and message
LogError("main");
}
// Parse the timestamp at the start of the shutdown log entry
tm end = { 0 };
logFile >> get_time(&end, "[%d-%m-%Y %T");
if (logFile.fail() || logFile.bad()) {
// Same as above. Param is name of function within which error occurred
LogError("main");
}
// Finally, we have the last shutdown time as a chrono::time_point
auto sysEnd = system_clock::from_time_t(mktime(&end));
// Calculate the time for which the system was inactive
auto sysInactive = sysStart - sysEnd;
auto hrs = duration_cast<hours>(sysInactive).count();
auto mins = duration_cast<minutes>(sysInactive).count() - hrs * 60;
auto secs = duration_cast<seconds>(sysInactive).count() - (hrs * 3600) - mins * 60;
auto ms = duration_cast<milliseconds>(sysInactive).count() - (hrs * 3600000)
- (mins * 60000) - secs * 1000;
return 0;
}
它可以工作,但它非常难看,而且对我来说太冗长了。 仅使用 STL 函数有更简单的方法吗? MTIA :-)
编辑:我意识到完整的代码毕竟不是那么复杂,所以根据@idclev463035818 的评论,我添加了缺少的内容。
当您不能使用 fmtlib 或等待 C++20 <format>
时,您至少要尽可能延迟对持续时间的 cout()
调用。另外,让 <chrono>
为您处理计算。这两项措施都提高了代码段的简洁性:
const auto hrs = duration_cast<hours>(sysInactive);
const auto mins = duration_cast<minutes>(sysInactive - hrs);
const auto secs = duration_cast<seconds>(sysInactive - hrs - mins);
const auto ms = duration_cast<milliseconds>(sysInactive - hrs - secs);
并且输出:
cout << "System inactive for " << hrs.count() <<
":" << mins.count() <<
":" << secs.count() <<
"." << ms.count() << endl;
请注意,您还可以定义实用程序模板,
template <class Rep, std::intmax_t num, std::intmax_t denom>
auto chronoBurst(std::chrono::duration<Rep, std::ratio<num, denom>> d)
{
const auto hrs = duration_cast<hours>(d);
const auto mins = duration_cast<minutes>(d - hrs);
const auto secs = duration_cast<seconds>(d - hrs - mins);
const auto ms = duration_cast<milliseconds>(d - hrs - secs);
return std::make_tuple(hrs, mins, secs, ms);
}
结合结构化绑定有一个很好的用例:
const auto [hrs, mins, secs, ms] = chronoBurst(sysInactive);