我正在编写一个以ISO格式返回当前时间的实用程序函数。但是,我希望能够指定精度:
2017-04-28T15:07:37Z //s
2017-04-28T15:07:37.035Z //ms
2017-04-28T15:07:37.035332Z //us
我有工作代码来执行此操作,但是,我似乎无法找到使其通用的方法:
string getISOCurrentTimestamp_us()
{
char iso_buf[30];
auto now = chrono::high_resolution_clock::now();
auto s = chrono::duration_cast<chrono::seconds>(now.time_since_epoch());
time_t seconds = (time_t) s.count();
strftime(iso_buf, sizeof(iso_buf), "%FT%T", gmtime(&seconds));
string iso_timestamp(iso_buf);
auto us = chrono::duration_cast<chrono::microseconds>(now.time_since_epoch());
auto us_diff = us - chrono::duration_cast<chrono::microseconds>(s);
char buffer[8];
std::snprintf(buffer, sizeof(buffer), ".%06d", (int) us_diff.count());
iso_timestamp += string(buffer);
iso_timestamp += "Z";
return iso_timestamp;
}
如您所见,这个只返回微秒版本。我有一个单独的函数使用chrono:milliseconds
作为毫秒版本。当唯一的区别是持续时间模板参数和零填充时,似乎DRY违规具有如此多的类似代码。
然而,能够指定持续时间是棘手的。我想我不太了解函数模板,因为我尝试了类似getISOCurrentTimestamp<chrono::microseconds>()
的东西,但无济于事:
template <class T>
string getISOCurrentTimestamp() {
...
auto t = chrono::duration_cast<T>(now.time_since_epoch());
auto t_diff = t - chrono::duration_cast<T>(s);
}
另一个问题是推断基于T
的零填充量,这似乎也不是微不足道的(即微秒应该零填充到6,毫秒到3,等等。
如何使这个ISO字符串函数通用?我是以错误的方式接近这个吗?
编辑:使用@ HowardHinnant的库,我能够编写一个通用的包装器:
template <class Precision>
string getISOCurrentTimestamp()
{
auto now = chrono::system_clock::now();
return date::format("%FT%TZ", date::floor<Precision>(now));
}
使用:
调用 string timestamp = getISOCurrentTimestamp<chrono::seconds>()
答案 0 :(得分:3)
此free, open-source, header-only library通过调整输入chrono::time_point
函数的format
的精度来实现此目的。随意检查代码,看看如何完成。我认为您对decimal_format_seconds
特别感兴趣,{{3}}负责计算输出的小数位数(如果有的话)。或者随意使用此代码。
以下是使用它的内容:
#include "date.h"
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
using namespace date;
system_clock::time_point now = sys_days{2017_y/04/28} + 15h + 7min + 37s + 35332us;
cout << format("%FT%TZ\n", floor<seconds>(now));
cout << format("%FT%TZ\n", floor<milliseconds>(now));
cout << format("%FT%TZ\n", floor<microseconds>(now));
}
输出:
2017-04-28T15:07:37Z
2017-04-28T15:07:37.035Z
2017-04-28T15:07:37.035332Z