Skip to content

Commit

Permalink
Cleanup chrono formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaut committed Aug 18, 2024
1 parent 89af1ad commit 03ef52e
Showing 1 changed file with 33 additions and 29 deletions.
62 changes: 33 additions & 29 deletions include/fmt/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@ template <typename... T> inline void _tzset(T...) {}

FMT_BEGIN_NAMESPACE

// Check if std::chrono::local_t is available.
#ifndef FMT_USE_LOCAL_TIME
# ifdef __cpp_lib_chrono
# define FMT_USE_LOCAL_TIME (__cpp_lib_chrono >= 201907L)
# else
# define FMT_USE_LOCAL_TIME 0
# endif
#endif

// Enable safe chrono durations, unless explicitly disabled.
#ifndef FMT_SAFE_DURATION_CAST
# define FMT_SAFE_DURATION_CAST 1
Expand Down Expand Up @@ -263,6 +254,20 @@ struct utc_clock {
};
#endif

// Check if std::chrono::local_time is available.
#ifdef FMT_USE_LOCAL_TIME
// Use the provided definition.
#elif defined(__cpp_lib_chrono)
# define FMT_USE_LOCAL_TIME (__cpp_lib_chrono >= 201907L)
#else
# define FMT_USE_LOCAL_TIME 0
#endif
#if FMT_USE_LOCAL_TIME
using local_t = std::chrono::local_t;
#else
struct local_t {};
#endif

} // namespace detail

template <typename Duration>
Expand All @@ -271,6 +276,9 @@ using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
template <typename Duration>
using utc_time = std::chrono::time_point<detail::utc_clock, Duration>;

template <class Duration>
using local_time = std::chrono::time_point<detail::local_t, Duration>;

namespace detail {

// Prevents expansion of a preceding token as a function-style macro.
Expand Down Expand Up @@ -2377,42 +2385,38 @@ struct formatter<sys_time<Duration>, Char> : formatter<std::tm, Char> {
}
};

#if FMT_USE_LOCAL_TIME
template <typename Char, typename Duration>
struct formatter<std::chrono::local_time<Duration>, Char>
: formatter<std::tm, Char> {
template <typename Duration, typename Char>
struct formatter<utc_time<Duration>, Char>
: formatter<sys_time<Duration>, Char> {
template <typename FormatContext>
auto format(utc_time<Duration> val, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<sys_time<Duration>, Char>::format(
detail::utc_clock::to_sys(val), ctx);
}
};

template <typename Duration, typename Char>
struct formatter<local_time<Duration>, Char> : formatter<std::tm, Char> {
FMT_CONSTEXPR formatter() {
this->format_str_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();
}

template <typename FormatContext>
auto format(std::chrono::local_time<Duration> val, FormatContext& ctx) const
auto format(local_time<Duration> val, FormatContext& ctx) const
-> decltype(ctx.out()) {
using period = typename Duration::period;
if (period::num != 1 || period::den != 1 ||
std::is_floating_point<typename Duration::rep>::value) {
const auto epoch = val.time_since_epoch();
const auto subsecs = detail::duration_cast<Duration>(
auto epoch = val.time_since_epoch();
auto subsecs = detail::duration_cast<Duration>(
epoch - detail::duration_cast<std::chrono::seconds>(epoch));

return formatter<std::tm, Char>::do_format(localtime(val), ctx, &subsecs);
}

return formatter<std::tm, Char>::format(localtime(val), ctx);
}
};
#endif

template <typename Char, typename Duration>
struct formatter<utc_time<Duration>, Char>
: formatter<sys_time<Duration>, Char> {
template <typename FormatContext>
auto format(utc_time<Duration> val, FormatContext& ctx) const
-> decltype(ctx.out()) {
return formatter<sys_time<Duration>, Char>::format(
detail::utc_clock::to_sys(val), ctx);
}
};

FMT_END_EXPORT
FMT_END_NAMESPACE
Expand Down

0 comments on commit 03ef52e

Please sign in to comment.