4

我是新手std::chrono,我正在寻找一种简单的方法来构造一个string包含格式为 hhh:mm:ss 的时间间隔(是的,3 小时数字),指示开始时间点和现在之间的差异。

我将如何使用steady_clock? Cppreference 上的示例不太适合这个问题。

4

2 回答 2

7

每当您发现自己在<chrono>库中手动应用单位之间的转换因子时,您应该问自己:

为什么我要手动转换单位?这不是<chrono>应该为我做的吗?!

“转换因子”是 60、1000、100 或其他任何值。如果您在代码中看到它,那么您将面临转换因子错误。

这是 sasha.sochka 在没有这些转换因子的情况下重写的代码。为了说明这种技术的普遍性,为耀斑添加了毫秒:

#include <chrono>
#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>

int main() {
    using namespace std::chrono;
    steady_clock::time_point start;
    steady_clock::time_point now = steady_clock::now();

    auto d = now -start;
    auto hhh = duration_cast<hours>(d);
    d -= hhh;
    auto mm = duration_cast<minutes>(d);
    d -= mm;
    auto ss = duration_cast<seconds>(d);
    d -= ss;
    auto ms = duration_cast<milliseconds>(d);

    std::ostringstream stream;
    stream << std::setfill('0') << std::setw(3) << hhh.count() << ':' <<
        std::setfill('0') << std::setw(2) << mm.count() << ':' << 
        std::setfill('0') << std::setw(2) << ss.count() << '.' <<
        std::setfill('0') << std::setw(3) << ms.count();
    std::string result = stream.str();
    std::cout << result << '\n';
}

在不暴露转换因子的情况下,还有其他方法可以做到这一点,这种方法只是一个示例。我的主要观点是:避免在代码中硬编码单位转换因子。它们容易出错。即使您在第一次编码时就正确了,转换因子也容易受到未来代码维护的影响。<chrono>您可以通过要求所有单位转换都在库中进行,从而使您的代码面向未来。

于 2013-08-02T03:28:48.860 回答
5

正如 Joachim Pileborg 在评论中指出的那样,没有用于从duration对象格式化字符串的函数。但是您可以使用duration_cast将时差先转换为hours然后再minutes转换为seconds

之后使用 C++11to_string函数,您可以将它们连接起来以获取结果字符串。

#include <chrono>
#include <string>
#include <sstream>
#include <iomanip>

int main() {
    using namespace std::chrono;
    steady_clock::time_point start = /* Some point in time */;
    steady_clock::time_point now = steady_clock::now();

    int hhh = duration_cast<hours>(now - start).count();
    int mm = duration_cast<minutes>(now - start).count() % 60;
    int ss = duration_cast<seconds>(now - start).count() % 60;

    std::ostringstream stream;
    stream << std::setfill('0') << std::setw(3) << hhh << ':' <<
        std::setfill('0') << std::setw(2) << mm << ':' << 
        std::setfill('0') << std::setw(2) << ss;
    std::string result = stream.str();

}
于 2013-07-30T11:57:27.570 回答