Repository: fmtlib/fmt
File: include/fmt/chrono.h (C/C++)

Code before:
  strftime = std::strftime;
  return strftime(str, count, format, time);
}

inline size_t strftime(wchar_t* str, size_t count, const wchar_t* format,
                       const std::tm* time) {
  // See above
  std::size_t (*wcsftime)(wchar_t*, std::size_t, const wchar_t*,
                          const std::tm*) = nullptr;
  wcsftime = std::wcsftime;
  return wcsftime(str, count, format, time);
}

FMT_END_DETAIL_NAMESPACE

template <typename Char, typename Duration>
struct formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
                 Char> : formatter<std::tm, Char> {
  template <typename ParseContext>
  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
    auto it = ctx.begin();
    if (it != ctx.end() && *it == ':') ++it;
    auto end = it;
    while (end != ctx.end() && *end != '}') ++end;
    if (end == it)
      this->specs = {default_spec, 17};
    else
      this->specs = {it, detail::to_unsigned(end - it)};
    return end;
  }

  template <typename FormatContext>
  auto format(std::chrono::time_point<std::chrono::system_clock> val,
              FormatContext& ctx) -> decltype(ctx.out()) {
    std::tm time = localtime(val);
    return formatter<std::tm, Char>::format(time, ctx);
  }
  
  static constexpr Char default_spec[] = {'%', 'Y', '-', '%', 'm', '-',
                                          '%', 'd', ' ', '%', 'H', ':',
                                          '%', 'M', ':', '%', 'S'};
};

template <typename Char> struct formatter<std::tm, Char> {
  template <typename ParseContext>
  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
    auto it = ctx.begin();
    if (it != ctx.end() && *it == ':') ++it;
    auto end = it;
    while (end != ctx.end() && *end != '}') ++end;
    specs = {it, detail::to_unsigned(end - it)};

Review comment (suggestion):
Maybe replace constant ```17``` to ```std::end(default_spec) - std::begin(default_spec)``` ?
```std::begin``` and ```std::end``` functions is ```constexpr``` since C++14.

Code after:
  strftime = std::strftime;
  return strftime(str, count, format, time);
}

inline size_t strftime(wchar_t* str, size_t count, const wchar_t* format,
                       const std::tm* time) {
  // See above
  std::size_t (*wcsftime)(wchar_t*, std::size_t, const wchar_t*,
                          const std::tm*) = nullptr;
  wcsftime = std::wcsftime;
  return wcsftime(str, count, format, time);
}

FMT_END_DETAIL_NAMESPACE

template <typename Char, typename Duration>
struct formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
                 Char> : formatter<std::tm, Char> {
  FMT_CONSTEXPR formatter() {
    this->specs = {default_specs, sizeof(default_specs) / sizeof(Char)};
  }

  template <typename ParseContext>
  FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
    auto it = ctx.begin();
    if (it != ctx.end() && *it == ':') ++it;
    auto end = it;
    while (end != ctx.end() && *end != '}') ++end;
    if (end != it) this->specs = {it, detail::to_unsigned(end - it)};
    return end;
  }

  template <typename FormatContext>
  auto format(std::chrono::time_point<std::chrono::system_clock> val,
              FormatContext& ctx) -> decltype(ctx.out()) {
    std::tm time = localtime(val);
    return formatter<std::tm, Char>::format(time, ctx);
  }

  static constexpr Char default_specs[] = {'%', 'Y', '-', '%', 'm', '-',
                                           '%', 'd', ' ', '%', 'H', ':',
                                           '%', 'M', ':', '%', 'S'};
};

template <typename Char, typename Duration>
constexpr Char
    formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
              Char>::default_specs[];

template <typename Char> struct formatter<std::tm, Char> {
  template <typename ParseContext>