From ac6dd9f6de06712d16d0ca5c8f56874502820bfb Mon Sep 17 00:00:00 2001 From: Filip Brcic Date: Tue, 18 May 2021 14:45:34 +0200 Subject: [PATCH] Added support for subsecond resolution for time_point and %T or %S formats --- include/fmt/chrono.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index e26e5190..be2bb073 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -412,7 +412,11 @@ struct formatter, auto format(std::chrono::time_point val, FormatContext& ctx) -> decltype(ctx.out()) { std::tm time = localtime(val); - return formatter::format(time, ctx); + auto epoch = val.time_since_epoch(); + auto seconds = std::chrono::duration_cast(epoch).count() / 1000; + auto today = std::chrono::high_resolution_clock::duration(std::chrono::milliseconds(seconds * 1000)); + auto subseconds = std::chrono::duration_cast(epoch - today); + return formatter::format(time, ctx, subseconds.count()); } }; @@ -428,14 +432,20 @@ template struct formatter { } template - auto format(const std::tm& tm, FormatContext& ctx) const + auto format(const std::tm& tm, FormatContext& ctx, int subseconds) const -> decltype(ctx.out()) { basic_memory_buffer tm_format; tm_format.append(specs.begin(), specs.end()); // By appending an extra space we can distinguish an empty result that // indicates insufficient buffer size from a guaranteed non-empty result // https://github.com/fmtlib/fmt/issues/2238 - tm_format.push_back(' '); + auto hasS = std::find(tm_format.begin(), tm_format.end(), 'S') != tm_format.end(); + auto hasT = std::find(tm_format.begin(), tm_format.end(), 'T') != tm_format.end(); + auto writeSubseconds = (hasS || hasT) && (subseconds != 0); + if (writeSubseconds) + tm_format.push_back('.'); + else + tm_format.push_back(' '); tm_format.push_back('\0'); basic_memory_buffer buf; size_t start = buf.size(); @@ -449,6 +459,11 @@ template struct formatter { const size_t MIN_GROWTH = 10; buf.reserve(buf.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH)); } + + if (writeSubseconds) { + buf.append(std::to_string(subseconds)); + } + // Remove the extra space. return std::copy(buf.begin(), buf.end() - 1, ctx.out()); }