I am using gcc-13.3
with c++23
enabled.
I have the following code which uses std::format
to format a std::chrono::year_month_day
to a string:
#include <chrono>
#include <format>
#include <iostream>
int main()
{
const std::chrono::time_point now {std::chrono::system_clock::now()};
const std::chrono::year_month_day ymd {std::chrono::floor<std::chrono::days>(now)};
std::cout << std::format("{}", ymd) << '\n';
return 0;
}
This works as expected.
Now I want to replace std::format
with libfmt
. (I have fmtlib-11.2.0
installed.)
#include <fmt/chrono.h>
#include <fmt/core.h>
#include <chrono>
#include <iostream>
int main()
{
const std::chrono::time_point now {std::chrono::system_clock::now()};
const std::chrono::year_month_day ymd {std::chrono::floor<std::chrono::days>(now)};
std::cout << fmt::format("{}", ymd) << '\n';
return 0;
}
This fails to compile:
/usr/local/include/fmt/base.h:2262:45: error: \
‘fmt::v11::detail::type_is_unformattable_for< \
std::chrono::year_month_day, char> _’ has incomplete type
2262 | type_is_unformattable_for<T, char_type> _;
I was (perhaps incorrectly?) under the impression that std::chrono
types are directly formattable with fmtlib
.
In addition, I can see formatter
specialisations in fmt/chrono.h
which I have included.
$ grep year_month_day /usr/local/include/include/fmt/chrono.h
using year_month_day = std::chrono::year_month_day;
class year_month_day {
year_month_day() = default;
constexpr year_month_day(const year& y, const month& m, const day& d) noexcept
struct formatter<year_month_day, Char> : private formatter<std::tm, Char> {
auto format(year_month_day val, FormatContext& ctx) const
fmtlib
to log std::chrono::year_month_day
directly?{fmt} uses the __cpp_lib_chrono
feature-test macro to detect if chrono types are available. For std::chrono::year_month_day
, which is a C++20 feature, it checks if the standard library sets this macro to 201907
or higher. One possible reason for it to not be set or set to a lower value is that you are compiling with an older standard. It is also possible that the standard library sets this macro to a lower value if it only provides a partial implementation of C++20 chrono features.
Your example works on godbolt with gcc 15.1 (and a corresponding version of libstdc++) and -std=c++20
: https://www.godbolt.org/z/o5fxEGMdn.