将std::duration转换为人类可读时间
Convert std::duration to human readable time
是否有标准实现将std::duration
打印为人类可读的持续时间?
steady_clock::time_point start = steady_clock::now();
doSomeFoo();
steady_clock::time_point end = steady_clock::now();
std::cout << "Operation took "
<< may_be_std::theMagic(start-end) << std::endl;
应该输出类似于:
"Operation took 10d:15h:12m:14:s"
同意没有标准实现。下面是你自己写的方法:
#include <iostream>
#include <iomanip>
#include <chrono>
std::ostream&
display(std::ostream& os, std::chrono::nanoseconds ns)
{
using namespace std;
using namespace std::chrono;
typedef duration<int, ratio<86400>> days;
char fill = os.fill();
os.fill('0');
auto d = duration_cast<days>(ns);
ns -= d;
auto h = duration_cast<hours>(ns);
ns -= h;
auto m = duration_cast<minutes>(ns);
ns -= m;
auto s = duration_cast<seconds>(ns);
os << setw(2) << d.count() << "d:"
<< setw(2) << h.count() << "h:"
<< setw(2) << m.count() << "m:"
<< setw(2) << s.count() << 's';
os.fill(fill);
return os;
};
int
main()
{
std::cout << "Operation took ";
display(std::cout, std::chrono::microseconds(918734000000));
std::cout << 'n';
}
Operation took 10d:15h:12m:14s
根据Howard的回答,我写这篇文章是为了确保只打印出相关的数据,所以120秒变成了2m00s
而不是00d:00h:02m00s
,并确保去掉前导零,所以它仍然是2m00s
而不是02m00s
。
用法很简单:
std::chrono::seconds seconds{60*60*24 + 61};
std::string pretty_seconds = beautify_duration(seconds);
printf("seconds: %s", pretty_seconds.c_str());
>>seconds: 1d00h01m01s
代码:std::string beautify_duration(std::chrono::seconds input_seconds)
{
using namespace std::chrono;
typedef duration<int, std::ratio<86400>> days;
auto d = duration_cast<days>(input_seconds);
input_seconds -= d;
auto h = duration_cast<hours>(input_seconds);
input_seconds -= h;
auto m = duration_cast<minutes>(input_seconds);
input_seconds -= m;
auto s = duration_cast<seconds>(input_seconds);
auto dc = d.count();
auto hc = h.count();
auto mc = m.count();
auto sc = s.count();
std::stringstream ss;
ss.fill('0');
if (dc) {
ss << d.count() << "d";
}
if (dc || hc) {
if (dc) { ss << std::setw(2); } //pad if second set of numbers
ss << h.count() << "h";
}
if (dc || hc || mc) {
if (dc || hc) { ss << std::setw(2); }
ss << m.count() << "m";
}
if (dc || hc || mc || sc) {
if (dc || hc || mc) { ss << std::setw(2); }
ss << s.count() << 's';
}
return ss.str();
}
这个版本允许你使用operator<<它只打印必要的内容,并允许设置所需的精度:
#include <chrono>
#include <iomanip>
#include <optional>
#include <ostream>
std::ostream& operator<<(std::ostream& os, std::chrono::nanoseconds ns)
{
using namespace std::chrono;
using days = duration<int, std::ratio<86400>>;
auto d = duration_cast<days>(ns);
ns -= d;
auto h = duration_cast<hours>(ns);
ns -= h;
auto m = duration_cast<minutes>(ns);
ns -= m;
auto s = duration_cast<seconds>(ns);
ns -= s;
std::optional<int> fs_count;
switch (os.precision()) {
case 9: fs_count = ns.count();
break;
case 6: fs_count = duration_cast<microseconds>(ns).count();
break;
case 3: fs_count = duration_cast<milliseconds>(ns).count();
break;
}
char fill = os.fill('0');
if (d.count())
os << d.count() << "d ";
if (d.count() || h.count())
os << std::setw(2) << h.count() << ":";
if (d.count() || h.count() || m.count())
os << std::setw(d.count() || h.count() ? 2 : 1) << m.count() << ":";
os << std::setw(d.count() || h.count() || m.count() ? 2 : 1) << s.count();
if (fs_count.has_value())
os << "." << std::setw(os.precision()) << fs_count.value();
if (!d.count() && !h.count() && !m.count())
os << "s";
os.fill(fill);
return os;
}
下面是一些用法示例:
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono_literals;
int main()
{
cout << 918734032564785ns << "n";
cout << setprecision(3) << 918734032564785ns << "n";
cout << setprecision(9) << 918734032564785ns << "n";
cout << setprecision(0) << 918734032564785ns << "n";
cout << setprecision(3) << 432034ms << "n";
cout << 14h + 32min + 37s + 645ms << "n";
cout << 86472s << "n";
cout << 4324ms << "n";
return 0;
}
输出:10d 15:12:14.032564
10d 15:12:14.032
10d 15:12:14.032564785
10d 15:12:14
7:12.034
14:32:37.645
1d 00:01:12.000
4.324s
这是一个模板版本,它适用于来自chrono的所有时间单位。
这要归功于我之前的反应者。
template<typename T>
inline std::string format(T timeunit) {
nanoseconds ns = duration_cast<nanoseconds>(timeunit);
std::ostringstream os;
bool foundNonZero = false;
os.fill('0');
typedef duration<int, std::ratio<86400*365>> years;
const auto y = duration_cast<years>(ns);
if (y.count()) {
foundNonZero = true;
os << y.count() << "y:";
ns -= y;
}
typedef duration<int, std::ratio<86400>> days;
const auto d = duration_cast<days>(ns);
if (d.count()) {
foundNonZero = true;
os << d.count() << "d:";
ns -= d;
}
const auto h = duration_cast<hours>(ns);
if (h.count() || foundNonZero) {
foundNonZero = true;
os << h.count() << "h:";
ns -= h;
}
const auto m = duration_cast<minutes>(ns);
if (m.count() || foundNonZero) {
foundNonZero = true;
os << m.count() << "m:";
ns -= m;
}
const auto s = duration_cast<seconds>(ns);
if (s.count() || foundNonZero) {
foundNonZero = true;
os << s.count() << "s:";
ns -= s;
}
const auto ms = duration_cast<milliseconds>(ns);
if (ms.count() || foundNonZero) {
if (foundNonZero) {
os << std::setw(3);
}
os << ms.count() << ".";
ns -= ms;
foundNonZero = true;
}
const auto us = duration_cast<microseconds>(ns);
if (us.count() || foundNonZero) {
if (foundNonZero) {
os << std::setw(3);
}
os << us.count() << ".";
ns -= us;
}
os << std::setw(3) << ns.count() << "ns" ;
return os.str();
}
输出:59y:325d:20h:33m:19s:008.800.999ns
20d:13h:53m:19s:008.800.999ns
33m:19s:008.800.999ns
1s:000.000.999ns
1.000.099ns
10.000ns
100ns
没有,没有标准实现。您可以通过std::put_time获得std::chrono::time_point的人类可读版本,但不能使用std::chrono::duration。
相关文章:
- C++为构建时间获取QDateTime的可靠方法
- 从持续时间构造std::chrono::system_clock::time_point
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- while循环中while循环的时间复杂度是多少
- 使用简单类型列表实现的指数编译时间.为什么
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在已经使用Git的情况下减少编译时间
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 从文本文件中读取时钟时间和事件时间并进行处理
- 具有未知值时的时间复杂性
- 如何减少花费的时间
- C++在变量给定的指定时间内关闭电脑
- rcpp函数中的清理时间很长
- 将 unix 时间戳转换为人类可读的日期
- 如何将包含 64 位纪元时间的字符串转换为人类可读格式
- 将UTC毫秒转换为人类可读日期时间
- 提高简单的人类可读的日期时间
- c++时间戳到人类可读的datetime函数
- 将std::duration转换为人类可读时间