Replace fmt::localtime() with localtime_r() to fix build failure with
fmt 11.2.0. The fmt::localtime() function was deprecated in favor of
std::localtime, causing build errors when treating warnings as errors:
```
[1/2] Building CXX object src/crimson/CMakeFiles/crimson-common.dir/common/formatter.cc.o
/home/kefu/dev/ceph/src/crimson/common/formatter.cc: In member function ‘auto fmt::v11::formatter<std::chrono::time_point<seastar::lowres_system_clock, std::chrono::duration<long int, std::ratio<1,
1000000000> > > >::format(const seastar::lowres_system_clock::time_point&, FormatContext&) const’:
/home/kefu/dev/ceph/src/crimson/common/formatter.cc:28:41: warning: ‘tm fmt::v11::localtime(time_t)’ is deprecated [-Wdeprecated-declarations]
28 | fmt::localtime(tt), milliseconds);
| ~~~~~~~~~~~~~~^~~~
In file included from /home/kefu/dev/ceph/src/fmt/include/fmt/ostream.h:23,
from /home/kefu/dev/ceph/src/seastar/include/seastar/util/backtrace.hh:40,
from /home/kefu/dev/ceph/src/seastar/include/seastar/core/task.hh:25,
from /home/kefu/dev/ceph/src/seastar/include/seastar/core/future.hh:36,
from /home/kefu/dev/ceph/src/seastar/include/seastar/core/timer.hh:24,
from /home/kefu/dev/ceph/src/seastar/include/seastar/core/lowres_clock.hh:26,
from /home/kefu/dev/ceph/src/crimson/common/formatter.h:4,
from /home/kefu/dev/ceph/src/crimson/common/formatter.cc:4:
/home/kefu/dev/ceph/src/fmt/include/fmt/chrono.h:538:28: note: declared here
538 | FMT_DEPRECATED inline auto localtime(std::time_t time) -> std::tm {
| ^~~~~~~~~
```
Unlike other parts of the codebase, this implementation checks the return
value of localtime_r() to preserve the error-handling behavior of
fmt::localtime(), which throws on failure. Future changes may opt for
consistency with the broader codebase over behavioral compatibility.
Signed-off-by: Kefu Chai <tchaikov@gmail.com>
#include "formatter.h"
+#include <chrono>
#include <fmt/format.h>
#if FMT_VERSION >= 60000
#include <fmt/chrono.h>
template <typename FormatContext>
auto format(const seastar::lowres_system_clock::time_point& t,
FormatContext& ctx) const {
- std::time_t tt = std::chrono::duration_cast<std::chrono::seconds>(
- t.time_since_epoch()).count();
- auto milliseconds = (t.time_since_epoch() %
- std::chrono::seconds(1)).count();
- return fmt::format_to(ctx.out(), "{:%Y-%m-%d %H:%M:%S} {:03d}",
- fmt::localtime(tt), milliseconds);
+ auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(
+ t.time_since_epoch() % std::chrono::seconds(1)).count();
+
+ std::time_t time = seastar::lowres_system_clock::to_time_t(t);
+ std::tm tm_local;
+ if (!localtime_r(&time, &tm_local)) {
+ throw fmt::format_error("time_t value out of range");
+ }
+ return fmt::format_to(ctx.out(), "{:%F %T} {:03d}", tm_local, milliseconds);
}
};