Reputation: 16409
This code
#include <chrono>
#include <fmt/format.h>
#include <fmt/chrono.h>
...
auto now = std::chrono::system_clock::now();
fmt::print("The time is: {:%Y-%m-%d %H:%M:%S}\n", now);
Prints this:
The time is: 2023-01-02 15:51:23
How do I get it to print sub-second precision, for example, milliseconds? Something like:
The time is: 2023-01-02 15:51:23.753
Upvotes: 4
Views: 1984
Reputation: 397
Just share my way to output fractional seconds in logging:
std::string Timestamp() {
namespace c = std::chrono;
auto tp = c::time_point_cast<c::microseconds>(c::system_clock::now());
auto us = tp.time_since_epoch().count() % std::micro::den;
return fmt::format("{:%Y-%m-%d_%H:%M:%S}.{:06d}", tp, us);
}
There is a pull request to output fractional seconds for formatting time_point
, (but closed, the author did not continue the work):
https://github.com/fmtlib/fmt/pull/2292
My concern is that change %S
to include fractional part is some-what breaking change (strftime
defines it as seconds from 00
to 60
). I hope fmtlib
would consider some other way to tackle this requirement.
Upvotes: 2
Reputation: 368261
I think you have to do this in two steps -- YMD and HM followed by the high-res seconds. Here is a worked example, using fmt
version 9.0 on Ubuntu:
#include <chrono>
#include <fmt/format.h>
#include <fmt/chrono.h>
int main() {
auto now = std::chrono::system_clock::now();
auto sse = now.time_since_epoch();
fmt::print("{:%FT%H:%M:}{:%S}\n", now, sse);
exit(0);
}
for which I get
$ g++ -o answer answer.cpp -lfmt; ./answer
2023-01-02T16:26:17.009359309
$
(Initial, earlier, slightly off attempt to reason based on spdlog
follows. But spdlog
wraps fmt
and overlays its format.)
It is on the format page, you want something like %Y-%m-%d %H:%M:%S.%e
. Note that %e
, %f
and %F
give you milli, micro and nanoseconds. Edit: That was the spdlog format though.
Here is a quick example, for simplicity from my R package RcppSpdlog accessing fmt via spdlog:
> library(RcppSpdlog)
> RcppSpdlog::log_set_pattern("[%Y-%m-%d %H:%M:%S.%f] [%L] %v")
> RcppSpdlog::log_warn("Hello")
[2023-01-02 15:00:49.746031] [W] Hello
> RcppSpdlog::log_set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%L] %v")
> RcppSpdlog::log_warn("World")
[2023-01-02 15:01:02.137] [W] World
>
Note the display of micro- and milliseconds as stated.
Edit: There is something else going on with your example. Here is a simplified answer, printing only seconds and it comes by default fractionally down to nanoseconds (for me on Linux):
$ cat answer.cpp
#include <chrono>
#include <fmt/format.h>
#include <fmt/chrono.h>
int main() {
fmt::print("{:%S}\n", std::chrono::system_clock::now().time_since_epoch());
exit(0);
}
$ g++ -o answer answer.cpp -lfmt
$ ./answer
02.461241690
$
Upvotes: 7