@@ -265,6 +265,9 @@ using utc_time = std::chrono::time_point<detail::utc_clock, Duration>;
265265template <class Duration >
266266using local_time = std::chrono::time_point<detail::local_t , Duration>;
267267
268+ template <typename Duration, typename TimeZonePtr>
269+ using zoned_time = std::chrono::zoned_time<Duration, TimeZonePtr>;
270+
268271namespace detail {
269272
270273// Prevents expansion of a preceding token as a function-style macro.
@@ -2240,6 +2243,41 @@ struct formatter<local_time<Duration>, Char>
22402243 }
22412244};
22422245
2246+ template <typename Duration, typename TimeZonePtr, typename Char>
2247+ struct formatter <zoned_time<Duration, TimeZonePtr>, Char,
2248+ std::enable_if_t <std::is_pointer_v<TimeZonePtr>>>
2249+ : private formatter<std::tm, Char> {
2250+ FMT_CONSTEXPR auto parse (parse_context<Char>& ctx) -> const Char* {
2251+ return this ->do_parse (ctx, true );
2252+ }
2253+
2254+ template <typename FormatContext>
2255+ auto format (const std::chrono::zoned_time<Duration, TimeZonePtr>& val,
2256+ FormatContext& ctx) const -> decltype(ctx.out()) {
2257+ auto time_info = val.get_info ();
2258+ auto time_since_epoch = val.get_local_time ().time_since_epoch ();
2259+ auto seconds_since_epoch =
2260+ detail::duration_cast<std::chrono::seconds>(time_since_epoch);
2261+ std::time_t time_val = seconds_since_epoch.count ();
2262+ // Use gmtime to prevent time zone conversion since local_time has an
2263+ // unspecified time zone.
2264+ std::tm t = gmtime (time_val);
2265+ // Create a custom tm with timezone info if supported
2266+ if constexpr (detail::has_tm_zone<std::tm>::value) {
2267+ t.tm_zone = time_info.abbrev .c_str ();
2268+ t.tm_gmtoff = time_info.offset .count ();
2269+ }
2270+ using period = typename Duration::period;
2271+ if (period::num == 1 && period::den == 1 &&
2272+ !std::is_floating_point<typename Duration::rep>::value) {
2273+ return formatter<std::tm, Char>::format (t, ctx);
2274+ }
2275+ auto subsecs =
2276+ detail::duration_cast<Duration>(time_since_epoch - seconds_since_epoch);
2277+ return formatter<std::tm, Char>::do_format (t, ctx, &subsecs);
2278+ }
2279+ };
2280+
22432281FMT_END_EXPORT
22442282FMT_END_NAMESPACE
22452283
0 commit comments