I am writing a utility function that returns the current time in ISO format. However, I would like to be able to specify the precision:
2017-04-28T15:07:37Z //s
2017-04-28T15:07:37.035Z //ms
2017-04-28T15:07:37.035332Z //us
I have working code to do this, however, I can't seem to find a way to make it generic:
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;
}
As you can see, this one only returns the microsecond version. I have a separate function using chrono:milliseconds
for the millisecond version. Seems like a DRY violation to have so much similar code when the only difference is the duration template parameter and the zero-padding.
Yet being able to specify the duration is tricky. I think I'm not quite understanding function templates, because I tried something like getISOCurrentTimestamp<chrono::microseconds>()
, to no avail:
template <class T>
string getISOCurrentTimestamp() {
...
auto t = chrono::duration_cast<T>(now.time_since_epoch());
auto t_diff = t - chrono::duration_cast<T>(s);
}
Another problem is deducing the amount of zero padding based on T
which doesn't seem trivial either (i.e. microseconds should be zero-padded up to 6, milliseconds up to 3, etc.
How can I make this ISO String function generic? Am I approaching this the wrong way?
Aucun commentaire:
Enregistrer un commentaire