【问题标题】:Most simple way to get string containing time interval获取包含时间间隔的字符串的最简单方法
【发布时间】:2013-07-30 11:43:38
【问题描述】:

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

我将如何使用steady_clock 来解决这个问题? examples on Cppreference 不太适合这个问题。

【问题讨论】:

  • 时时时:分分:秒秒
  • 不幸的是,没有任何函数可以格式化来自 duration 对象的字符串。您可能不得不求助于以秒为单位获取持续时间,然后使用算术从该持续时间中获取秒、分钟和小时,并根据这些数字手动格式化字符串。

标签: c++ c++11 chrono


【解决方案1】:

每当您发现自己使用 <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';
}

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

【讨论】:

    【解决方案2】:

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

    之后使用 C++11 to_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();
    
    }
    

    【讨论】:

    • 这是我链接中示例中最合乎逻辑的。我只是希望有一种方法可以使用put_time 之类的东西。没关系。 +1 :)
    • @learnvst,注意我这里修正了一个错误,我使用了3次hours作为模板参数。
    • @learnvst 如果您想专门格式化数字,您可以使用std::ostringstream 和正常的输出流格式化操纵器轻松完成。
    • @JoachimPileborg,我更新为使用固定宽度输出数字的 ostringstream。
    • 你也可以直接使用operator%和durations,见example at cppreference
    猜你喜欢
    • 1970-01-01
    • 2013-11-12
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 2011-06-08
    相关资源
    最近更新 更多