【问题标题】:C++ Print days, hours, minutes, etc. of a chrono::durationC++ 打印 chrono::duration 的天数、小时数、分钟数等
【发布时间】:2020-10-02 09:29:12
【问题描述】:

我有以下代码:

// #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(), '\0');

    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 的评论,我已经添加了缺少的内容。

【问题讨论】:

  • 请至少包含sysStartsysEnd的声明

标签: c++ windows chrono


【解决方案1】:

当您无法使用fmtlib 或等待C++20 &lt;format&gt; 时,您至少希望尽可能延迟cout() 的持续时间调用。另外,让&lt;chrono&gt; 为您处理计算。这两种措施都提高了 sn-p 的简洁性:

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);

【讨论】:

  • 糟糕。我错过了std::formatter<std::chrono::duration> 是 C++20 特性的事实。 ;-) 链接的文章似乎仍然不完整。
  • 不错!我特别喜欢实用模板;我已经离开 C++ 循环很长一段时间了,所以甚至不知道你可以做元组之类的东西。谢谢! :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多