%!TEX root = std.tex
\rSec0[time]{Time library}

\rSec1[time.general]{General}

\pnum
\indexlibraryglobal{chrono}%
This Clause describes the chrono library\iref{time.syn} and various C
functions\iref{ctime.syn} that provide generally useful time
utilities, as summarized in \tref{time.summary}.

\begin{libsumtab}{Time library summary}{time.summary}
\ref{time.clock.req}        & \oldconcept{Clock} requirements    & \\ \rowsep
\ref{time.traits}           & Time-related traits                & \tcode{<chrono>} \\
\ref{time.duration}         & Class template \tcode{duration}    & \\
\ref{time.point}            & Class template \tcode{time_point}  & \\
\ref{time.clock}            & Clocks                             & \\
\ref{time.cal}              & Civil calendar                     & \\
\ref{time.hms}              & Class template \tcode{hh_mm_ss}    & \\
\ref{time.12}               & 12/24 hour functions               & \\
\ref{time.zone}             & Time zones                         & \\
\ref{time.format}           & Formatting                         & \\
\ref{time.parse}            & Parsing                            & \\
\ref{time.hash}             & Hash support                       & \\ \rowsep
\ref{ctime.syn}             & C library time utilities           & \tcode{<ctime>} \\
\end{libsumtab}

\rSec1[time.syn]{Header \tcode{<chrono>} synopsis}

\indexheader{chrono}%
\indexlibraryglobal{treat_as_floating_point_v}%
\indexlibraryglobal{is_clock_v}%
\indexlibraryglobal{nanoseconds}%
\indexlibraryglobal{microseconds}%
\indexlibraryglobal{milliseconds}%
\indexlibraryglobal{seconds}%
\indexlibraryglobal{minutes}%
\indexlibraryglobal{hours}%
\indexlibraryglobal{days}%
\indexlibraryglobal{weeks}%
\indexlibraryglobal{years}%
\indexlibraryglobal{months}%
\indexlibraryglobal{sys_time}%
\indexlibraryglobal{sys_seconds}%
\indexlibraryglobal{sys_days}%
\indexlibraryglobal{utc_time}%
\indexlibraryglobal{utc_seconds}%
\indexlibraryglobal{tai_time}%
\indexlibraryglobal{tai_seconds}%
\indexlibraryglobal{gps_time}%
\indexlibraryglobal{gps_seconds}%
\indexlibraryglobal{file_time}%
\indexlibraryglobal{local_time}%
\indexlibraryglobal{local_seconds}%
\indexlibraryglobal{local_days}%
\indexlibraryglobal{local_t}%
\indexlibraryglobal{choose}%
\indexlibrarymember{earliest}{choose}%
\indexlibrarymember{latest}{choose}%
\begin{codeblock}
#include <compare>              // see \ref{compare.syn}

namespace std::chrono {
  // \ref{time.duration}, class template \tcode{duration}
  template<class Rep, class Period = ratio<1>> class duration;

  // \ref{time.point}, class template \tcode{time_point}
  template<class Clock, class Duration = typename Clock::duration> class time_point;
}

namespace std {
  // \ref{time.traits.specializations}, \tcode{common_type} specializations
  template<class Rep1, class Period1, class Rep2, class Period2>
    struct common_type<chrono::duration<Rep1, Period1>,
                       chrono::duration<Rep2, Period2>>;

  template<class Clock, class Duration1, class Duration2>
    struct common_type<chrono::time_point<Clock, Duration1>,
                       chrono::time_point<Clock, Duration2>>;
}

namespace std::chrono {
  // \ref{time.traits}, customization traits
  template<class Rep> struct treat_as_floating_point;
  template<class Rep>
    constexpr bool treat_as_floating_point_v = treat_as_floating_point<Rep>::value;

  template<class Rep> struct duration_values;

  template<class T> struct is_clock;
  template<class T> constexpr bool is_clock_v = is_clock<T>::value;

  // \ref{time.duration.nonmember}, \tcode{duration} arithmetic
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period, class Rep2>
    constexpr duration<common_type_t<Rep1, Rep2>, Period>
      operator*(const duration<Rep1, Period>& d, const Rep2& s);
  template<class Rep1, class Rep2, class Period>
    constexpr duration<common_type_t<Rep1, Rep2>, Period>
      operator*(const Rep1& s, const duration<Rep2, Period>& d);
  template<class Rep1, class Period, class Rep2>
    constexpr duration<common_type_t<Rep1, Rep2>, Period>
      operator/(const duration<Rep1, Period>& d, const Rep2& s);
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr common_type_t<Rep1, Rep2>
      operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period, class Rep2>
    constexpr duration<common_type_t<Rep1, Rep2>, Period>
      operator%(const duration<Rep1, Period>& d, const Rep2& s);
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
      operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);

  // \ref{time.duration.comparisons}, \tcode{duration} comparisons
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator==(const duration<Rep1, Period1>& lhs,
                              const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator< (const duration<Rep1, Period1>& lhs,
                              const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator> (const duration<Rep1, Period1>& lhs,
                              const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
                              const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period1, class Rep2, class Period2>
    constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
                              const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period1, class Rep2, class Period2>
    requires @\seebelow@
    constexpr auto operator<=>(const duration<Rep1, Period1>& lhs,
                               const duration<Rep2, Period2>& rhs);

  // \ref{time.duration.cast}, conversions
  template<class ToDuration, class Rep, class Period>
    constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
  template<class ToDuration, class Rep, class Period>
    constexpr ToDuration floor(const duration<Rep, Period>& d);
  template<class ToDuration, class Rep, class Period>
    constexpr ToDuration ceil(const duration<Rep, Period>& d);
  template<class ToDuration, class Rep, class Period>
    constexpr ToDuration round(const duration<Rep, Period>& d);

  // \ref{time.duration.io}, \tcode{duration} I/O
  template<class charT, class traits, class Rep, class Period>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os,
                 const duration<Rep, Period>& d);
  template<class charT, class traits, class Rep, class Period, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  duration<Rep, Period>& d,
                  basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // convenience typedefs
  using nanoseconds  = duration<@\placeholder{signed integer type of at least 64 bits}@, nano>;
  using microseconds = duration<@\placeholder{signed integer type of at least 55 bits}@, micro>;
  using milliseconds = duration<@\placeholder{signed integer type of at least 45 bits}@, milli>;
  using seconds      = duration<@\placeholder{signed integer type of at least 35 bits}@>;
  using minutes      = duration<@\placeholder{signed integer type of at least 29 bits}@, ratio<  60>>;
  using hours        = duration<@\placeholder{signed integer type of at least 23 bits}@, ratio<3600>>;
  using days         = duration<@\placeholder{signed integer type of at least 25 bits}@,
                                ratio_multiply<ratio<24>, hours::period>>;
  using weeks        = duration<@\placeholder{signed integer type of at least 22 bits}@,
                                ratio_multiply<ratio<7>, days::period>>;
  using years        = duration<@\placeholder{signed integer type of at least 17 bits}@,
                                ratio_multiply<ratio<146097, 400>, days::period>>;
  using months       = duration<@\placeholder{signed integer type of at least 20 bits}@,
                                ratio_divide<years::period, ratio<12>>>;

  // \ref{time.point.nonmember}, \tcode{time_point} arithmetic
  template<class Clock, class Duration1, class Rep2, class Period2>
    constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
      operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
  template<class Rep1, class Period1, class Clock, class Duration2>
    constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
      operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
  template<class Clock, class Duration1, class Rep2, class Period2>
    constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
      operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
  template<class Clock, class Duration1, class Duration2>
    constexpr common_type_t<Duration1, Duration2>
      operator-(const time_point<Clock, Duration1>& lhs,
                const time_point<Clock, Duration2>& rhs);

  // \ref{time.point.comparisons}, \tcode{time_point} comparisons
  template<class Clock, class Duration1, class Duration2>
    constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
                              const time_point<Clock, Duration2>& rhs);
  template<class Clock, class Duration1, class Duration2>
    constexpr bool operator< (const time_point<Clock, Duration1>& lhs,
                              const time_point<Clock, Duration2>& rhs);
  template<class Clock, class Duration1, class Duration2>
    constexpr bool operator> (const time_point<Clock, Duration1>& lhs,
                              const time_point<Clock, Duration2>& rhs);
  template<class Clock, class Duration1, class Duration2>
    constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
                              const time_point<Clock, Duration2>& rhs);
  template<class Clock, class Duration1, class Duration2>
    constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
                              const time_point<Clock, Duration2>& rhs);
  template<class Clock, class Duration1, @\libconcept{three_way_comparable_with}@<Duration1> Duration2>
    constexpr auto operator<=>(const time_point<Clock, Duration1>& lhs,
                               const time_point<Clock, Duration2>& rhs);

  // \ref{time.point.cast}, conversions
  template<class ToDuration, class Clock, class Duration>
    constexpr time_point<Clock, ToDuration>
      time_point_cast(const time_point<Clock, Duration>& t);
  template<class ToDuration, class Clock, class Duration>
    constexpr time_point<Clock, ToDuration> floor(const time_point<Clock, Duration>& tp);
  template<class ToDuration, class Clock, class Duration>
    constexpr time_point<Clock, ToDuration> ceil(const time_point<Clock, Duration>& tp);
  template<class ToDuration, class Clock, class Duration>
    constexpr time_point<Clock, ToDuration> round(const time_point<Clock, Duration>& tp);

  // \ref{time.duration.alg}, specialized algorithms
  template<class Rep, class Period>
    constexpr duration<Rep, Period> abs(duration<Rep, Period> d);

  // \ref{time.clock.system}, class \tcode{system_clock}
  class system_clock;

  template<class Duration>
    using sys_time  = time_point<system_clock, Duration>;
  using sys_seconds = sys_time<seconds>;
  using sys_days    = sys_time<days>;

  template<class charT, class traits, class Duration>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const sys_time<Duration>& tp);

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const sys_days& dp);

  template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  sys_time<Duration>& tp,
                  basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.clock.utc}, class \tcode{utc_clock}
  class utc_clock;

  template<class Duration>
    using utc_time  = time_point<utc_clock, Duration>;
  using utc_seconds = utc_time<seconds>;

  template<class charT, class traits, class Duration>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const utc_time<Duration>& t);
  template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  utc_time<Duration>& tp,
                  basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  struct leap_second_info;

  template<class Duration>
    leap_second_info get_leap_second_info(const utc_time<Duration>& ut);

  // \ref{time.clock.tai}, class \tcode{tai_clock}
  class tai_clock;

  template<class Duration>
    using tai_time  = time_point<tai_clock, Duration>;
  using tai_seconds = tai_time<seconds>;

  template<class charT, class traits, class Duration>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const tai_time<Duration>& t);
  template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  tai_time<Duration>& tp,
                  basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.clock.gps}, class \tcode{gps_clock}
  class gps_clock;

  template<class Duration>
    using gps_time  = time_point<gps_clock, Duration>;
  using gps_seconds = gps_time<seconds>;

  template<class charT, class traits, class Duration>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const gps_time<Duration>& t);
  template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  gps_time<Duration>& tp,
                  basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.clock.file}, type \tcode{file_clock}
  using file_clock = @\seebelow@;

  template<class Duration>
    using file_time = time_point<file_clock, Duration>;

  template<class charT, class traits, class Duration>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const file_time<Duration>& tp);
  template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  file_time<Duration>& tp,
                  basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.clock.steady}, class \tcode{steady_clock}
  class steady_clock;

  // \ref{time.clock.hires}, class \tcode{high_resolution_clock}
  class high_resolution_clock;

  // \ref{time.clock.local}, local time
  struct local_t {};
  template<class Duration>
    using local_time  = time_point<local_t, Duration>;
  using local_seconds = local_time<seconds>;
  using local_days    = local_time<days>;

  template<class charT, class traits, class Duration>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const local_time<Duration>& tp);
  template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  local_time<Duration>& tp,
                  basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.clock.cast}, \tcode{time_point} conversions
  template<class DestClock, class SourceClock>
    struct clock_time_conversion;

  template<class DestClock, class SourceClock, class Duration>
    auto clock_cast(const time_point<SourceClock, Duration>& t);

  // \ref{time.cal.last}, class \tcode{last_spec}
  struct last_spec;

  // \ref{time.cal.day}, class \tcode{day}
  class day;

  constexpr bool operator==(const day& x, const day& y) noexcept;
  constexpr strong_ordering operator<=>(const day& x, const day& y) noexcept;

  constexpr day  operator+(const day&  x, const days& y) noexcept;
  constexpr day  operator+(const days& x, const day&  y) noexcept;
  constexpr day  operator-(const day&  x, const days& y) noexcept;
  constexpr days operator-(const day&  x, const day&  y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const day& d);
  template<class charT, class traits, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  day& d, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.cal.month}, class \tcode{month}
  class month;

  constexpr bool operator==(const month& x, const month& y) noexcept;
  constexpr strong_ordering operator<=>(const month& x, const month& y) noexcept;

  constexpr month  operator+(const month&  x, const months& y) noexcept;
  constexpr month  operator+(const months& x,  const month& y) noexcept;
  constexpr month  operator-(const month&  x, const months& y) noexcept;
  constexpr months operator-(const month&  x,  const month& y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const month& m);
  template<class charT, class traits, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  month& m, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.cal.year}, class \tcode{year}
  class year;

  constexpr bool operator==(const year& x, const year& y) noexcept;
  constexpr strong_ordering operator<=>(const year& x, const year& y) noexcept;

  constexpr year  operator+(const year&  x, const years& y) noexcept;
  constexpr year  operator+(const years& x, const year&  y) noexcept;
  constexpr year  operator-(const year&  x, const years& y) noexcept;
  constexpr years operator-(const year&  x, const year&  y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const year& y);

  template<class charT, class traits, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  year& y, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.cal.wd}, class \tcode{weekday}
  class weekday;

  constexpr bool operator==(const weekday& x, const weekday& y) noexcept;

  constexpr weekday operator+(const weekday& x, const days&    y) noexcept;
  constexpr weekday operator+(const days&    x, const weekday& y) noexcept;
  constexpr weekday operator-(const weekday& x, const days&    y) noexcept;
  constexpr days    operator-(const weekday& x, const weekday& y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const weekday& wd);

  template<class charT, class traits, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  weekday& wd, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.cal.wdidx}, class \tcode{weekday_indexed}
  class weekday_indexed;

  constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const weekday_indexed& wdi);

  // \ref{time.cal.wdlast}, class \tcode{weekday_last}
  class weekday_last;

  constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const weekday_last& wdl);

  // \ref{time.cal.md}, class \tcode{month_day}
  class month_day;

  constexpr bool operator==(const month_day& x, const month_day& y) noexcept;
  constexpr strong_ordering operator<=>(const month_day& x, const month_day& y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const month_day& md);

  template<class charT, class traits, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  month_day& md, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.cal.mdlast}, class \tcode{month_day_last}
  class month_day_last;

  constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept;
  constexpr strong_ordering operator<=>(const month_day_last& x,
                                        const month_day_last& y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const month_day_last& mdl);

  // \ref{time.cal.mwd}, class \tcode{month_weekday}
  class month_weekday;

  constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const month_weekday& mwd);

  // \ref{time.cal.mwdlast}, class \tcode{month_weekday_last}
  class month_weekday_last;

  constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const month_weekday_last& mwdl);

  // \ref{time.cal.ym}, class \tcode{year_month}
  class year_month;

  constexpr bool operator==(const year_month& x, const year_month& y) noexcept;
  constexpr strong_ordering operator<=>(const year_month& x, const year_month& y) noexcept;

  constexpr year_month operator+(const year_month& ym, const months& dm) noexcept;
  constexpr year_month operator+(const months& dm, const year_month& ym) noexcept;
  constexpr year_month operator-(const year_month& ym, const months& dm) noexcept;
  constexpr months operator-(const year_month& x, const year_month& y) noexcept;
  constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
  constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
  constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const year_month& ym);

  template<class charT, class traits, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  year_month& ym, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.cal.ymd}, class \tcode{year_month_day}
  class year_month_day;

  constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept;
  constexpr strong_ordering operator<=>(const year_month_day& x,
                                        const year_month_day& y) noexcept;

  constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
  constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
  constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
  constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
  constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
  constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const year_month_day& ymd);

  template<class charT, class traits, class Alloc = allocator<charT>>
    basic_istream<charT, traits>&
      from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                  year_month_day& ymd,
                  basic_string<charT, traits, Alloc>* abbrev = nullptr,
                  minutes* offset = nullptr);

  // \ref{time.cal.ymdlast}, class \tcode{year_month_day_last}
  class year_month_day_last;

  constexpr bool operator==(const year_month_day_last& x,
                            const year_month_day_last& y) noexcept;
  constexpr strong_ordering operator<=>(const year_month_day_last& x,
                                        const year_month_day_last& y) noexcept;

  constexpr year_month_day_last
    operator+(const year_month_day_last& ymdl, const months& dm) noexcept;
  constexpr year_month_day_last
    operator+(const months& dm, const year_month_day_last& ymdl) noexcept;
  constexpr year_month_day_last
    operator+(const year_month_day_last& ymdl, const years& dy) noexcept;
  constexpr year_month_day_last
    operator+(const years& dy, const year_month_day_last& ymdl) noexcept;
  constexpr year_month_day_last
    operator-(const year_month_day_last& ymdl, const months& dm) noexcept;
  constexpr year_month_day_last
    operator-(const year_month_day_last& ymdl, const years& dy) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const year_month_day_last& ymdl);

  // \ref{time.cal.ymwd}, class \tcode{year_month_weekday}
  class year_month_weekday;

  constexpr bool operator==(const year_month_weekday& x,
                            const year_month_weekday& y) noexcept;

  constexpr year_month_weekday
    operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
  constexpr year_month_weekday
    operator+(const months& dm, const year_month_weekday& ymwd) noexcept;
  constexpr year_month_weekday
    operator+(const year_month_weekday& ymwd, const years& dy) noexcept;
  constexpr year_month_weekday
    operator+(const years& dy, const year_month_weekday& ymwd) noexcept;
  constexpr year_month_weekday
    operator-(const year_month_weekday& ymwd, const months& dm) noexcept;
  constexpr year_month_weekday
    operator-(const year_month_weekday& ymwd, const years& dy) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const year_month_weekday& ymwd);

  // \ref{time.cal.ymwdlast}, class \tcode{year_month_weekday_last}
  class year_month_weekday_last;

  constexpr bool operator==(const year_month_weekday_last& x,
                            const year_month_weekday_last& y) noexcept;

  constexpr year_month_weekday_last
    operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
  constexpr year_month_weekday_last
    operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept;
  constexpr year_month_weekday_last
    operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
  constexpr year_month_weekday_last
    operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept;
  constexpr year_month_weekday_last
    operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
  constexpr year_month_weekday_last
    operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const year_month_weekday_last& ymwdl);

  // \ref{time.cal.operators}, civil calendar conventional syntax operators
  constexpr year_month
    operator/(const year& y, const month& m) noexcept;
  constexpr year_month
    operator/(const year& y, int m) noexcept;
  constexpr month_day
    operator/(const month& m, const day& d) noexcept;
  constexpr month_day
    operator/(const month& m, int d) noexcept;
  constexpr month_day
    operator/(int m, const day& d) noexcept;
  constexpr month_day
    operator/(const day& d, const month& m) noexcept;
  constexpr month_day
    operator/(const day& d, int m) noexcept;
  constexpr month_day_last
    operator/(const month& m, last_spec) noexcept;
  constexpr month_day_last
    operator/(int m, last_spec) noexcept;
  constexpr month_day_last
    operator/(last_spec, const month& m) noexcept;
  constexpr month_day_last
    operator/(last_spec, int m) noexcept;
  constexpr month_weekday
    operator/(const month& m, const weekday_indexed& wdi) noexcept;
  constexpr month_weekday
    operator/(int m, const weekday_indexed& wdi) noexcept;
  constexpr month_weekday
    operator/(const weekday_indexed& wdi, const month& m) noexcept;
  constexpr month_weekday
    operator/(const weekday_indexed& wdi, int m) noexcept;
  constexpr month_weekday_last
    operator/(const month& m, const weekday_last& wdl) noexcept;
  constexpr month_weekday_last
    operator/(int m, const weekday_last& wdl) noexcept;
  constexpr month_weekday_last
    operator/(const weekday_last& wdl, const month& m) noexcept;
  constexpr month_weekday_last
    operator/(const weekday_last& wdl, int m) noexcept;
  constexpr year_month_day
    operator/(const year_month& ym, const day& d) noexcept;
  constexpr year_month_day
    operator/(const year_month& ym, int d) noexcept;
  constexpr year_month_day
    operator/(const year& y, const month_day& md) noexcept;
  constexpr year_month_day
    operator/(int y, const month_day& md) noexcept;
  constexpr year_month_day
    operator/(const month_day& md, const year& y) noexcept;
  constexpr year_month_day
    operator/(const month_day& md, int y) noexcept;
  constexpr year_month_day_last
    operator/(const year_month& ym, last_spec) noexcept;
  constexpr year_month_day_last
    operator/(const year& y, const month_day_last& mdl) noexcept;
  constexpr year_month_day_last
    operator/(int y, const month_day_last& mdl) noexcept;
  constexpr year_month_day_last
    operator/(const month_day_last& mdl, const year& y) noexcept;
  constexpr year_month_day_last
    operator/(const month_day_last& mdl, int y) noexcept;
  constexpr year_month_weekday
    operator/(const year_month& ym, const weekday_indexed& wdi) noexcept;
  constexpr year_month_weekday
    operator/(const year& y, const month_weekday& mwd) noexcept;
  constexpr year_month_weekday
    operator/(int y, const month_weekday& mwd) noexcept;
  constexpr year_month_weekday
    operator/(const month_weekday& mwd, const year& y) noexcept;
  constexpr year_month_weekday
    operator/(const month_weekday& mwd, int y) noexcept;
  constexpr year_month_weekday_last
    operator/(const year_month& ym, const weekday_last& wdl) noexcept;
  constexpr year_month_weekday_last
    operator/(const year& y, const month_weekday_last& mwdl) noexcept;
  constexpr year_month_weekday_last
    operator/(int y, const month_weekday_last& mwdl) noexcept;
  constexpr year_month_weekday_last
    operator/(const month_weekday_last& mwdl, const year& y) noexcept;
  constexpr year_month_weekday_last
    operator/(const month_weekday_last& mwdl, int y) noexcept;

  // \ref{time.hms}, class template \tcode{hh_mm_ss}
  template<class Duration> class hh_mm_ss;

  template<class charT, class traits, class Duration>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const hh_mm_ss<Duration>& hms);

  // \ref{time.12}, 12/24 hour functions
  constexpr bool is_am(const hours& h) noexcept;
  constexpr bool is_pm(const hours& h) noexcept;
  constexpr hours make12(const hours& h) noexcept;
  constexpr hours make24(const hours& h, bool is_pm) noexcept;

  // \ref{time.zone.db}, time zone database
  struct tzdb;
  class tzdb_list;

  // \ref{time.zone.db.access}, time zone database access
  const tzdb& get_tzdb();
  tzdb_list& get_tzdb_list();
  const time_zone* locate_zone(string_view tz_name);
  const time_zone* current_zone();

  // \ref{time.zone.db.remote}, remote time zone database support
  const tzdb& reload_tzdb();
  string remote_version();

  // \ref{time.zone.exception}, exception classes
  class nonexistent_local_time;
  class ambiguous_local_time;

  // \ref{time.zone.info}, information classes
  struct sys_info;
  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const sys_info& si);

  struct local_info;
  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os, const local_info& li);

  // \ref{time.zone.timezone}, class \tcode{time_zone}
  enum class choose {earliest, latest};
  class time_zone;

  bool operator==(const time_zone& x, const time_zone& y) noexcept;
  strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept;

  // \ref{time.zone.zonedtraits}, class template \tcode{zoned_traits}
  template<class T> struct zoned_traits;

  // \ref{time.zone.zonedtime}, class template \tcode{zoned_time}
  template<class Duration, class TimeZonePtr = const time_zone*> class zoned_time;

  using zoned_seconds = zoned_time<seconds>;

  template<class Duration1, class Duration2, class TimeZonePtr>
    bool operator==(const zoned_time<Duration1, TimeZonePtr>& x,
                    const zoned_time<Duration2, TimeZonePtr>& y);

  template<class charT, class traits, class Duration, class TimeZonePtr>
    basic_ostream<charT, traits>&
      operator<<(basic_ostream<charT, traits>& os,
                 const zoned_time<Duration, TimeZonePtr>& t);

  // \ref{time.zone.leap}, leap second support
  class leap_second;

  constexpr bool operator==(const leap_second& x, const leap_second& y);
  constexpr strong_ordering operator<=>(const leap_second& x, const leap_second& y);

  template<class Duration>
    constexpr bool operator==(const leap_second& x, const sys_time<Duration>& y);
  template<class Duration>
    constexpr bool operator< (const leap_second& x, const sys_time<Duration>& y);
  template<class Duration>
    constexpr bool operator< (const sys_time<Duration>& x, const leap_second& y);
  template<class Duration>
    constexpr bool operator> (const leap_second& x, const sys_time<Duration>& y);
  template<class Duration>
    constexpr bool operator> (const sys_time<Duration>& x, const leap_second& y);
  template<class Duration>
    constexpr bool operator<=(const leap_second& x, const sys_time<Duration>& y);
  template<class Duration>
    constexpr bool operator<=(const sys_time<Duration>& x, const leap_second& y);
  template<class Duration>
    constexpr bool operator>=(const leap_second& x, const sys_time<Duration>& y);
  template<class Duration>
    constexpr bool operator>=(const sys_time<Duration>& x, const leap_second& y);
  template<class Duration>
    requires @\libconcept{three_way_comparable_with}@<sys_seconds, sys_time<Duration>>
    constexpr auto operator<=>(const leap_second& x, const sys_time<Duration>& y);

  // \ref{time.zone.link}, class \tcode{time_zone_link}
  class time_zone_link;

  bool operator==(const time_zone_link& x, const time_zone_link& y);
  strong_ordering operator<=>(const time_zone_link& x, const time_zone_link& y);

  // \ref{time.format}, formatting
  template<class Duration> struct @\placeholder{local-time-format-t}@;        // \expos
  template<class Duration>
    @\placeholder{local-time-format-t}@<Duration>
      local_time_format(local_time<Duration> time, const string* abbrev = nullptr,
                        const seconds* offset_sec = nullptr);
}

namespace std {
  template<class Rep, class Period, class charT>
    struct formatter<chrono::duration<Rep, Period>, charT>;
  template<class Duration, class charT>
    struct formatter<chrono::sys_time<Duration>, charT>;
  template<class Duration, class charT>
    struct formatter<chrono::utc_time<Duration>, charT>;
  template<class Duration, class charT>
    struct formatter<chrono::tai_time<Duration>, charT>;
  template<class Duration, class charT>
    struct formatter<chrono::gps_time<Duration>, charT>;
  template<class Duration, class charT>
    struct formatter<chrono::file_time<Duration>, charT>;
  template<class Duration, class charT>
    struct formatter<chrono::local_time<Duration>, charT>;
  template<class Duration, class charT>
    struct formatter<chrono::@\placeholder{local-time-format-t}@<Duration>, charT>;
  template<class charT> struct formatter<chrono::day, charT>;
  template<class charT> struct formatter<chrono::month, charT>;
  template<class charT> struct formatter<chrono::year, charT>;
  template<class charT> struct formatter<chrono::weekday, charT>;
  template<class charT> struct formatter<chrono::weekday_indexed, charT>;
  template<class charT> struct formatter<chrono::weekday_last, charT>;
  template<class charT> struct formatter<chrono::month_day, charT>;
  template<class charT> struct formatter<chrono::month_day_last, charT>;
  template<class charT> struct formatter<chrono::month_weekday, charT>;
  template<class charT> struct formatter<chrono::month_weekday_last, charT>;
  template<class charT> struct formatter<chrono::year_month, charT>;
  template<class charT> struct formatter<chrono::year_month_day, charT>;
  template<class charT> struct formatter<chrono::year_month_day_last, charT>;
  template<class charT> struct formatter<chrono::year_month_weekday, charT>;
  template<class charT> struct formatter<chrono::year_month_weekday_last, charT>;
  template<class Rep, class Period, class charT>
    struct formatter<chrono::hh_mm_ss<chrono::duration<Rep, Period>>, charT>;
  template<class charT> struct formatter<chrono::sys_info, charT>;
  template<class charT> struct formatter<chrono::local_info, charT>;
  template<class Duration, class TimeZonePtr, class charT>
    struct formatter<chrono::zoned_time<Duration, TimeZonePtr>, charT>;
}

namespace std::chrono {
  // \ref{time.parse}, parsing
  template<class charT, class Parsable>
    @\unspec@
      parse(const charT* fmt, Parsable& tp);
  template<class charT, class traits, class Alloc, class Parsable>
    @\unspec@
      parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp);

  template<class charT, class traits, class Alloc, class Parsable>
    @\unspec@
      parse(const charT* fmt, Parsable& tp,
            basic_string<charT, traits, Alloc>& abbrev);
  template<class charT, class traits, class Alloc, class Parsable>
    @\unspec@
      parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
            basic_string<charT, traits, Alloc>& abbrev);

  template<class charT, class Parsable>
    @\unspec@
      parse(const charT* fmt, Parsable& tp, minutes& offset);
  template<class charT, class traits, class Alloc, class Parsable>
    @\unspec@
      parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
            minutes& offset);

  template<class charT, class traits, class Alloc, class Parsable>
    @\unspec@
      parse(const charT* fmt, Parsable& tp,
            basic_string<charT, traits, Alloc>& abbrev, minutes& offset);
  template<class charT, class traits, class Alloc, class Parsable>
    @\unspec@
      parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
            basic_string<charT, traits, Alloc>& abbrev, minutes& offset);

  // calendrical constants
  inline constexpr last_spec last{};

  inline constexpr weekday Sunday{0};
  inline constexpr weekday Monday{1};
  inline constexpr weekday Tuesday{2};
  inline constexpr weekday Wednesday{3};
  inline constexpr weekday Thursday{4};
  inline constexpr weekday Friday{5};
  inline constexpr weekday Saturday{6};

  inline constexpr month January{1};
  inline constexpr month February{2};
  inline constexpr month March{3};
  inline constexpr month April{4};
  inline constexpr month May{5};
  inline constexpr month June{6};
  inline constexpr month July{7};
  inline constexpr month August{8};
  inline constexpr month September{9};
  inline constexpr month October{10};
  inline constexpr month November{11};
  inline constexpr month December{12};
}

namespace std::inline literals::inline chrono_literals {
  // \ref{time.duration.literals}, suffixes for duration literals
  constexpr chrono::hours                                 operator""h(unsigned long long);
  constexpr chrono::duration<@\unspec,@ ratio<3600, 1>> operator""h(long double);

  constexpr chrono::minutes                             operator""min(unsigned long long);
  constexpr chrono::duration<@\unspec,@ ratio<60, 1>> operator""min(long double);

  constexpr chrono::seconds               operator""s(unsigned long long);
  constexpr chrono::duration<@\unspec@>@\itcorr[-1]@ operator""s(long double);

  constexpr chrono::milliseconds                 operator""ms(unsigned long long);
  constexpr chrono::duration<@\unspec,@ milli> operator""ms(long double);

  constexpr chrono::microseconds                 operator""us(unsigned long long);
  constexpr chrono::duration<@\unspec,@ micro> operator""us(long double);

  constexpr chrono::nanoseconds                 operator""ns(unsigned long long);
  constexpr chrono::duration<@\unspec,@ nano> operator""ns(long double);

  // \ref{time.cal.day.nonmembers}, non-member functions
  constexpr chrono::day  operator""d(unsigned long long d) noexcept;

  // \ref{time.cal.year.nonmembers}, non-member functions
  constexpr chrono::year operator""y(unsigned long long y) noexcept;
}

namespace std::chrono {
  using namespace literals::chrono_literals;
}

namespace std {
  // \ref{time.hash}, hash support
  template<class T> struct hash;
  template<class Rep, class Period> struct hash<chrono::duration<Rep, Period>>;
  template<class Clock, class Duration> struct hash<chrono::time_point<Clock, Duration>>;
  template<> struct hash<chrono::day>;
  template<> struct hash<chrono::month>;
  template<> struct hash<chrono::year>;
  template<> struct hash<chrono::weekday>;
  template<> struct hash<chrono::weekday_indexed>;
  template<> struct hash<chrono::weekday_last>;
  template<> struct hash<chrono::month_day>;
  template<> struct hash<chrono::month_day_last>;
  template<> struct hash<chrono::month_weekday>;
  template<> struct hash<chrono::month_weekday_last>;
  template<> struct hash<chrono::year_month>;
  template<> struct hash<chrono::year_month_day>;
  template<> struct hash<chrono::year_month_day_last>;
  template<> struct hash<chrono::year_month_weekday>;
  template<> struct hash<chrono::year_month_weekday_last>;
  template<class Duration, class TimeZonePtr>
    struct hash<chrono::zoned_time<Duration, TimeZonePtr>>;
  template<> struct hash<chrono::leap_second>;
}
\end{codeblock}

\rSec1[time.clock.req]{\oldconcept{Clock} requirements}

\indextext{\idxoldconcept{Clock}}%
\pnum
A clock is a bundle consisting of a \tcode{duration}, a
\tcode{time_point}, and a function \tcode{now()} to get the current \tcode{time_point}.
The origin of the clock's \tcode{time_point} is referred to as the clock's \defn{epoch}.
 A clock shall meet the requirements in \tref{time.clock}.

\pnum
In \tref{time.clock} \tcode{C1} and \tcode{C2} denote clock types. \tcode{t1} and
\tcode{t2} are values returned by \tcode{C1::now()} where the call returning \tcode{t1} happens
before\iref{intro.multithread} the call returning \tcode{t2} and both of these calls
occur
before \tcode{C1::time_point::max()}.
\begin{note}
This means \tcode{C1} did not wrap around between \tcode{t1} and
\tcode{t2}.
\end{note}

\begin{libreqtab3a}
{\oldconcept{Clock} requirements}
{time.clock}
\\ \topline
\lhdr{Expression}       &   \chdr{Return type}  &   \rhdr{Operational semantics} \\ \capsep
\endfirsthead
\continuedcaption\\
\hline
\lhdr{Expression}       &   \chdr{Return type}  &   \rhdr{Operational semantics}       \\ \capsep
\endhead

\tcode{C1::rep} &
  An arithmetic type or a class emulating an arithmetic type &
  The representation type of \tcode{C1::duration}.  \\ \rowsep

\tcode{C1::period}  &
  a specialization of \tcode{ratio}     &
  The tick period of the clock in seconds.  \\ \rowsep

\tcode{C1::duration}  &
  \tcode{chrono::duration<C1::rep, C1::period>} &
  The \tcode{duration} type of the clock. \\ \rowsep

\tcode{C1::time_point}  &
  \tcode{chrono::time_point<C1>} or \tcode{chrono::time_point<C2, C1::duration>}  &
  The \tcode{time_point} type of the clock. \tcode{C1} and \tcode{C2} shall
  refer to the same epoch. \\ \rowsep

\tcode{C1::is_steady}  &
  \tcode{const bool}      &
  \tcode{true} if \tcode{t1 <= t2} is always \tcode{true} and the time between clock
  ticks is constant, otherwise \tcode{false}.  \\ \rowsep

\tcode{C1::now()} &
  \tcode{C1::time_point}  &
  Returns a \tcode{time_point} object representing the current point in time. \\

\end{libreqtab3a}

\pnum
\begin{note}
The relative difference in durations between those reported by a given clock and the
SI definition is a measure of the quality of implementation.
\end{note}

\pnum
A type \tcode{TC} meets the \defnoldconcept{TrivialClock} requirements if
\begin{itemize}
\item
\tcode{TC} meets the \oldconcept{Clock} requirements,

\item
the types \tcode{TC::rep}, \tcode{TC::duration}, and \tcode{TC::time_point}
meet the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable}) and
\oldconcept{LessThanComparable} (\tref{cpp17.lessthancomparable})
and \oldconcept{Swappable}\iref{swappable.requirements}
requirements and the requirements of
numeric types\iref{numeric.requirements},
\begin{note}
This means, in particular,
that operations on these types will not throw exceptions.
\end{note}
\item
the function \tcode{TC::now()} does not throw exceptions, and
\item
the type \tcode{TC::time_point::clock} meets the \oldconcept{TrivialClock}
requirements, recursively.
\end{itemize}

\rSec1[time.traits]{Time-related traits}

\rSec2[time.traits.is.fp]{\tcode{treat_as_floating_point}}

\indexlibraryglobal{treat_as_floating_point}%
\begin{itemdecl}
template<class Rep> struct treat_as_floating_point : is_floating_point<Rep> { };
\end{itemdecl}

\pnum
The \tcode{duration} template uses the \tcode{treat_as_floating_point} trait to
help determine if a \tcode{duration} object can be converted to another
\tcode{duration} with a different tick \tcode{period}. If
\tcode{treat_as_floating_point_v<Rep>} is \tcode{true}, then implicit conversions
are allowed among \tcode{duration}s. Otherwise, the implicit convertibility
depends on the tick \tcode{period}s of the \tcode{duration}s.
\begin{note}
The intention of this trait is to indicate whether a given class behaves like a floating-point
type, and thus allows division of one value by another with acceptable loss of precision. If
\tcode{treat_as_floating_point_v<Rep>} is \tcode{false}, \tcode{Rep} will be treated as
if it behaved like an integral type for the purpose of these conversions.
\end{note}

\rSec2[time.traits.duration.values]{\tcode{duration_values}}

\indexlibraryglobal{duration_values}%
\begin{itemdecl}
template<class Rep>
  struct duration_values {
  public:
    static constexpr Rep zero() noexcept;
    static constexpr Rep min() noexcept;
    static constexpr Rep max() noexcept;
  };
\end{itemdecl}

\pnum
The \tcode{duration} template uses the \tcode{duration_values} trait to
construct special values of the duration's representation (\tcode{Rep}). This is
done because the representation can be a class type with behavior that
requires some other implementation to return these special values. In that case,
the author of that class type should specialize \tcode{duration_values} to
return the indicated values.

\indexlibrarymember{zero}{duration_values}%
\begin{itemdecl}
static constexpr Rep zero() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{Rep(0)}.
\begin{note}
\tcode{Rep(0)} is specified instead of
\tcode{Rep()} because \tcode{Rep()} can have some other meaning, such as an
uninitialized value.
\end{note}

\pnum
\remarks
The value returned shall be the additive identity.
\end{itemdescr}

\indexlibrarymember{min}{duration_values}%
\begin{itemdecl}
static constexpr Rep min() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{numeric_limits<Rep>::lowest()}.

\pnum
\remarks
The value returned shall compare less than or equal to \tcode{zero()}.
\end{itemdescr}

\indexlibrarymember{max}{duration_values}%
\begin{itemdecl}
static constexpr Rep max() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{numeric_limits<Rep>::max()}.

\pnum
\remarks
The value returned shall compare greater than \tcode{zero()}.
\end{itemdescr}

\rSec2[time.traits.specializations]{Specializations of \tcode{common_type}}

\indexlibraryglobal{common_type}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  struct common_type<chrono::duration<Rep1, Period1>, chrono::duration<Rep2, Period2>> {
    using type = chrono::duration<common_type_t<Rep1, Rep2>, @\seebelow@>;
  };
\end{itemdecl}

\pnum
The \tcode{period} of the \tcode{duration} indicated by this specialization of
\tcode{common_type} is the greatest common divisor of \tcode{Period1} and
\tcode{Period2}.
\begin{note}
This can be computed by forming a ratio of the
greatest common divisor of \tcode{Period1::num} and \tcode{Period2::num} and the
least common multiple of \tcode{Period1::den} and \tcode{Period2::den}.
\end{note}

\pnum
\begin{note}
The \keyword{typedef} name \tcode{type} is a synonym for the
\tcode{duration} with the largest tick \tcode{period} possible where both
\tcode{duration} arguments will convert to it without requiring a division
operation. The representation of this type is intended to be able to hold any
value resulting from this conversion with no truncation error, although
floating-point durations can have round-off errors.
\end{note}

\indexlibrarymember{common_type}{duration}%
\begin{itemdecl}
template<class Clock, class Duration1, class Duration2>
  struct common_type<chrono::time_point<Clock, Duration1>, chrono::time_point<Clock, Duration2>> {
    using type = chrono::time_point<Clock, common_type_t<Duration1, Duration2>>;
  };
\end{itemdecl}

\pnum
The common type of two \tcode{time_point} types is a \tcode{time_point} with the same
clock as the two types and the common type of their two \tcode{duration}s.

\rSec2[time.traits.is.clock]{Class template \tcode{is_clock}}

\indexlibraryglobal{is_clock}%
\begin{itemdecl}
template<class T> struct is_clock;
\end{itemdecl}

\pnum
\tcode{is_clock} is a \oldconcept{UnaryTypeTrait}\iref{meta.rqmts}
with a base characteristic of \tcode{true_type}
if \tcode{T} meets the \oldconcept{Clock} requirements\iref{time.clock.req},
otherwise \tcode{false_type}.
For the purposes of the specification of this trait,
the extent to which an implementation determines
that a type cannot meet the \oldconcept{Clock} requirements is unspecified,
except that as a minimum
a type \tcode{T} shall not qualify as a \oldconcept{Clock}
unless it meets all of the following conditions:
\begin{itemize}
\item the \grammarterm{qualified-id}s
\tcode{T::rep},
\tcode{T::period},
\tcode{T::duration}, and
\tcode{T::time_point}
are valid and each denotes a type\iref{temp.deduct},
\item the expression
\tcode{T::is_steady}
is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand},
\item the expression
\tcode{T::now()}
is well-formed when treated as an unevaluated operand.
\end{itemize}

\pnum
The behavior of a program that adds specializations for \tcode{is_clock} is undefined.

\rSec1[time.duration]{Class template \tcode{duration}}

\rSec2[time.duration.general]{General}

\pnum
A \tcode{duration} type measures time between two points in time (\tcode{time_point}s).
A \tcode{duration} has a representation which holds a count of ticks and a tick period.
The tick period is the amount of time which occurs from one tick to the next, in units
of seconds. It is expressed as a rational constant using the template \tcode{ratio}.

\indexlibraryglobal{duration}%
\begin{codeblock}
namespace std::chrono {
  template<class Rep, class Period = ratio<1>>
  class duration {
  public:
    using rep    = Rep;
    using period = Period::type;

  private:
    rep rep_;       // \expos

  public:
    // \ref{time.duration.cons}, construct/copy/destroy
    constexpr duration() = default;
    template<class Rep2>
      constexpr explicit duration(const Rep2& r);
    template<class Rep2, class Period2>
      constexpr duration(const duration<Rep2, Period2>& d);
    ~duration() = default;
    duration(const duration&) = default;
    duration& operator=(const duration&) = default;

    // \ref{time.duration.observer}, observer
    constexpr rep count() const;

    // \ref{time.duration.arithmetic}, arithmetic
    constexpr common_type_t<duration> operator+() const;
    constexpr common_type_t<duration> operator-() const;
    constexpr duration& operator++();
    constexpr duration  operator++(int);
    constexpr duration& operator--();
    constexpr duration  operator--(int);

    constexpr duration& operator+=(const duration& d);
    constexpr duration& operator-=(const duration& d);

    constexpr duration& operator*=(const rep& rhs);
    constexpr duration& operator/=(const rep& rhs);
    constexpr duration& operator%=(const rep& rhs);
    constexpr duration& operator%=(const duration& rhs);

    // \ref{time.duration.special}, special values
    static constexpr duration zero() noexcept;
    static constexpr duration min() noexcept;
    static constexpr duration max() noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{Rep} shall be an arithmetic type or a class emulating an arithmetic type.
If \tcode{duration} is instantiated with a \tcode{duration} type as the argument for the template
parameter \tcode{Rep}, the program is ill-formed.

\pnum
If \tcode{Period} is not a specialization of \tcode{ratio}, the program is ill-formed.
If \tcode{Period::num} is not positive, the program is ill-formed.

\pnum
Members of \tcode{duration} do not throw exceptions other than
those thrown by the indicated operations on their representations.

\pnum
The defaulted copy constructor of \tcode{duration} shall be a
constexpr function if and only if the required initialization
of the member \tcode{rep_} for copy and move, respectively, would
be constexpr-suitable\iref{dcl.constexpr}.

\pnum
\begin{example}
\begin{codeblock}
duration<long, ratio<60>> d0;       // holds a count of minutes using a \tcode{long}
duration<long long, milli> d1;      // holds a count of milliseconds using a \tcode{long long}
duration<double, ratio<1, 30>>  d2; // holds a count with a tick period of $\frac{1}{30}$ of a second
                                    // (30 Hz) using a \tcode{double}
\end{codeblock}
\end{example}

\rSec2[time.duration.cons]{Constructors}

\indexlibraryctor{duration}%
\begin{itemdecl}
template<class Rep2>
  constexpr explicit duration(const Rep2& r);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const Rep2\&, rep>} is \tcode{true} and
\begin{itemize}
\item \tcode{treat_as_floating_point_v<rep>} is \tcode{true} or
\item \tcode{treat_as_floating_point_v<Rep2>} is \tcode{false}.
\end{itemize}
\begin{example}
\begin{codeblock}
duration<int, milli> d(3);          // OK
duration<int, milli> d2(3.5);       // error
\end{codeblock}
\end{example}

\pnum
\effects
Initializes \tcode{rep_} with \tcode{r}.
\end{itemdescr}

\indexlibraryctor{duration}%
\begin{itemdecl}
template<class Rep2, class Period2>
  constexpr duration(const duration<Rep2, Period2>& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const Rep2\&, rep>} is \tcode{true}.
\tcode{ratio_divide<typename Period2::\brk{}type, period>} is a valid ratio specialization.
Either:
\begin{itemize}
\item \tcode{treat_as_floating_point_v<rep>} is \tcode{true}; or
\item \tcode{ratio_divide<Period2, period>::den} is \tcode{1} and
\tcode{treat_as_floating_point_v<Rep2>} is \tcode{false}.
\end{itemize}
\begin{note}
This
requirement prevents implicit truncation errors when converting between
integral-based \tcode{duration} types. Such a construction could easily lead to
confusion about the value of the \tcode{duration}.
\end{note}
\begin{example}
\begin{codeblock}
duration<int, milli> ms(3);
duration<int, micro> us = ms;       // OK
duration<int, milli> ms2 = us;      // error
\end{codeblock}
\end{example}

\pnum
\effects
Initializes \tcode{rep_} with \tcode{duration_cast<duration>(d).count()}.
\end{itemdescr}

\rSec2[time.duration.observer]{Observer}

\indexlibrarymember{count}{duration}%
\begin{itemdecl}
constexpr rep count() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{rep_}.
\end{itemdescr}

\rSec2[time.duration.arithmetic]{Arithmetic}

\indexlibrarymember{operator+}{duration}%
\begin{itemdecl}
constexpr common_type_t<duration> operator+() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{common_type_t<duration>(*this)}.
\end{itemdescr}

\indexlibrarymember{operator-}{duration}%
\begin{itemdecl}
constexpr common_type_t<duration> operator-() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{common_type_t<duration>(-rep_)}.
\end{itemdescr}

\indexlibrarymember{operator++}{duration}%
\begin{itemdecl}
constexpr duration& operator++();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{++rep_}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator++}{duration}%
\begin{itemdecl}
constexpr duration operator++(int);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return duration(rep_++);}
\end{itemdescr}

\indexlibrarymember{operator--}{duration}%
\begin{itemdecl}
constexpr duration& operator--();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{--rep_}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator--}{duration}%
\begin{itemdecl}
constexpr duration operator--(int);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return duration(rep_-{}-);}
\end{itemdescr}

\indexlibrarymember{operator+=}{duration}%
\begin{itemdecl}
constexpr duration& operator+=(const duration& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rep_ += d.count()}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{duration}%
\begin{itemdecl}
constexpr duration& operator-=(const duration& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rep_ -= d.count()}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator*=}{duration}%
\begin{itemdecl}
constexpr duration& operator*=(const rep& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rep_ *= rhs}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator/=}{duration}%
\begin{itemdecl}
constexpr duration& operator/=(const rep& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rep_ /= rhs}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator\%=}{duration}%
\begin{itemdecl}
constexpr duration& operator%=(const rep& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rep_ \%= rhs}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator\%=}{duration}%
\begin{itemdecl}
constexpr duration& operator%=(const duration& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{rep_ \%= rhs.count()}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}


\rSec2[time.duration.special]{Special values}

\indexlibrarymember{zero}{duration}%
\begin{itemdecl}
static constexpr duration zero() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{duration(duration_values<rep>::zero())}.
\end{itemdescr}

\indexlibrarymember{min}{duration}%
\begin{itemdecl}
static constexpr duration min() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{duration(duration_values<rep>::min())}.
\end{itemdescr}

\indexlibrarymember{max}{duration}%
\begin{itemdecl}
static constexpr duration max() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{duration(duration_values<rep>::max())}.
\end{itemdescr}

\rSec2[time.duration.nonmember]{Non-member arithmetic}

\pnum
In the function descriptions that follow, unless stated otherwise,
let \tcode{CD} represent the return type of the function.

\indexlibrarymember{operator+}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
    operator+(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{CD(CD(lhs).count() + CD(rhs).count())}.
\end{itemdescr}

\indexlibrarymember{operator-}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
    operator-(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{CD(CD(lhs).count() - CD(rhs).count())}.
\end{itemdescr}

\indexlibrarymember{operator*}{duration}%
\begin{itemdecl}
template<class Rep1, class Period, class Rep2>
  constexpr duration<common_type_t<Rep1, Rep2>, Period>
    operator*(const duration<Rep1, Period>& d, const Rep2& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const Rep2\&, common_type_t<Rep1, Rep2>>} is \tcode{true}.

\pnum
\returns
\tcode{CD(CD(d).count() * s)}.
\end{itemdescr}

\indexlibrarymember{operator*}{duration}%
\begin{itemdecl}
template<class Rep1, class Rep2, class Period>
  constexpr duration<common_type_t<Rep1, Rep2>, Period>
    operator*(const Rep1& s, const duration<Rep2, Period>& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const Rep1\&, common_type_t<Rep1, Rep2>>} is \tcode{true}.

\pnum
\returns
\tcode{d * s}.
\end{itemdescr}

\indexlibrarymember{operator/}{duration}%
\begin{itemdecl}
template<class Rep1, class Period, class Rep2>
  constexpr duration<common_type_t<Rep1, Rep2>, Period>
    operator/(const duration<Rep1, Period>& d, const Rep2& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const Rep2\&, common_type_t<Rep1, Rep2>>} is \tcode{true}
and \tcode{Rep2} is not a specialization of \tcode{duration}.

\pnum
\returns
\tcode{CD(CD(d).count() / s)}.
\end{itemdescr}

\indexlibrarymember{operator/}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr common_type_t<Rep1, Rep2>
    operator/(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let \tcode{CD} be
\tcode{common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>}.

\pnum
\returns
\tcode{CD(lhs).count() / CD(rhs).count()}.
\end{itemdescr}

\indexlibrarymember{operator\%}{duration}%
\begin{itemdecl}
template<class Rep1, class Period, class Rep2>
  constexpr duration<common_type_t<Rep1, Rep2>, Period>
    operator%(const duration<Rep1, Period>& d, const Rep2& s);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<const Rep2\&, common_type_t<Rep1, Rep2>>} is \tcode{true} and
\tcode{Rep2} is not a specialization of \tcode{duration}.

\pnum
\returns
\tcode{CD(CD(d).count() \% s)}.
\end{itemdescr}

\indexlibrarymember{operator\%}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr common_type_t<duration<Rep1, Period1>, duration<Rep2, Period2>>
    operator%(const duration<Rep1, Period1>& lhs, const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{CD(CD(lhs).count() \% CD(rhs).count())}.
\end{itemdescr}


\rSec2[time.duration.comparisons]{Comparisons}

\pnum
In the function descriptions that follow, \tcode{CT} represents
\tcode{common_type_t<A, B>}, where \tcode{A} and \tcode{B} are the types of
the two arguments to the function.

\indexlibrarymember{operator==}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr bool operator==(const duration<Rep1, Period1>& lhs,
                            const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{CT(lhs).count() == CT(rhs).count()}.
\end{itemdescr}

\indexlibrarymember{operator<}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr bool operator<(const duration<Rep1, Period1>& lhs,
                           const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{CT(lhs).count() < CT(rhs).count()}.
\end{itemdescr}

\indexlibrarymember{operator>}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr bool operator>(const duration<Rep1, Period1>& lhs,
                           const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{rhs < lhs}.
\end{itemdescr}

\indexlibrarymember{operator<=}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr bool operator<=(const duration<Rep1, Period1>& lhs,
                            const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!(rhs < lhs)}.
\end{itemdescr}

\indexlibrarymember{operator>=}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  constexpr bool operator>=(const duration<Rep1, Period1>& lhs,
                            const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!(lhs < rhs)}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Rep2, class Period2>
  requires @\libconcept{three_way_comparable}@<typename CT::rep>
  constexpr auto operator<=>(const duration<Rep1, Period1>& lhs,
                             const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{CT(lhs).count() <=> CT(rhs).count()}.
\end{itemdescr}

\rSec2[time.duration.cast]{Conversions}

\indexlibrarymember{duration}{duration_cast}%
\indexlibraryglobal{duration_cast}%
\begin{itemdecl}
template<class ToDuration, class Rep, class Period>
  constexpr ToDuration duration_cast(const duration<Rep, Period>& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ToDuration} is a specialization of \tcode{duration}.

\pnum
\returns
Let \tcode{CF} be \tcode{ratio_divide<Period, typename
ToDuration::period>}, and \tcode{CR} be \tcode{common_type<typename
ToDuration::rep, Rep, intmax_t>::type}.
\begin{itemize}
\item If \tcode{CF::num == 1} and \tcode{CF::den == 1}, returns
\begin{codeblock}
ToDuration(static_cast<typename ToDuration::rep>(d.count()))
\end{codeblock}

\item otherwise, if \tcode{CF::num != 1} and \tcode{CF::den == 1}, returns
\begin{codeblock}
ToDuration(static_cast<typename ToDuration::rep>(
  static_cast<CR>(d.count()) * static_cast<CR>(CF::num)))
\end{codeblock}

\item otherwise, if \tcode{CF::num == 1} and \tcode{CF::den != 1}, returns
\begin{codeblock}
ToDuration(static_cast<typename ToDuration::rep>(
  static_cast<CR>(d.count()) / static_cast<CR>(CF::den)))
\end{codeblock}

\item otherwise, returns
\begin{codeblock}
ToDuration(static_cast<typename ToDuration::rep>(
  static_cast<CR>(d.count()) * static_cast<CR>(CF::num) / static_cast<CR>(CF::den)))
\end{codeblock}
\end{itemize}

\pnum
\begin{note}
This function does not use any implicit conversions; all conversions
are done with \keyword{static_cast}. It avoids multiplications and divisions when
it is known at compile time that one or more arguments is 1. Intermediate
computations are carried out in the widest representation and only converted to
the destination representation at the final step.
\end{note}
\end{itemdescr}

\indexlibrarymember{floor}{duration}%
\begin{itemdecl}
template<class ToDuration, class Rep, class Period>
  constexpr ToDuration floor(const duration<Rep, Period>& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ToDuration} is a specialization of \tcode{duration}.

\pnum
\returns
The greatest result \tcode{t} representable in \tcode{ToDuration}
for which \tcode{t <= d}.
\end{itemdescr}

\indexlibrarymember{ceil}{duration}%
\begin{itemdecl}
template<class ToDuration, class Rep, class Period>
  constexpr ToDuration ceil(const duration<Rep, Period>& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ToDuration} is a specialization of \tcode{duration}.

\pnum
\returns
The least result \tcode{t} representable in \tcode{ToDuration}
for which \tcode{t >= d}.
\end{itemdescr}

\indexlibrarymember{round}{duration}%
\begin{itemdecl}
template<class ToDuration, class Rep, class Period>
  constexpr ToDuration round(const duration<Rep, Period>& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ToDuration} is a specialization of \tcode{duration} and
\tcode{treat_as_floating_point_v<typename ToDuration::rep>} is \tcode{false}.

\pnum
\returns
The value of \tcode{ToDuration} that is closest to \tcode{d}.
If there are two closest values, then return the value \tcode{t}
for which \tcode{t \% 2 == 0}.
\end{itemdescr}

\rSec2[time.duration.literals]{Suffixes for duration literals}

\pnum
This subclause describes literal suffixes for constructing duration literals. The
suffixes \tcode{h}, \tcode{min}, \tcode{s}, \tcode{ms}, \tcode{us}, \tcode{ns}
denote duration values of the corresponding types \tcode{hours}, \tcode{minutes},
\tcode{seconds}, \tcode{milliseconds}, \tcode{microseconds}, and \tcode{nanoseconds}
respectively if they are applied to \grammarterm{integer-literal}{s}.

\pnum
If any of these suffixes are applied to a \grammarterm{floating-point-literal}
the result is a
\tcode{chrono::duration} literal with an unspecified floating-point representation.

\pnum
If any of these suffixes are applied to an \grammarterm{integer-literal}
and the resulting
\tcode{chrono::duration} value cannot be represented in the result type because
of overflow, the program is ill-formed.

\pnum
\begin{example}
The following code shows some duration literals.
\begin{codeblock}
using namespace std::chrono_literals;
auto constexpr aday=24h;
auto constexpr lesson=45min;
auto constexpr halfanhour=0.5h;
\end{codeblock}
\end{example}

\indexlibrarymember{operator""""h}{duration}%
\begin{itemdecl}
constexpr chrono::hours                                 operator""h(unsigned long long hours);
constexpr chrono::duration<@\unspec,@ ratio<3600, 1>> operator""h(long double hours);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{duration} literal representing \tcode{hours} hours.
\end{itemdescr}

\indexlibrarymember{operator""""min}{duration}%
\begin{itemdecl}
constexpr chrono::minutes                             operator""min(unsigned long long minutes);
constexpr chrono::duration<@\unspec,@ ratio<60, 1>> operator""min(long double minutes);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{duration} literal representing \tcode{minutes} minutes.
\end{itemdescr}

\indexlibrarymember{operator""""s}{duration}%
\begin{itemdecl}
constexpr chrono::seconds  @\itcorr@             operator""s(unsigned long long sec);
constexpr chrono::duration<@\unspec@> operator""s(long double sec);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{duration} literal representing \tcode{sec} seconds.

\pnum
\begin{note}
The same suffix \tcode{s} is used for \tcode{basic_string} but there is no
conflict, since duration suffixes apply to numbers and string literal suffixes
apply to character array literals.
\end{note}
\end{itemdescr}

\indexlibrarymember{operator""""ms}{duration}%
\begin{itemdecl}
constexpr chrono::milliseconds                 operator""ms(unsigned long long msec);
constexpr chrono::duration<@\unspec,@ milli> operator""ms(long double msec);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{duration} literal representing \tcode{msec} milliseconds.
\end{itemdescr}

\indexlibrarymember{operator""""us}{duration}%
\begin{itemdecl}
constexpr chrono::microseconds                 operator""us(unsigned long long usec);
constexpr chrono::duration<@\unspec,@ micro> operator""us(long double usec);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{duration} literal representing \tcode{usec} microseconds.
\end{itemdescr}

\indexlibrarymember{operator""""ns}{duration}%
\begin{itemdecl}
constexpr chrono::nanoseconds                 operator""ns(unsigned long long nsec);
constexpr chrono::duration<@\unspec,@ nano> operator""ns(long double nsec);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{duration} literal representing \tcode{nsec} nanoseconds.
\end{itemdescr}

\rSec2[time.duration.alg]{Algorithms}

\indexlibrarymember{abs}{duration}%
\begin{itemdecl}
template<class Rep, class Period>
  constexpr duration<Rep, Period> abs(duration<Rep, Period> d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{numeric_limits<Rep>::is_signed} is \tcode{true}.

\pnum
\returns
If \tcode{d >= d.zero()}, return \tcode{d},
otherwise return \tcode{-d}.
\end{itemdescr}

\rSec2[time.duration.io]{I/O}

\indexlibrarymember{operator<<}{duration}%
\begin{itemdecl}
template<class charT, class traits, class Rep, class Period>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const duration<Rep, Period>& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Inserts the duration \tcode{d} onto the stream \tcode{os}
as if it were implemented as follows:
\begin{codeblock}
basic_ostringstream<charT, traits> s;
s.flags(os.flags());
s.imbue(os.getloc());
s.precision(os.precision());
s << d.count() << @\placeholder{units-suffix}@;
return os << s.str();
\end{codeblock}
where \tcode{\placeholder{units-suffix}}
depends on the type \tcode{Period::type} as follows:

\begin{itemize}
\item
If \tcode{Period::type} is \tcode{atto},
\tcode{\placeholder{units-suffix}} is \tcode{"as"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{femto},
\tcode{\placeholder{units-suffix}} is \tcode{"fs"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{pico},
\tcode{\placeholder{units-suffix}} is \tcode{"ps"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{nano},
\tcode{\placeholder{units-suffix}} is \tcode{"ns"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{micro},
it is
\impldef{unit suffix when \tcode{Period::type} is \tcode{micro}}
whether \tcode{\placeholder{units-suffix}} is
\tcode{"\textmu{}s"} (\tcode{"\textbackslash{}u00b5\textbackslash{}u0073"}) or
\tcode{"us"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{milli},
\tcode{\placeholder{units-suffix}} is \tcode{"ms"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{centi},
\tcode{\placeholder{units-suffix}} is \tcode{"cs"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{deci},
\tcode{\placeholder{units-suffix}} is \tcode{"ds"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{ratio<1>},
\tcode{\placeholder{units-suffix}} is \tcode{"s"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{deca},
\tcode{\placeholder{units-suffix}} is \tcode{"das"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{hecto},
\tcode{\placeholder{units-suffix}} is \tcode{"hs"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{kilo},
\tcode{\placeholder{units-suffix}} is \tcode{"ks"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{mega},
\tcode{\placeholder{units-suffix}} is \tcode{"Ms"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{giga},
\tcode{\placeholder{units-suffix}} is \tcode{"Gs"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{tera},
\tcode{\placeholder{units-suffix}} is \tcode{"Ts"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{peta},
\tcode{\placeholder{units-suffix}} is \tcode{"Ps"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{exa},
\tcode{\placeholder{units-suffix}} is \tcode{"Es"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{ratio<60>},
\tcode{\placeholder{units-suffix}} is \tcode{"min"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{ratio<3600>},
\tcode{\placeholder{units-suffix}} is \tcode{"h"}.

\item
Otherwise, if \tcode{Period::type} is \tcode{ratio<86400>},
\tcode{\placeholder{units-suffix}} is \tcode{"d"}.

\item
Otherwise, if \tcode{Period::type::den == 1},
\tcode{\placeholder{units-suffix}} is \tcode{"[\placeholder{num}]s"}.

\item
Otherwise, \tcode{\placeholder{units-suffix}} is
\tcode{"[\placeholder{num}/\placeholder{den}]s"}.
\end{itemize}

In the list above,
the use of \tcode{\placeholder{num}} and \tcode{\placeholder{den}}
refers to the static data members of \tcode{Period::type},
which are converted to arrays of \tcode{charT} using a decimal conversion with no leading zeroes.

\pnum
\returns
\tcode{os}.
\end{itemdescr}

\indexlibrarymember{from_stream}{duration}%
\begin{itemdecl}
template<class charT, class traits, class Rep, class Period, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                duration<Rep, Period>& d,
                basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the duration \tcode{d}
using the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid duration,
\tcode{is.setstate(ios_base::failbit)} is called and \tcode{d} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec1[time.point]{Class template \tcode{time_point}}

\rSec2[time.point.general]{General}

\indexlibraryglobal{time_point}%
\begin{codeblock}
namespace std::chrono {
  template<class Clock, class Duration = typename Clock::duration>
  class time_point {
  public:
    using clock    = Clock;
    using duration = Duration;
    using rep      = duration::rep;
    using period   = duration::period;

  private:
    duration d_;                                                // \expos

  public:
    // \ref{time.point.cons}, construct
    constexpr time_point();                                     // has value epoch
    constexpr explicit time_point(const duration& d);           // same as \tcode{time_point() + d}
    template<class Duration2>
      constexpr time_point(const time_point<clock, Duration2>& t);

    // \ref{time.point.observer}, observer
    constexpr duration time_since_epoch() const;

    // \ref{time.point.arithmetic}, arithmetic
    constexpr time_point& operator++();
    constexpr time_point operator++(int);
    constexpr time_point& operator--();
    constexpr time_point operator--(int);
    constexpr time_point& operator+=(const duration& d);
    constexpr time_point& operator-=(const duration& d);

    // \ref{time.point.special}, special values
    static constexpr time_point min() noexcept;
    static constexpr time_point max() noexcept;
  };
}
\end{codeblock}

\pnum
If \tcode{Duration} is not a specialization of \tcode{duration},
the program is ill-formed.

\rSec2[time.point.cons]{Constructors}

\indexlibraryctor{time_point}%
\begin{itemdecl}
constexpr time_point();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{d_} with \tcode{duration::zero()}.
Such a \tcode{time_point} object represents the epoch.
\end{itemdescr}

\indexlibraryctor{time_point}%
\begin{itemdecl}
constexpr explicit time_point(const duration& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{d_} with \tcode{d}.
Such a \tcode{time_point} object represents the epoch \tcode{+ d}.
\end{itemdescr}

\indexlibraryctor{time_point}%
\begin{itemdecl}
template<class Duration2>
  constexpr time_point(const time_point<clock, Duration2>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<Duration2, duration>} is \tcode{true}.

\pnum
\effects
Initializes \tcode{d_} with \tcode{t.time_since_epoch()}.
\end{itemdescr}

\rSec2[time.point.observer]{Observer}

\indexlibrarymember{time_since_epoch}{time_point}%
\begin{itemdecl}
constexpr duration time_since_epoch() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{d_}.
\end{itemdescr}

\rSec2[time.point.arithmetic]{Arithmetic}

\indexlibrarymember{operator++}{time_point}%
\begin{itemdecl}
constexpr time_point& operator++();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{++d_}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator++}{time_point}%
\begin{itemdecl}
constexpr time_point operator++(int);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return time_point\{d_++\};}
\end{itemdescr}

\indexlibrarymember{operator--}{time_point}%
\begin{itemdecl}
constexpr time_point& operator--();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{--d_}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator--}{time_point}%
\begin{itemdecl}
constexpr time_point operator--(int);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{return time_point\{d_-{}-\};}
\end{itemdescr}

\indexlibrarymember{operator+=}{time_point}%
\begin{itemdecl}
constexpr time_point& operator+=(const duration& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{d_ += d}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{time_point}%
\begin{itemdecl}
constexpr time_point& operator-=(const duration& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{d_ -= d}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\rSec2[time.point.special]{Special values}

\indexlibrarymember{min}{time_point}%
\begin{itemdecl}
static constexpr time_point min() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{time_point(duration::min())}.
\end{itemdescr}

\indexlibrarymember{max}{time_point}%
\begin{itemdecl}
static constexpr time_point max() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{time_point(duration::max())}.
\end{itemdescr}

\rSec2[time.point.nonmember]{Non-member arithmetic}

\indexlibrarymember{operator+}{time_point}%
\indexlibrarymember{operator+}{duration}%
\begin{itemdecl}
template<class Clock, class Duration1, class Rep2, class Period2>
  constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
    operator+(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{CT(lhs.time_since_epoch() + rhs)}, where \tcode{CT} is the type of the return value.
\end{itemdescr}

\indexlibrarymember{operator+}{time_point}%
\indexlibrarymember{operator+}{duration}%
\begin{itemdecl}
template<class Rep1, class Period1, class Clock, class Duration2>
  constexpr time_point<Clock, common_type_t<duration<Rep1, Period1>, Duration2>>
    operator+(const duration<Rep1, Period1>& lhs, const time_point<Clock, Duration2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{rhs + lhs}.
\end{itemdescr}

\indexlibrarymember{operator-}{time_point}%
\indexlibrarymember{operator-}{duration}%
\begin{itemdecl}
template<class Clock, class Duration1, class Rep2, class Period2>
  constexpr time_point<Clock, common_type_t<Duration1, duration<Rep2, Period2>>>
    operator-(const time_point<Clock, Duration1>& lhs, const duration<Rep2, Period2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{CT(lhs.time_since_epoch() - rhs)},
where \tcode{CT} is the type of the return value.
\end{itemdescr}

\indexlibrarymember{operator-}{time_point}%
\begin{itemdecl}
template<class Clock, class Duration1, class Duration2>
  constexpr common_type_t<Duration1, Duration2>
    operator-(const time_point<Clock, Duration1>& lhs, const time_point<Clock, Duration2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{lhs.time_since_epoch() - rhs.time_since_epoch()}.
\end{itemdescr}

\rSec2[time.point.comparisons]{Comparisons}

\indexlibrarymember{operator==}{time_point}%
\begin{itemdecl}
template<class Clock, class Duration1, class Duration2>
  constexpr bool operator==(const time_point<Clock, Duration1>& lhs,
                            const time_point<Clock, Duration2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{lhs.time_since_epoch() == rhs.time_since_epoch()}.
\end{itemdescr}

\indexlibrarymember{operator<}{time_point}%
\begin{itemdecl}
template<class Clock, class Duration1, class Duration2>
  constexpr bool operator<(const time_point<Clock, Duration1>& lhs,
                           const time_point<Clock, Duration2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{lhs.time_since_epoch() < rhs.time_since_epoch()}.
\end{itemdescr}

\indexlibrarymember{operator>}{time_point}%
\begin{itemdecl}
template<class Clock, class Duration1, class Duration2>
  constexpr bool operator>(const time_point<Clock, Duration1>& lhs,
                           const time_point<Clock, Duration2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{rhs < lhs}.
\end{itemdescr}

\indexlibrarymember{operator<=}{time_point}%
\begin{itemdecl}
template<class Clock, class Duration1, class Duration2>
  constexpr bool operator<=(const time_point<Clock, Duration1>& lhs,
                            const time_point<Clock, Duration2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!(rhs < lhs)}.
\end{itemdescr}

\indexlibrarymember{operator>=}{time_point}%
\begin{itemdecl}
template<class Clock, class Duration1, class Duration2>
  constexpr bool operator>=(const time_point<Clock, Duration1>& lhs,
                            const time_point<Clock, Duration2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!(lhs < rhs)}.
\end{itemdescr}

\indexlibrarymember{operator>=}{time_point}%
\begin{itemdecl}
template<class Clock, class Duration1,
         @\libconcept{three_way_comparable_with}@<Duration1> Duration2>
  constexpr auto operator<=>(const time_point<Clock, Duration1>& lhs,
                             const time_point<Clock, Duration2>& rhs);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{lhs.time_since_epoch() <=> rhs.time_since_epoch()}.
\end{itemdescr}

\rSec2[time.point.cast]{Conversions}

\indexlibrarymember{time_point}{time_point_cast}%
\indexlibraryglobal{time_point_cast}%
\begin{itemdecl}
template<class ToDuration, class Clock, class Duration>
  constexpr time_point<Clock, ToDuration> time_point_cast(const time_point<Clock, Duration>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ToDuration} is a specialization of \tcode{duration}.

\pnum
\returns
\begin{codeblock}
time_point<Clock, ToDuration>(duration_cast<ToDuration>(t.time_since_epoch()))
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{floor}{time_point}%
\begin{itemdecl}
template<class ToDuration, class Clock, class Duration>
  constexpr time_point<Clock, ToDuration> floor(const time_point<Clock, Duration>& tp);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ToDuration} is a specialization of \tcode{duration}.

\pnum
\returns
\tcode{time_point<Clock, ToDuration>(floor<ToDuration>(tp.time_since_epoch()))}.
\end{itemdescr}

\indexlibrarymember{ceil}{time_point}%
\begin{itemdecl}
template<class ToDuration, class Clock, class Duration>
  constexpr time_point<Clock, ToDuration> ceil(const time_point<Clock, Duration>& tp);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ToDuration} is a specialization of \tcode{duration}.

\pnum
\returns
\tcode{time_point<Clock, ToDuration>(ceil<ToDuration>(tp.time_since_epoch()))}.
\end{itemdescr}

\indexlibrarymember{round}{time_point}%
\begin{itemdecl}
template<class ToDuration, class Clock, class Duration>
  constexpr time_point<Clock, ToDuration> round(const time_point<Clock, Duration>& tp);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{ToDuration} is a specialization of \tcode{duration}, and
\tcode{treat_as_floating_point_v<typename ToDuration::rep>} is \tcode{false}.

\pnum
\returns
\tcode{time_point<Clock, ToDuration>(round<ToDuration>(tp.time_since_epoch()))}.
\end{itemdescr}

\rSec1[time.clock]{Clocks}

\rSec2[time.clock.general]{General}

\pnum
The types defined in \ref{time.clock} meet the
\oldconcept{TrivialClock}
requirements\iref{time.clock.req}
unless otherwise specified.

\rSec2[time.clock.system]{Class \tcode{system_clock}}

\rSec3[time.clock.system.overview]{Overview}
\indexlibraryglobal{system_clock}%

\begin{codeblock}
namespace std::chrono {
  class system_clock {
  public:
    using rep        = @\seebelow@;
    using period     = ratio<@\unspecnc@, @\unspec{}@>;
    using duration   = chrono::duration<rep, period>;
    using time_point = chrono::time_point<system_clock>;
    static constexpr bool is_steady = @\unspec;@

    static time_point now() noexcept;

    // mapping to/from C type \tcode{time_t}
    static time_t     to_time_t  (const time_point& t) noexcept;
    static time_point from_time_t(time_t t) noexcept;
  };
}
\end{codeblock}

\pnum
Objects of type \tcode{system_clock} represent wall clock time from the system-wide
realtime clock.
Objects of type \tcode{sys_time<Duration>} measure time since
1970-01-01 00:00:00 UTC excluding leap seconds.
This measure is commonly referred to as \defn{Unix time}.
This measure facilitates an efficient mapping between
\tcode{sys_time} and calendar types\iref{time.cal}.
\begin{example}
\\
\tcode{sys_seconds\{sys_days\{1970y/January/1\}\}.time_since_epoch()} is \tcode{0s}. \\
\tcode{sys_seconds\{sys_days\{2000y/January/1\}\}.time_since_epoch()} is \tcode{946'684'800s},
which is \tcode{10'957 * 86'400s}. \\
\end{example}

\rSec3[time.clock.system.members]{Members}

\indexlibrarymember{rep}{system_clock}%
\begin{itemdecl}
using system_clock::rep = @\unspec@;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{system_clock::duration::min() < system_clock::duration::zero()} is \tcode{true}.
\begin{note}
This implies that \tcode{rep} is a signed type.
\end{note}
\end{itemdescr}

\indexlibrarymember{to_time_t}{system_clock}%
\begin{itemdecl}
static time_t to_time_t(const time_point& t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{time_t} object that represents the same point in time as \tcode{t}
when both values are restricted to the coarser of the precisions of \tcode{time_t} and
\tcode{time_point}.
It is \impldef{whether values are rounded or truncated to the
required precision when converting between \tcode{time_t} values and \tcode{time_point} objects}
whether values are rounded or truncated to the required precision.
\end{itemdescr}

\indexlibrarymember{from_time_t}{system_clock}%
\begin{itemdecl}
static time_point from_time_t(time_t t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{time_point} object that represents the same point in time as \tcode{t}
when both values are restricted to the coarser of the precisions of \tcode{time_t} and
\tcode{time_point}.
It is \impldef{whether values are rounded or truncated to the
required precision when converting between \tcode{time_t} values and \tcode{time_point} objects}
whether values are rounded or truncated to the required precision.
\end{itemdescr}

\rSec3[time.clock.system.nonmembers]{Non-member functions}

\indexlibrarymember{operator<<}{sys_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const sys_time<Duration>& tp);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{treat_as_floating_point_v<typename Duration::rep>} is \tcode{false}, and
\tcode{Duration\{1\} < days\{1\}} is \tcode{true}.

\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%F %T}"), tp);
\end{codeblock}

\pnum
\begin{example}
\begin{codeblock}
cout << sys_seconds{0s} << '\n';                // 1970-01-01 00:00:00
cout << sys_seconds{946'684'800s} << '\n';      // 2000-01-01 00:00:00
cout << sys_seconds{946'688'523s} << '\n';      // 2000-01-01 01:02:03
\end{codeblock}
\end{example}
\end{itemdescr}

\indexlibrarymember{operator<<}{sys_days}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const sys_days& dp);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{os << year_month_day\{dp\}}.

\pnum
\returns
\tcode{os}.
\end{itemdescr}

\indexlibrarymember{from_stream}{sys_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                sys_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{sys_time} \tcode{tp} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid date,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{tp} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.
Additionally, the parsed offset will be subtracted
from the successfully parsed timestamp
prior to assigning that difference to \tcode{tp}.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.clock.utc]{Class \tcode{utc_clock}}

\rSec3[time.clock.utc.overview]{Overview}
\indexlibraryglobal{utc_clock}%

\begin{codeblock}
namespace std::chrono {
  class utc_clock {
  public:
    using rep                       = @\textit{a signed arithmetic type}@;
    using period                    = ratio<@\unspecnc@, @\unspec@>;
    using duration                  = chrono::duration<rep, period>;
    using time_point                = chrono::time_point<utc_clock>;
    static constexpr bool is_steady = @\unspec@;

    static time_point now();

    template<class Duration>
      static sys_time<common_type_t<Duration, seconds>>
        to_sys(const utc_time<Duration>& t);
    template<class Duration>
      static utc_time<common_type_t<Duration, seconds>>
        from_sys(const sys_time<Duration>& t);
  };
}
\end{codeblock}

\pnum
In contrast to \tcode{sys_time},
which does not take leap seconds into account,
\tcode{utc_clock} and its associated \tcode{time_point}, \tcode{utc_time},
count time, including leap seconds, since 1970-01-01 00:00:00 UTC.
\begin{note}
The UTC time standard began on 1972-01-01 00:00:10 TAI.
To measure time since this epoch instead, one can add/subtract the constant
\tcode{sys_days\{1972y/1/1\} - sys_days\{1970y/1/1\}} (\tcode{63'072'000s})
from the \tcode{utc_time}.
\end{note}
\begin{example}
\\
\tcode{clock_cast<utc_clock>(sys_seconds\{sys_days\{1970y/January/1\}\}).time_since_epoch()} is \tcode{0s}. \\
\tcode{clock_cast<utc_clock>(sys_seconds\{sys_days\{2000y/January/1\}\}).time_since_epoch()} is \tcode{946'684'822s},\\
which is \tcode{10'957 * 86'400s + 22s}. \\
\end{example}

\pnum
\tcode{utc_clock} is not a \oldconcept{TrivialClock}
unless the implementation can guarantee that \tcode{utc_clock::now()}
does not propagate an exception.
\begin{note}
\tcode{noexcept(from_sys(system_clock::now()))} is \tcode{false}.
\end{note}

\rSec3[time.clock.utc.members]{Member functions}

\indexlibrarymember{now}{utc_clock}%
\begin{itemdecl}
static time_point now();
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{from_sys(system_clock::now())}, or a more accurate value of \tcode{utc_time}.
\end{itemdescr}

\indexlibrarymember{to_sys}{utc_clock}%
\begin{itemdecl}
template<class Duration>
  static sys_time<common_type_t<Duration, seconds>>
    to_sys(const utc_time<Duration>& u);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{sys_time} \tcode{t},
such that \tcode{from_sys(t) == u} if such a mapping exists.
Otherwise \tcode{u} represents a \tcode{time_point}
during a positive leap second insertion,
the conversion counts that leap second as not inserted,
and the last representable value of \tcode{sys_time}
prior to the insertion of the leap second is returned.
\end{itemdescr}

\indexlibrarymember{from_sys}{utc_clock}%
\begin{itemdecl}
template<class Duration>
  static utc_time<common_type_t<Duration, seconds>>
    from_sys(const sys_time<Duration>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{utc_time} \tcode{u}, such that
\tcode{u.time_since_epoch() - t.time_since_epoch()}
is equal to the sum of leap seconds that were inserted
between \tcode{t} and 1970-01-01.
If \tcode{t} is exactly the date of leap second insertion,
then the conversion counts that leap second as inserted.

\begin{example}
\begin{codeblock}
auto t = sys_days{July/1/2015} - 2ns;
auto u = utc_clock::from_sys(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
t += 1ns;
u = utc_clock::from_sys(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 25s);
t += 1ns;
u = utc_clock::from_sys(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
t += 1ns;
u = utc_clock::from_sys(t);
assert(u.time_since_epoch() - t.time_since_epoch() == 26s);
\end{codeblock}
\end{example}
\end{itemdescr}

\rSec3[time.clock.utc.nonmembers]{Non-member functions}

\indexlibrarymember{operator<<}{utc_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const utc_time<Duration>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%F %T}"), t);
\end{codeblock}

\pnum
\begin{example}
\begin{codeblock}
auto t = sys_days{July/1/2015} - 500ms;
auto u = clock_cast<utc_clock>(t);
for (auto i = 0; i < 8; ++i, u += 250ms)
  cout << u << " UTC\n";
\end{codeblock}

Produces this output:

\begin{outputblock}
2015-06-30 23:59:59.500 UTC
2015-06-30 23:59:59.750 UTC
2015-06-30 23:59:60.000 UTC
2015-06-30 23:59:60.250 UTC
2015-06-30 23:59:60.500 UTC
2015-06-30 23:59:60.750 UTC
2015-07-01 00:00:00.000 UTC
2015-07-01 00:00:00.250 UTC
\end{outputblock}
\end{example}
\end{itemdescr}

\indexlibrarymember{from_stream}{utc_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                utc_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{utc_time} \tcode{tp} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid date,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{tp} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.
Additionally, the parsed offset will be subtracted from
the successfully parsed timestamp
prior to assigning that difference to \tcode{tp}.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\indexlibraryglobal{leap_second_info}%
\begin{itemdecl}
struct leap_second_info {
  bool    is_leap_second;
  seconds elapsed;
};
\end{itemdecl}

\begin{itemdescr}
\pnum
The type \tcode{leap_second_info}
has data members and special members specified above.
It has no base classes or members other than those specified.
\end{itemdescr}

\indexlibraryglobal{get_leap_second_info}%
\begin{itemdecl}
template<class Duration>
  leap_second_info get_leap_second_info(const utc_time<Duration>& ut);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{leap_second_info} \tcode{lsi},
where \tcode{lsi.is_leap_second} is \tcode{true}
if \tcode{ut} is during a positive leap second insertion, and
otherwise \tcode{false}.
\tcode{lsi.elapsed} is the sum of leap seconds between 1970-01-01 and \tcode{ut}.
If \tcode{lsi.is_leap_second} is \tcode{true},
the leap second referred to by \tcode{ut} is included in the sum.
\end{itemdescr}

\rSec2[time.clock.tai]{Class \tcode{tai_clock}}

\rSec3[time.clock.tai.overview]{Overview}
\indexlibraryglobal{tai_clock}%

\begin{codeblock}
namespace std::chrono {
  class tai_clock {
  public:
    using rep                       = @\textit{a signed arithmetic type}@;
    using period                    = ratio<@\unspecnc@, @\unspec@>;
    using duration                  = chrono::duration<rep, period>;
    using time_point                = chrono::time_point<tai_clock>;
    static constexpr bool is_steady = @\unspec@;

    static time_point now();

    template<class Duration>
      static utc_time<common_type_t<Duration, seconds>>
        to_utc(const tai_time<Duration>&) noexcept;
    template<class Duration>
      static tai_time<common_type_t<Duration, seconds>>
        from_utc(const utc_time<Duration>&) noexcept;
  };
}
\end{codeblock}

\pnum
The clock \tcode{tai_clock} measures seconds since 1958-01-01 00:00:00
and is offset 10s ahead of UTC at this date.
That is, 1958-01-01 00:00:00 TAI is equivalent to 1957-12-31 23:59:50 UTC\@.
Leap seconds are not inserted into TAI\@.
Therefore every time a leap second is inserted into UTC,
UTC shifts another second with respect to TAI\@.
For example by 2000-01-01 there had been
22 positive and 0 negative leap seconds inserted
so 2000-01-01 00:00:00 UTC is equivalent to 2000-01-01 00:00:32 TAI
(22s plus the initial 10s offset).

\pnum
\tcode{tai_clock} is not a \oldconcept{TrivialClock}
unless the implementation can guarantee that \tcode{tai_clock::now()}
does not propagate an exception.
\begin{note}
\tcode{noexcept(from_utc(utc_clock::now()))} is \tcode{false}.
\end{note}

\rSec3[time.clock.tai.members]{Member functions}

\indexlibrarymember{now}{tai_clock}%
\begin{itemdecl}
static time_point now();
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{from_utc(utc_clock::now())}, or a more accurate value of \tcode{tai_time}.
\end{itemdescr}

\indexlibrarymember{to_utc}{tai_clock}%
\begin{itemdecl}
template<class Duration>
  static utc_time<common_type_t<Duration, seconds>>
    to_utc(const tai_time<Duration>& t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 378691210s
\end{codeblock}
\begin{note}
\begin{codeblock}
378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s
\end{codeblock}
\end{note}
\end{itemdescr}

\indexlibrarymember{from_utc}{tai_clock}%
\begin{itemdecl}
template<class Duration>
  static tai_time<common_type_t<Duration, seconds>>
    from_utc(const utc_time<Duration>& t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
tai_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 378691210s
\end{codeblock}
\begin{note}
\begin{codeblock}
378691210s == sys_days{1970y/January/1} - sys_days{1958y/January/1} + 10s
\end{codeblock}
\end{note}
\end{itemdescr}

\rSec3[time.clock.tai.nonmembers]{Non-member functions}

\indexlibrarymember{operator<<}{tai_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const tai_time<Duration>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%F %T}"), t);
\end{codeblock}

\pnum
\begin{example}
% FIXME: This example is not an example of this function.
\begin{codeblock}
auto st = sys_days{2000y/January/1};
auto tt = clock_cast<tai_clock>(st);
cout << format("{0:%F %T %Z} == {1:%F %T %Z}\n", st, tt);
\end{codeblock}

Produces this output:

\begin{outputblock}
2000-01-01 00:00:00 UTC == 2000-01-01 00:00:32 TAI
\end{outputblock}
\end{example}
\end{itemdescr}

\indexlibrarymember{from_stream}{tai_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                tai_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{tai_time} \tcode{tp} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid date,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{tp} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.
Additionally, the parsed offset will be subtracted from
the successfully parsed timestamp prior to assigning that difference to \tcode{tp}.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.clock.gps]{Class \tcode{gps_clock}}

\rSec3[time.clock.gps.overview]{Overview}
\indexlibraryglobal{gps_clock}%

\begin{codeblock}
namespace std::chrono {
  class gps_clock {
  public:
    using rep                       = @\textit{a signed arithmetic type}@;
    using period                    = ratio<@\unspecnc@, @\unspec@>;
    using duration                  = chrono::duration<rep, period>;
    using time_point                = chrono::time_point<gps_clock>;
    static constexpr bool is_steady = @\unspec@;

    static time_point now();

    template<class Duration>
      static utc_time<common_type_t<Duration, seconds>>
        to_utc(const gps_time<Duration>&) noexcept;
    template<class Duration>
      static gps_time<common_type_t<Duration, seconds>>
        from_utc(const utc_time<Duration>&) noexcept;
  };
}
\end{codeblock}

\pnum
The clock \tcode{gps_clock} measures
seconds since the first Sunday of January, 1980 00:00:00 UTC\@.
Leap seconds are not inserted into GPS\@.
Therefore every time a leap second is inserted into UTC,
UTC shifts another second with respect to GPS\@.
Aside from the offset from \tcode{1958y/January/1} to \tcode{1980y/January/Sunday[1]},
GPS is behind TAI by 19s due to the 10s offset between 1958 and 1970
and the additional 9 leap seconds inserted between 1970 and 1980.

\pnum
\tcode{gps_clock} is not a \oldconcept{TrivialClock}
unless the implementation can guarantee that
\tcode{gps_clock::now()} does not propagate an exception.
\begin{note}
\tcode{noexcept(from_utc(utc_clock::now()))} is \tcode{false}.
\end{note}

\rSec3[time.clock.gps.members]{Member functions}

\indexlibrarymember{now}{gps_clock}%
\begin{itemdecl}
static time_point now();
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{from_utc(utc_clock::now())}, or a more accurate value of \tcode{gps_time}.
\end{itemdescr}

\indexlibrarymember{to_utc}{gps_clock}%
\begin{itemdecl}
template<class Duration>
  static utc_time<common_type_t<Duration, seconds>>
    to_utc(const gps_time<Duration>& t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
utc_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} + 315964809s
\end{codeblock}
\begin{note}
\begin{codeblock}
315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s
\end{codeblock}
\end{note}
\end{itemdescr}

\indexlibrarymember{from_utc}{gps_clock}%
\begin{itemdecl}
template<class Duration>
  static gps_time<common_type_t<Duration, seconds>>
    from_utc(const utc_time<Duration>& t) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
gps_time<common_type_t<Duration, seconds>>{t.time_since_epoch()} - 315964809s
\end{codeblock}
\begin{note}
\begin{codeblock}
315964809s == sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1} + 9s
\end{codeblock}
\end{note}
\end{itemdescr}

\rSec3[time.clock.gps.nonmembers]{Non-member functions}

\indexlibrarymember{operator<<}{gps_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const gps_time<Duration>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%F %T}"), t);
\end{codeblock}

\pnum
% FIXME: This example is not an example of this function.
\begin{example}
\begin{codeblock}
auto st = sys_days{2000y/January/1};
auto gt = clock_cast<gps_clock>(st);
cout << format("{0:%F %T %Z} == {1:%F %T %Z}\n", st, gt);
\end{codeblock}

Produces this output:

\begin{outputblock}
2000-01-01 00:00:00 UTC == 2000-01-01 00:00:13 GPS
\end{outputblock}
\end{example}
\end{itemdescr}

\indexlibrarymember{from_stream}{gps_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                gps_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{gps_time} \tcode{tp} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid date,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{tp} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.
Additionally, the parsed offset will be subtracted from
the successfully parsed timestamp prior to assigning that difference to \tcode{tp}.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.clock.file]{Type \tcode{file_clock}}

\rSec3[time.clock.file.overview]{Overview}
\indexlibraryglobal{file_clock}%

\begin{codeblock}
namespace std::chrono {
  using file_clock = @\seebelow@;
}
\end{codeblock}

\pnum
\tcode{file_clock} is an alias for a type
meeting the \oldconcept{TrivialClock} requirements\iref{time.clock.req}, and
using a signed arithmetic type for \tcode{file_clock::rep}.
\tcode{file_clock} is used to create the \tcode{time_point} system
used for \tcode{file_time_type}\iref{filesystems}.
Its epoch is unspecified, and
\tcode{noexcept(file_clock::now())} is \tcode{true}.
\begin{note}
The type that \tcode{file_clock} denotes can be
in a different namespace than \tcode{std::chrono},
such as \tcode{std::file\-sys\-tem}.
\end{note}

\rSec3[time.clock.file.members]{Member functions}

\indexlibrarymember{now}{file_clock}%
\pnum
The type denoted by \tcode{file_clock} provides
precisely one of the following two sets of static member functions:

\begin{codeblock}
template<class Duration>
  static sys_time<@\seebelow@>
    to_sys(const file_time<Duration>&);
template<class Duration>
  static file_time<@\seebelow@>
    from_sys(const sys_time<Duration>&);
\end{codeblock}

or:

\begin{codeblock}
template<class Duration>
  static utc_time<@\seebelow@>
    to_utc(const file_time<Duration>&);
template<class Duration>
  static file_time<@\seebelow@>
    from_utc(const utc_time<Duration>&);
\end{codeblock}

These member functions shall provide \tcode{time_point} conversions
consistent with those specified by
\tcode{utc_clock}, \tcode{tai_clock}, and \tcode{gps_clock}.
The \tcode{Duration} of the resultant \tcode{time_point}
is computed from the \tcode{Duration} of the input \tcode{time_point}.

\rSec3[time.clock.file.nonmembers]{Non-member functions}

\indexlibrarymember{operator<<}{file_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const file_time<Duration>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%F %T}"), t);
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{from_stream}{file_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                file_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{file_time} \tcode{tp} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid date,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{tp} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.
Additionally, the parsed offset will be subtracted from
the successfully parsed timestamp prior to assigning that difference to \tcode{tp}.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.clock.steady]{Class \tcode{steady_clock}}
\indexlibraryglobal{steady_clock}%

\begin{codeblock}
namespace std::chrono {
  class steady_clock {
  public:
    using rep        = @\unspec@;
    using period     = ratio<@\unspecnc@, @\unspec{}@>;
    using duration   = chrono::duration<rep, period>;
    using time_point = chrono::time_point<@\unspecnc@, duration>;
    static constexpr bool is_steady = true;

    static time_point now() noexcept;
  };
}
\end{codeblock}

\pnum
Objects of class \tcode{steady_clock} represent clocks for which values of \tcode{time_point}
never decrease as physical time advances and for which values of \tcode{time_point} advance at
a steady rate relative to real time. That is, the clock may not be adjusted.

\rSec2[time.clock.hires]{Class \tcode{high_resolution_clock}}
\indexlibraryglobal{high_resolution_clock}%

\begin{codeblock}
namespace std::chrono {
  class high_resolution_clock {
  public:
    using rep        = @\unspec@;
    using period     = ratio<@\unspecnc@, @\unspec{}@>;
    using duration   = chrono::duration<rep, period>;
    using time_point = chrono::time_point<@\unspecnc@, duration>;
    static constexpr bool is_steady = @\unspec@;

    static time_point now() noexcept;
  };
}
\end{codeblock}

\pnum
Objects of class \tcode{high_resolution_clock} represent clocks with the
shortest tick period. \tcode{high_resolution_clock} may be a synonym for
\tcode{system_clock} or \tcode{steady_clock}.

\rSec2[time.clock.local]{Local time}
\indexlibraryglobal{local_time}%

\pnum
The family of time points
denoted by \tcode{local_time<Duration>}
are based on the pseudo clock \tcode{local_t}.
\tcode{local_t} has no member \tcode{now()}
and thus does not meet the clock requirements.
Nevertheless \tcode{local_time<Duration>} serves the vital role of
representing local time with respect to a not-yet-specified time zone.
Aside from being able to get the current time,
the complete \tcode{time_point} algebra is available
for \tcode{local_time<Duration>} (just as for \tcode{sys_time<Duration>}).

\indexlibrarymember{operator<<}{local_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const local_time<Duration>& lt);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{os << sys_time<Duration>{lt.time_since_epoch()}} is a valid expression.

\pnum
\effects
\begin{codeblock}
os << sys_time<Duration>{lt.time_since_epoch()};
\end{codeblock}

\pnum
\returns
\tcode{os}.
\end{itemdescr}

\indexlibrarymember{from_stream}{local_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                local_time<Duration>& tp, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{local_time} \tcode{tp} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid date,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{tp} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.clock.cast]{\tcode{time_point} conversions}

\rSec3[time.clock.conv]{Class template \tcode{clock_time_conversion}}
\indexlibraryglobal{clock_time_conversion}%

\begin{codeblock}
namespace std::chrono {
  template<class DestClock, class SourceClock>
  struct clock_time_conversion {};
}
\end{codeblock}

\pnum
\tcode{clock_time_conversion} serves as a trait
which can be used to specify how to convert
a source \tcode{time_point} of type
\tcode{time_point<SourceClock, Duration>}
to a destination \tcode{time_point} of type
\tcode{time_point<DestClock, Duration>}
via a specialization:
\tcode{clock_time_conversion<DestClock, SourceClock>}.
A specialization of \tcode{clock_time_conversion<DestClock, SourceClock>}
shall provide a const-qualified \tcode{operator()}
that takes a parameter of type \tcode{time_point<SourceClock, Duration>}
and returns a \tcode{time_point<DestClock, OtherDuration>}
representing an equivalent point in time.
\tcode{OtherDuration} is a \tcode{chrono::duration}
whose specialization is computed from the input \tcode{Duration}
in a manner which can vary for each \tcode{clock_time_conversion} specialization.
A program may specialize \tcode{clock_time_conversion}
if at least one of the template parameters is a user-defined clock type.

\pnum
Several specializations are provided by the implementation,
as described in
\ref{time.clock.cast.id},
\ref{time.clock.cast.sys.utc},
\ref{time.clock.cast.sys}, and
\ref{time.clock.cast.utc}.

\rSec3[time.clock.cast.id]{Identity conversions}

\begin{codeblock}
template<class Clock>
struct clock_time_conversion<Clock, Clock> {
  template<class Duration>
    time_point<Clock, Duration>
      operator()(const time_point<Clock, Duration>& t) const;
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  time_point<Clock, Duration>
    operator()(const time_point<Clock, Duration>& t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{t}.
\end{itemdescr}

\begin{codeblock}
template<>
struct clock_time_conversion<system_clock, system_clock> {
  template<class Duration>
    sys_time<Duration>
      operator()(const sys_time<Duration>& t) const;
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  sys_time<Duration>
    operator()(const sys_time<Duration>& t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{t}.
\end{itemdescr}

\begin{codeblock}
template<>
struct clock_time_conversion<utc_clock, utc_clock> {
  template<class Duration>
    utc_time<Duration>
      operator()(const utc_time<Duration>& t) const;
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  utc_time<Duration>
    operator()(const utc_time<Duration>& t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{t}.
\end{itemdescr}

\rSec3[time.clock.cast.sys.utc]{Conversions between \tcode{system_clock} and \tcode{utc_clock}}

\begin{codeblock}
template<>
struct clock_time_conversion<utc_clock, system_clock> {
  template<class Duration>
    utc_time<common_type_t<Duration, seconds>>
      operator()(const sys_time<Duration>& t) const;
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  utc_time<common_type_t<Duration, seconds>>
    operator()(const sys_time<Duration>& t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{utc_clock::from_sys(t)}.
\end{itemdescr}

\begin{codeblock}
template<>
struct clock_time_conversion<system_clock, utc_clock> {
  template<class Duration>
    sys_time<common_type_t<Duration, seconds>>
      operator()(const utc_time<Duration>& t) const;
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  sys_time<common_type_t<Duration, seconds>>
    operator()(const utc_time<Duration>& t) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{utc_clock::to_sys(t)}.
\end{itemdescr}

\rSec3[time.clock.cast.sys]{Conversions between \tcode{system_clock} and other clocks}

\begin{codeblock}
template<class SourceClock>
struct clock_time_conversion<system_clock, SourceClock> {
  template<class Duration>
    auto operator()(const time_point<SourceClock, Duration>& t) const
      -> decltype(SourceClock::to_sys(t));
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  auto operator()(const time_point<SourceClock, Duration>& t) const
    -> decltype(SourceClock::to_sys(t));
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{SourceClock::to_sys(t)} is well-formed.

\pnum
\mandates
\tcode{SourceClock::to_sys(t)} returns a \tcode{sys_time<Duration2>}
for some type \tcode{Duration2}\iref{time.point.general}.

\pnum
\returns
\tcode{SourceClock::to_sys(t)}.
\end{itemdescr}

\begin{codeblock}
template<class DestClock>
struct clock_time_conversion<DestClock, system_clock> {
  template<class Duration>
    auto operator()(const sys_time<Duration>& t) const
      -> decltype(DestClock::from_sys(t));
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  auto operator()(const sys_time<Duration>& t) const
    -> decltype(DestClock::from_sys(t));
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{DestClock::from_sys(t)} is well-formed.

\pnum
\mandates
\tcode{DestClock::from_sys(t)} returns a \tcode{time_point<DestClock, Duration2>}
for some type \tcode{Duration2}\iref{time.point.general}.

\pnum
\returns
\tcode{DestClock::from_sys(t)}.
\end{itemdescr}

\rSec3[time.clock.cast.utc]{Conversions between \tcode{utc_clock} and other clocks}

\begin{codeblock}
template<class SourceClock>
struct clock_time_conversion<utc_clock, SourceClock> {
  template<class Duration>
    auto operator()(const time_point<SourceClock, Duration>& t) const
      -> decltype(SourceClock::to_utc(t));
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  auto operator()(const time_point<SourceClock, Duration>& t) const
    -> decltype(SourceClock::to_utc(t));
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{SourceClock::to_utc(t)} is well-formed.

\pnum
\mandates
\tcode{SourceClock::to_utc(t)}  returns a \tcode{utc_time<Duration2>}
for some type \tcode{Duration2}\iref{time.point.general}.

\pnum
\returns
\tcode{SourceClock::to_utc(t)}.
\end{itemdescr}

\begin{codeblock}
template<class DestClock>
struct clock_time_conversion<DestClock, utc_clock> {
  template<class Duration>
    auto operator()(const utc_time<Duration>& t) const
      -> decltype(DestClock::from_utc(t));
};
\end{codeblock}

\indexlibrarymember{operator()}{clock_time_conversion}%
\begin{itemdecl}
template<class Duration>
  auto operator()(const utc_time<Duration>& t) const
    -> decltype(DestClock::from_utc(t));
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{DestClock::from_utc(t)} is well-formed.

\pnum
\mandates
\tcode{DestClock::from_utc(t)} returns a \tcode{time_point<DestClock, Duration2>}
for some type \tcode{Duration2}\iref{time.point.general}.

\pnum
\returns
\tcode{DestClock::from_utc(t)}.
\end{itemdescr}

\rSec3[time.clock.cast.fn]{Function template \tcode{clock_cast}}

\indexlibraryglobal{clock_cast}%
\begin{itemdecl}
template<class DestClock, class SourceClock, class Duration>
  auto clock_cast(const time_point<SourceClock, Duration>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
At least one of the following clock time conversion expressions
is well-formed:

\begin{itemize}
\item
\begin{codeblock}
clock_time_conversion<DestClock, SourceClock>{}(t)
\end{codeblock}

\item
\begin{codeblock}
clock_time_conversion<DestClock, system_clock>{}(
  clock_time_conversion<system_clock, SourceClock>{}(t))
\end{codeblock}

\item
\begin{codeblock}
clock_time_conversion<DestClock, utc_clock>{}(
  clock_time_conversion<utc_clock, SourceClock>{}(t))
\end{codeblock}

\item
\begin{codeblock}
clock_time_conversion<DestClock, utc_clock>{}(
  clock_time_conversion<utc_clock, system_clock>{}(
    clock_time_conversion<system_clock, SourceClock>{}(t)))
\end{codeblock}

\item
\begin{codeblock}
clock_time_conversion<DestClock, system_clock>{}(
  clock_time_conversion<system_clock, utc_clock>{}(
    clock_time_conversion<utc_clock, SourceClock>{}(t)))
\end{codeblock}
\end{itemize}

A clock time conversion expression is considered better than
another clock time conversion expression if it involves fewer
\tcode{operator()} calls on \tcode{clock_time_conversion}
specializations.

\pnum
\mandates
Among the well-formed clock time conversion expressions
from the above list, there is a unique best expression.

\pnum
\returns
The best well-formed clock time conversion expression in the above list.
\end{itemdescr}

\rSec1[time.cal]{The civil calendar}

\rSec2[time.cal.general]{General}

\pnum
The types in \ref{time.cal} describe the civil (Gregorian) calendar
and its relationship to \tcode{sys_days} and \tcode{local_days}.

\rSec2[time.cal.last]{Class \tcode{last_spec}}
\indexlibraryglobal{last_spec}%

\begin{codeblock}
namespace std::chrono {
  struct last_spec {
    explicit last_spec() = default;
  };
}
\end{codeblock}

\pnum
The type \tcode{last_spec} is used
in conjunction with other calendar types
to specify the last in a sequence.
For example, depending on context,
it can represent the last day of a month,
or the last day of the week of a month.

\rSec2[time.cal.day]{Class \tcode{day}}

\rSec3[time.cal.day.overview]{Overview}
\indexlibraryglobal{day}

\begin{codeblock}
namespace std::chrono {
  class day {
    unsigned char d_;           // \expos
  public:
    day() = default;
    constexpr explicit day(unsigned d) noexcept;

    constexpr day& operator++()    noexcept;
    constexpr day  operator++(int) noexcept;
    constexpr day& operator--()    noexcept;
    constexpr day  operator--(int) noexcept;

    constexpr day& operator+=(const days& d) noexcept;
    constexpr day& operator-=(const days& d) noexcept;

    constexpr explicit operator unsigned() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{day} represents a day of a month.
It normally holds values in the range 1 to 31,
but may hold non-negative values outside this range.
It can be constructed with any \tcode{unsigned} value,
which will be subsequently truncated to fit into \tcode{day}'s unspecified internal storage.
\tcode{day} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable})
and \oldconcept{LessThanComparable} (\tref{cpp17.lessthancomparable}) requirements,
and participates in basic arithmetic with \tcode{days} objects,
which represent a difference between two \tcode{day} objects.

\pnum
\tcode{day} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.day.members]{Member functions}

\indexlibraryctor{day}%
\begin{itemdecl}
constexpr explicit day(unsigned d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{d_} with \tcode{d}.
The value held is unspecified if \tcode{d} is not in the range \crange{0}{255}.
\end{itemdescr}

\indexlibrarymember{operator++}{day}%
\begin{itemdecl}
constexpr day& operator++() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{++d_}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator++}{day}%
\begin{itemdecl}
constexpr day operator++(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{++(*this)}.

\pnum
\returns
A copy of \tcode{*this} as it existed on entry to this member function.
\end{itemdescr}

\indexlibrarymember{operator--}{day}%
\begin{itemdecl}
constexpr day& operator--() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to: \tcode{--d_}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator--}{day}%
\begin{itemdecl}
constexpr day operator--(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{--(*this)}.

\pnum
\returns
A copy of \tcode{*this} as it existed on entry to this member function.
\end{itemdescr}

\indexlibrarymember{operator+=}{day}%
\begin{itemdecl}
constexpr day& operator+=(const days& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + d}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{day}%
\begin{itemdecl}
constexpr day& operator-=(const days& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - d}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator unsigned}{day}%
\begin{itemdecl}
constexpr explicit operator unsigned() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{d_}.
\end{itemdescr}

\indexlibrarymember{ok}{day}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{1 <= d_ \&\& d_ <= 31}.
\end{itemdescr}

\rSec3[time.cal.day.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{day}%
\begin{itemdecl}
constexpr bool operator==(const day& x, const day& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{unsigned\{x\} == unsigned\{y\}}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{day}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const day& x, const day& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{unsigned\{x\} <=> unsigned\{y\}}.
\end{itemdescr}

\indexlibrarymember{operator+}{day}%
\begin{itemdecl}
constexpr day operator+(const day& x, const days& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{day(unsigned\{x\} + y.count())}.
\end{itemdescr}

\indexlibrarymember{operator+}{day}%
\begin{itemdecl}
constexpr day operator+(const days& x, const day& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y + x}.
\end{itemdescr}

\indexlibrarymember{operator-}{day}%
\begin{itemdecl}
constexpr day operator-(const day& x, const days& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x + -y}.
\end{itemdescr}

\indexlibrarymember{operator-}{day}%
\begin{itemdecl}
constexpr days operator-(const day& x, const day& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{days\{int(unsigned\{x\}) - int(unsigned\{y\})\}}.
\end{itemdescr}

\indexlibrarymember{operator<<}{day}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const day& d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << (d.ok() ?
  format(@\placeholder{STATICALLY-WIDEN}@<charT>("{:%d}"), d) :
  format(@\placeholder{STATICALLY-WIDEN}@<charT>("{:%d} is not a valid day"), d));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{from_stream}{day}%
\begin{itemdecl}
template<class charT, class traits, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                day& d, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{day} \tcode{d} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid day,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{d} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\indexlibrarymember{operator""""d}{day}%
\begin{itemdecl}
constexpr chrono::day operator""d(unsigned long long d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{day\{static_cast<unsigned>(d)\}}.
\end{itemdescr}

\rSec2[time.cal.month]{Class \tcode{month}}

\rSec3[time.cal.month.overview]{Overview}
\indexlibraryglobal{month}

\begin{codeblock}
namespace std::chrono {
  class month {
    unsigned char m_;           // \expos
  public:
    month() = default;
    constexpr explicit month(unsigned m) noexcept;

    constexpr month& operator++()    noexcept;
    constexpr month  operator++(int) noexcept;
    constexpr month& operator--()    noexcept;
    constexpr month  operator--(int) noexcept;

    constexpr month& operator+=(const months& m) noexcept;
    constexpr month& operator-=(const months& m) noexcept;

    constexpr explicit operator unsigned() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{month} represents a month of a year.
It normally holds values in the range 1 to 12,
but may hold non-negative values outside this range.
It can be constructed with any \tcode{unsigned} value,
which will be subsequently truncated to fit into \tcode{month}'s unspecified internal storage.
\tcode{month} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable})
and \oldconcept{LessThanComparable} (\tref{cpp17.lessthancomparable}) requirements,
and participates in basic arithmetic with \tcode{months} objects,
which represent a difference between two \tcode{month} objects.

\pnum
\tcode{month} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.month.members]{Member functions}

\indexlibraryctor{month}%
\begin{itemdecl}
constexpr explicit month(unsigned m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{m_} with \tcode{m}.
The value held is unspecified if \tcode{m} is not in the range \crange{0}{255}.
\end{itemdescr}

\indexlibrarymember{operator++}{month}%
\begin{itemdecl}
constexpr month& operator++() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this += months\{1\}}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator++}{month}%
\begin{itemdecl}
constexpr month operator++(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{++(*this)}.

\pnum
\returns
A copy of \tcode{*this} as it existed on entry to this member function.
\end{itemdescr}

\indexlibrarymember{operator--}{month}%
\begin{itemdecl}
constexpr month& operator--() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this -= months\{1\}}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator--}{month}%
\begin{itemdecl}
constexpr month operator--(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{--(*this)}.

\pnum
\returns
A copy of \tcode{*this} as it existed on entry to this member function.
\end{itemdescr}

\indexlibrarymember{operator+=}{month}%
\begin{itemdecl}
constexpr month& operator+=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{month}%
\begin{itemdecl}
constexpr month& operator-=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator unsigned}{month}%
\begin{itemdecl}
constexpr explicit operator unsigned() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{ok}{month}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{1 <= m_ \&\& m_ <= 12}.
\end{itemdescr}

\rSec3[time.cal.month.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{month}%
\begin{itemdecl}
constexpr bool operator==(const month& x, const month& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{unsigned\{x\} == unsigned\{y\}}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{month}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const month& x, const month& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{unsigned\{x\} <=> unsigned\{y\}}.
\end{itemdescr}

\indexlibrarymember{operator+}{month}%
\begin{itemdecl}
constexpr month operator+(const month& x, const months& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
month{modulo(static_cast<long long>(unsigned{x}) + (y.count() - 1), 12) + 1}
\end{codeblock}
where \tcode{modulo(n, 12)} computes the remainder of \tcode{n} divided by 12 using Euclidean division.
\begin{note}
Given a divisor of 12, Euclidean division truncates towards negative infinity and
always produces a remainder in the range of \crange{0}{11}.
Assuming no overflow in the signed summation,
this operation results in a \tcode{month} holding a value in the range \crange{1}{12} even if \tcode{!x.ok()}.
\end{note}
\begin{example}
\tcode{February + months\{11\} == January}.
\end{example}
\end{itemdescr}

\indexlibrarymember{operator+}{month}%
\begin{itemdecl}
constexpr month operator+(const months& x, const month& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y + x}.
\end{itemdescr}

\indexlibrarymember{operator-}{month}%
\begin{itemdecl}
constexpr month operator-(const month& x, const months& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x + -y}.
\end{itemdescr}

\indexlibrarymember{operator-}{month}%
\begin{itemdecl}
constexpr months operator-(const month& x, const month& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{x.ok() == true}
and \tcode{y.ok() == true},
returns a value \tcode{m}
in the range \crange{months\{0\}}{months\{11\}}
satisfying \tcode{y + m == x}.
Otherwise the value returned is unspecified.
\begin{example}
\tcode{January - February == months\{11\}}.
\end{example}
\end{itemdescr}

\indexlibrarymember{operator<<}{month}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const month& m);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << (m.ok() ?
  format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%b}"), m) :
  format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{} is not a valid month"),
         static_cast<unsigned>(m)));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{from_stream}{month}%
\begin{itemdecl}
template<class charT, class traits, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                month& m, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{month} \tcode{m} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid month,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{m} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.cal.year]{Class \tcode{year}}

\rSec3[time.cal.year.overview]{Overview}
\indexlibraryglobal{year}

\begin{codeblock}
namespace std::chrono {
  class year {
    short y_;                   // \expos
  public:
    year() = default;
    constexpr explicit year(int y) noexcept;

    constexpr year& operator++()    noexcept;
    constexpr year  operator++(int) noexcept;
    constexpr year& operator--()    noexcept;
    constexpr year  operator--(int) noexcept;

    constexpr year& operator+=(const years& y) noexcept;
    constexpr year& operator-=(const years& y) noexcept;

    constexpr year operator+() const noexcept;
    constexpr year operator-() const noexcept;

    constexpr bool is_leap() const noexcept;

    constexpr explicit operator int() const noexcept;
    constexpr bool ok() const noexcept;

    static constexpr year min() noexcept;
    static constexpr year max() noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{year} represents a year in the civil calendar.
It can represent values in the range \crange{min()}{max()}.
It can be constructed with any \tcode{int} value,
which will be subsequently truncated to fit into \tcode{year}'s unspecified internal storage.
\tcode{year} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable})
and \oldconcept{LessThanComparable} (\tref{cpp17.lessthancomparable}) requirements,
and participates in basic arithmetic with \tcode{years} objects,
which represent a difference between two \tcode{year} objects.

\pnum
\tcode{year} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.year.members]{Member functions}

\indexlibraryctor{year}%
\begin{itemdecl}
constexpr explicit year(int y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{y_} with \tcode{y}.
The value held is unspecified if \tcode{y} is not in the range \crange{-32767}{32767}.
\end{itemdescr}

\indexlibrarymember{operator++}{year}%
\begin{itemdecl}
constexpr year& operator++() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{++y_}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator++}{year}%
\begin{itemdecl}
constexpr year operator++(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{++(*this)}.

\pnum
\returns
A copy of \tcode{*this} as it existed on entry to this member function.
\end{itemdescr}

\indexlibrarymember{operator--}{year}%
\begin{itemdecl}
constexpr year& operator--() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{--y_}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator--}{year}%
\begin{itemdecl}
constexpr year operator--(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{--(*this)}.

\pnum
\returns
A copy of \tcode{*this} as it existed on entry to this member function.
\end{itemdescr}

\indexlibrarymember{operator+=}{year}%
\begin{itemdecl}
constexpr year& operator+=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year}%
\begin{itemdecl}
constexpr year& operator-=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator+}{year}%
\begin{itemdecl}
constexpr year operator+() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-}{year}%
\begin{itemdecl}
constexpr year operator-() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year\{-y_\}}.
\end{itemdescr}

\indexlibrarymember{is_leap}{year}%
\begin{itemdecl}
constexpr bool is_leap() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_ \% 4 == 0 \&\& (y_ \% 100 != 0 || y_ \% 400 == 0)}.
\end{itemdescr}

\indexlibrarymember{operator int}{year}%
\begin{itemdecl}
constexpr explicit operator int() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_}.
\end{itemdescr}

\indexlibrarymember{ok}{year}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{min().y_ <= y_ \&\& y_ <= max().y_}.
\end{itemdescr}

\indexlibrarymember{min}{year}%
\begin{itemdecl}
static constexpr year min() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year\{-32767\}}.
\end{itemdescr}

\indexlibrarymember{max}{year}%
\begin{itemdecl}
static constexpr year max() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year\{32767\}}.
\end{itemdescr}

\rSec3[time.cal.year.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{year}%
\begin{itemdecl}
constexpr bool operator==(const year& x, const year& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{int\{x\} == int\{y\}}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{year}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const year& x, const year& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{int\{x\} <=> int\{y\}}.
\end{itemdescr}

\indexlibrarymember{operator+}{year}%
\begin{itemdecl}
constexpr year operator+(const year& x, const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year\{int\{x\} + static_cast<int>(y.count())\}}.
\end{itemdescr}

\indexlibrarymember{operator+}{year}%
\begin{itemdecl}
constexpr year operator+(const years& x, const year& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y + x}.
\end{itemdescr}

\indexlibrarymember{operator-}{year}%
\begin{itemdecl}
constexpr year operator-(const year& x, const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x + -y}.
\end{itemdescr}

\indexlibrarymember{operator-}{year}%
\begin{itemdecl}
constexpr years operator-(const year& x, const year& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{years\{int\{x\} - int\{y\}\}}.
\end{itemdescr}

\indexlibrarymember{operator<<}{year}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const year& y);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << (y.ok() ?
  format(@\placeholder{STATICALLY-WIDEN}@<charT>("{:%Y}"), y) :
  format(@\placeholder{STATICALLY-WIDEN}@<charT>("{:%Y} is not a valid year"), y));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{from_stream}{year}%
\begin{itemdecl}
template<class charT, class traits, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                year& y, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{year} \tcode{y} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid year,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{y} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\indexlibrarymember{operator""""y}{year}%
\begin{itemdecl}
constexpr chrono::year operator""y(unsigned long long y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year\{static_cast<int>(y)\}}.
\end{itemdescr}

\rSec2[time.cal.wd]{Class \tcode{weekday}}

\rSec3[time.cal.wd.overview]{Overview}
\indexlibraryglobal{weekday}

\begin{codeblock}
namespace std::chrono {
  class weekday {
    unsigned char wd_;          // \expos
  public:
    weekday() = default;
    constexpr explicit weekday(unsigned wd) noexcept;
    constexpr weekday(const sys_days& dp) noexcept;
    constexpr explicit weekday(const local_days& dp) noexcept;

    constexpr weekday& operator++()    noexcept;
    constexpr weekday  operator++(int) noexcept;
    constexpr weekday& operator--()    noexcept;
    constexpr weekday  operator--(int) noexcept;

    constexpr weekday& operator+=(const days& d) noexcept;
    constexpr weekday& operator-=(const days& d) noexcept;

    constexpr unsigned c_encoding() const noexcept;
    constexpr unsigned iso_encoding() const noexcept;
    constexpr bool ok() const noexcept;

    constexpr weekday_indexed operator[](unsigned index) const noexcept;
    constexpr weekday_last    operator[](last_spec) const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{weekday} represents a day of the week in the civil calendar.
It normally holds values in the range \tcode{0} to \tcode{6},
corresponding to Sunday through Saturday, but
it may hold non-negative values outside this range.
It can be constructed with any \tcode{unsigned} value,
which will be subsequently truncated to fit into \tcode{weekday}'s unspecified internal storage.
\tcode{weekday} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable}) requirements.
\begin{note}
\tcode{weekday} is not
\oldconcept{LessThanComparable}
because there is no universal consensus on which day is the first day of the week.
\tcode{weekday}'s arithmetic operations treat the days of the week as a circular range,
with no beginning and no end.
\end{note}

\pnum
\tcode{weekday} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.wd.members]{Member functions}

\indexlibraryctor{weekday}%
\begin{itemdecl}
constexpr explicit weekday(unsigned wd) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{wd_} with \tcode{wd == 7 ?\ 0 :\ wd}.
The value held is unspecified if \tcode{wd} is not in the range \crange{0}{255}.
\end{itemdescr}

\indexlibraryctor{weekday}%
\begin{itemdecl}
constexpr weekday(const sys_days& dp) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Computes what day of the week corresponds to the \tcode{sys_days} \tcode{dp},
and initializes that day of the week in \tcode{wd_}.

\pnum
\begin{example}
If \tcode{dp} represents 1970-01-01,
the constructed \tcode{weekday} represents Thursday
by storing \tcode{4} in \tcode{wd_}.
\end{example}
\end{itemdescr}

\indexlibraryctor{weekday}%
\begin{itemdecl}
constexpr explicit weekday(const local_days& dp) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Computes what day of the week corresponds to the \tcode{local_days} \tcode{dp},
and initializes that day of the week in \tcode{wd_}.

\pnum
\ensures
The value is identical to that constructed from
\tcode{sys_days\{dp.time_since_epoch()\}}.
\end{itemdescr}

\indexlibrarymember{operator++}{weekday}%
\begin{itemdecl}
constexpr weekday& operator++() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this += days\{1\}}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator++}{weekday}%
\begin{itemdecl}
constexpr weekday operator++(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{++(*this)}.

\pnum
\returns
A copy of \tcode{*this} as it existed on entry to this member function.
\end{itemdescr}

\indexlibrarymember{operator--}{weekday}%
\begin{itemdecl}
constexpr weekday& operator--() noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this -= days\{1\}}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator--}{weekday}%
\begin{itemdecl}
constexpr weekday operator--(int) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{--(*this)}.

\pnum
\returns
A copy of \tcode{*this} as it existed on entry to this member function.
\end{itemdescr}

\indexlibrarymember{operator+=}{weekday}%
\begin{itemdecl}
constexpr weekday& operator+=(const days& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + d}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{weekday}%
\begin{itemdecl}
constexpr weekday& operator-=(const days& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - d}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{c_encoding}{weekday}%
\begin{itemdecl}
constexpr unsigned c_encoding() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wd_}.
\end{itemdescr}

\indexlibrarymember{iso_encoding}{weekday}%
\begin{itemdecl}
constexpr unsigned iso_encoding() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wd_ == 0u ?\ 7u :\ wd_}.
\end{itemdescr}

\indexlibrarymember{ok}{weekday}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wd_ <= 6}.
\end{itemdescr}

\indexlibrarymember{operator[]}{weekday}%
\begin{itemdecl}
constexpr weekday_indexed operator[](unsigned index) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{*this, index\}}.
\end{itemdescr}

\indexlibrarymember{operator[]}{weekday}%
\begin{itemdecl}
constexpr weekday_last operator[](last_spec) const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{weekday_last\{*this\}}.
\end{itemdescr}

\rSec3[time.cal.wd.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{weekday}%
\begin{itemdecl}
constexpr bool operator==(const weekday& x, const weekday& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.wd_ == y.wd_}.
\end{itemdescr}

\indexlibrarymember{operator+}{weekday}%
\begin{itemdecl}
constexpr weekday operator+(const weekday& x, const days& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
weekday{modulo(static_cast<long long>(x.wd_) + y.count(), 7)}
\end{codeblock}
where \tcode{modulo(n, 7)} computes the remainder of \tcode{n} divided by 7 using Euclidean division.
\begin{note}
Given a divisor of 7, Euclidean division truncates towards negative infinity and
always produces a remainder in the range of \crange{0}{6}.
Assuming no overflow in the signed summation,
this operation results in a \tcode{weekday} holding a value in the range \crange{0}{6} even if \tcode{!x.ok()}.
\end{note}
\begin{example}
\tcode{Monday + days\{6\} == Sunday}.
\end{example}
\end{itemdescr}

\indexlibrarymember{operator+}{weekday}%
\begin{itemdecl}
constexpr weekday operator+(const days& x, const weekday& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y + x}.
\end{itemdescr}

\indexlibrarymember{operator-}{weekday}%
\begin{itemdecl}
constexpr weekday operator-(const weekday& x, const days& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x + -y}.
\end{itemdescr}

\indexlibrarymember{operator-}{weekday}%
\begin{itemdecl}
constexpr days operator-(const weekday& x, const weekday& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{x.ok() == true}
and \tcode{y.ok() == true},
returns a value \tcode{d}
in the range \crange{days\{0\}}{days\{6\}}
satisfying \tcode{y + d == x}.
Otherwise the value returned is unspecified.
\begin{example}
\tcode{Sunday - Monday == days\{6\}}.
\end{example}
\end{itemdescr}

\indexlibrarymember{operator<<}{weekday}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const weekday& wd);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << (wd.ok() ?
  format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%a}"), wd) :
  format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{} is not a valid weekday"),
         static_cast<unsigned>(wd.wd_)));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{from_stream}{weekday}%
\begin{itemdecl}
template<class charT, class traits, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                weekday& wd, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{weekday} \tcode{wd} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid weekday,
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{wd} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.cal.wdidx]{Class \tcode{weekday_indexed}}

\rSec3[time.cal.wdidx.overview]{Overview}
\indexlibraryglobal{weekday_indexed}

\begin{codeblock}
namespace std::chrono {
  class weekday_indexed {
    chrono::weekday  wd_;       // \expos
    unsigned char    index_;    // \expos

  public:
    weekday_indexed() = default;
    constexpr weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept;

    constexpr chrono::weekday weekday() const noexcept;
    constexpr unsigned        index()   const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{weekday_indexed} represents a \tcode{weekday}
and a small index in the range 1 to 5.
This class is used to represent the
first, second, third, fourth, or fifth weekday of a month.

\pnum
\begin{note}
A \tcode{weekday_indexed} object
can be constructed by indexing a \tcode{weekday}
with an \tcode{unsigned}.
\end{note}
\begin{example}
\begin{codeblock}
constexpr auto wdi = Sunday[2]; // \tcode{wdi} is the second Sunday of an as yet unspecified month
static_assert(wdi.weekday() == Sunday);
static_assert(wdi.index() == 2);
\end{codeblock}
\end{example}

\pnum
\tcode{weekday_indexed} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.wdidx.members]{Member functions}

\indexlibraryctor{weekday_indexed}%
\begin{itemdecl}
constexpr weekday_indexed(const chrono::weekday& wd, unsigned index) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{wd_} with \tcode{wd} and \tcode{index_} with \tcode{index}.
The values held are unspecified if \tcode{!wd.ok()} or \tcode{index} is not in the range \crange{0}{7}.
\end{itemdescr}

\indexlibrarymember{weekday}{weekday_indexed}%
\begin{itemdecl}
constexpr chrono::weekday weekday() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wd_}.
\end{itemdescr}

\indexlibrarymember{index}{weekday_indexed}%
\begin{itemdecl}
constexpr unsigned index() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{index_}.
\end{itemdescr}

\indexlibrarymember{ok}{weekday_indexed}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wd_.ok() \&\& 1 <= index_ \&\& index_ <= 5}.
\end{itemdescr}

\rSec3[time.cal.wdidx.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{weekday_indexed}%
\begin{itemdecl}
constexpr bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.weekday() == y.weekday() \&\& x.index() == y.index()}.
\end{itemdescr}

\indexlibrarymember{operator<<}{weekday_indexed}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const weekday_indexed& wdi);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
auto i = wdi.index();
return os << (i >= 1 && i <= 5 ?
  format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L}[{}]"), wdi.weekday(), i) :
  format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L}[{} is not a valid index]"),
         wdi.weekday(), i));
\end{codeblock}
\end{itemdescr}

\rSec2[time.cal.wdlast]{Class \tcode{weekday_last}}

\rSec3[time.cal.wdlast.overview]{Overview}
\indexlibraryglobal{weekday_last}

\begin{codeblock}
namespace std::chrono {
  class weekday_last {
    chrono::weekday wd_;                // \expos

  public:
    constexpr explicit weekday_last(const chrono::weekday& wd) noexcept;

    constexpr chrono::weekday weekday() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{weekday_last} represents the last weekday of a month.

\pnum
\begin{note}
A \tcode{weekday_last} object
can be constructed by indexing a \tcode{weekday} with \tcode{last}.
\end{note}
\begin{example}
\begin{codeblock}
constexpr auto wdl = Sunday[last];      // \tcode{wdl} is the last Sunday of an as yet unspecified month
static_assert(wdl.weekday() == Sunday);
\end{codeblock}
\end{example}

\pnum
\tcode{weekday_last} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.wdlast.members]{Member functions}

\indexlibraryctor{weekday_last}%
\begin{itemdecl}
constexpr explicit weekday_last(const chrono::weekday& wd) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{wd_} with \tcode{wd}.
\end{itemdescr}

\indexlibrarymember{weekday_last}{weekday}%
\begin{itemdecl}
constexpr chrono::weekday weekday() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wd_}.
\end{itemdescr}

\indexlibrarymember{ok}{weekday_last}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wd_.ok()}.
\end{itemdescr}

\rSec3[time.cal.wdlast.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{weekday_last}%
\begin{itemdecl}
constexpr bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.weekday() == y.weekday()}.
\end{itemdescr}

\indexlibrarymember{operator<<}{weekday_last}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const weekday_last& wdl);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L}[last]"), wdl.weekday());
\end{codeblock}
\end{itemdescr}

\rSec2[time.cal.md]{Class \tcode{month_day}}

\rSec3[time.cal.md.overview]{Overview}
\indexlibraryglobal{month_day}

\begin{codeblock}
namespace std::chrono {
  class month_day {
    chrono::month m_;           // \expos
    chrono::day   d_;           // \expos

  public:
    month_day() = default;
    constexpr month_day(const chrono::month& m, const chrono::day& d) noexcept;

    constexpr chrono::month month() const noexcept;
    constexpr chrono::day   day()   const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{month_day} represents a specific day of a specific month,
but with an unspecified year.
\tcode{month_day} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable})
and \oldconcept{LessThanComparable} (\tref{cpp17.lessthancomparable}) requirements.

\pnum
\tcode{month_day} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.md.members]{Member functions}

\indexlibraryctor{month_day}%
\begin{itemdecl}
constexpr month_day(const chrono::month& m, const chrono::day& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{m_} with \tcode{m}, and \tcode{d_} with \tcode{d}.
\end{itemdescr}

\indexlibrarymember{month}{month_day}%
\begin{itemdecl}
constexpr chrono::month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{day}{month_day}%
\begin{itemdecl}
constexpr chrono::day day() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{d_}.
\end{itemdescr}

\indexlibrarymember{ok}{month_day}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{true} if
\tcode{m_.ok()} is \tcode{true},
\tcode{1d <= d_}, and
\tcode{d_} is less than or equal to the number of days in month \tcode{m_};
otherwise returns \tcode{false}.
When \tcode{m_ == February},
the number of days is considered to be 29.
\end{itemdescr}

\rSec3[time.cal.md.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{month_day}%
\begin{itemdecl}
constexpr bool operator==(const month_day& x, const month_day& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.month() == y.month() \&\& x.day() == y.day()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{month_day}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const month_day& x, const month_day& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
if (auto c = x.month() <=> y.month(); c != 0) return c;
return x.day() <=> y.day();
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator<<}{month_day}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const month_day& md);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L}/{}"),
                    md.month(), md.day());
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{from_stream}{month_day}%
\begin{itemdecl}
template<class charT, class traits, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                month_day& md, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{month_day} \tcode{md} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid \tcode{month_day},
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{md} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.cal.mdlast]{Class \tcode{month_day_last}}
\indexlibraryglobal{month_day_last}

\begin{codeblock}
namespace std::chrono {
  class month_day_last {
    chrono::month m_;                   // \expos

  public:
    constexpr explicit month_day_last(const chrono::month& m) noexcept;

    constexpr chrono::month month() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{month_day_last} represents the last day of a month.

\pnum
\begin{note}
A \tcode{month_day_last} object
can be constructed using the expression \tcode{m/last} or \tcode{last/m},
where \tcode{m} is an expression of type \tcode{month}.
\end{note}
\begin{example}
\begin{codeblock}
constexpr auto mdl = February/last;     // \tcode{mdl} is the last day of February of an as yet unspecified year
static_assert(mdl.month() == February);
\end{codeblock}
\end{example}

\pnum
\tcode{month_day_last} is a trivially copyable and standard-layout class type.

\indexlibraryctor{month_day_last}%
\begin{itemdecl}
constexpr explicit month_day_last(const chrono::month& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{m_} with \tcode{m}.
\end{itemdescr}

\indexlibrarymember{month}{month_day_last}%
\begin{itemdecl}
constexpr month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{ok}{month_day_last}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_.ok()}.
\end{itemdescr}

\indexlibrarymember{operator==}{month_day_last}%
\begin{itemdecl}
constexpr bool operator==(const month_day_last& x, const month_day_last& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.month() == y.month()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{month_day_last}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const month_day_last& x, const month_day_last& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.month() <=> y.month()}.
\end{itemdescr}

\indexlibrarymember{operator<<}{month_day_last}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const month_day_last& mdl);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L}/last"), mdl.month());
\end{codeblock}
\end{itemdescr}

\rSec2[time.cal.mwd]{Class \tcode{month_weekday}}

\rSec3[time.cal.mwd.overview]{Overview}
\indexlibraryglobal{month_weekday}

\begin{codeblock}
namespace std::chrono {
  class month_weekday {
    chrono::month           m_;         // \expos
    chrono::weekday_indexed wdi_;       // \expos
  public:
    constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept;

    constexpr chrono::month           month()           const noexcept;
    constexpr chrono::weekday_indexed weekday_indexed() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{month_weekday} represents the $n^\text{th}$ weekday of a month,
of an as yet unspecified year.
To do this the \tcode{month_weekday} stores a \tcode{month} and a \tcode{weekday_indexed}.

\pnum
\begin{example}
\begin{codeblock}
constexpr auto mwd
    = February/Tuesday[3];              // \tcode{mwd} is the third Tuesday of February of an as yet unspecified year
static_assert(mwd.month() == February);
static_assert(mwd.weekday_indexed() == Tuesday[3]);
\end{codeblock}
\end{example}

\pnum
\tcode{month_weekday} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.mwd.members]{Member functions}

\indexlibraryctor{month_weekday}%
\begin{itemdecl}
constexpr month_weekday(const chrono::month& m, const chrono::weekday_indexed& wdi) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{m_} with \tcode{m}, and \tcode{wdi_} with \tcode{wdi}.
\end{itemdescr}

\indexlibrarymember{month}{month_weekday}%
\begin{itemdecl}
constexpr chrono::month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{weekday_indexed}{month_weekday}%
\begin{itemdecl}
constexpr chrono::weekday_indexed weekday_indexed() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wdi_}.
\end{itemdescr}

\indexlibrarymember{ok}{month_weekday}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_.ok() \&\& wdi_.ok()}.
\end{itemdescr}

\rSec3[time.cal.mwd.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{month_weekday}%
\begin{itemdecl}
constexpr bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.month() == y.month() \&\& x.weekday_indexed() == y.weekday_indexed()}.
\end{itemdescr}

\indexlibrarymember{operator<<}{month_weekday}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const month_weekday& mwd);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L}/{:L}"),
                    mwd.month(), mwd.weekday_indexed());
\end{codeblock}
\end{itemdescr}

\rSec2[time.cal.mwdlast]{Class \tcode{month_weekday_last}}

\rSec3[time.cal.mwdlast.overview]{Overview}
\indexlibraryglobal{month_weekday_last}

\begin{codeblock}
namespace std::chrono {
  class month_weekday_last {
    chrono::month        m_;    // \expos
    chrono::weekday_last wdl_;  // \expos
  public:
    constexpr month_weekday_last(const chrono::month& m,
                                 const chrono::weekday_last& wdl) noexcept;

    constexpr chrono::month        month()        const noexcept;
    constexpr chrono::weekday_last weekday_last() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{month_weekday_last} represents the last weekday of a month,
of an as yet unspecified year.
To do this the \tcode{month_weekday_last} stores a \tcode{month} and a \tcode{weekday_last}.

\pnum
\begin{example}
\begin{codeblock}
constexpr auto mwd
    = February/Tuesday[last];   // \tcode{mwd} is the last Tuesday of February of an as yet unspecified year
static_assert(mwd.month() == February);
static_assert(mwd.weekday_last() == Tuesday[last]);
\end{codeblock}
\end{example}

\pnum
\tcode{month_weekday_last} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.mwdlast.members]{Member functions}

\indexlibraryctor{month_weekday_last}%
\begin{itemdecl}
constexpr month_weekday_last(const chrono::month& m,
                             const chrono::weekday_last& wdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{m_} with \tcode{m}, and \tcode{wdl_} with \tcode{wdl}.
\end{itemdescr}

\indexlibrarymember{month}{month_weekday_last}%
\begin{itemdecl}
constexpr chrono::month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{weekday_last}{month_weekday_last}%
\begin{itemdecl}
constexpr chrono::weekday_last weekday_last() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wdl_}.
\end{itemdescr}

\indexlibrarymember{ok}{month_weekday_last}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_.ok() \&\& wdl_.ok()}.
\end{itemdescr}

\rSec3[time.cal.mwdlast.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{month_weekday_last}%
\begin{itemdecl}
constexpr bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.month() == y.month() \&\& x.weekday_last() == y.weekday_last()}.
\end{itemdescr}

\indexlibrarymember{operator<<}{month_weekday_last}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const month_weekday_last& mwdl);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L}/{:L}"),
                    mwdl.month(), mwdl.weekday_last());
\end{codeblock}
\end{itemdescr}

\rSec2[time.cal.ym]{Class \tcode{year_month}}

\rSec3[time.cal.ym.overview]{Overview}
\indexlibraryglobal{year_month}

\begin{codeblock}
namespace std::chrono {
  class year_month {
    chrono::year  y_;           // \expos
    chrono::month m_;           // \expos

  public:
    year_month() = default;
    constexpr year_month(const chrono::year& y, const chrono::month& m) noexcept;

    constexpr chrono::year  year()  const noexcept;
    constexpr chrono::month month() const noexcept;

    constexpr year_month& operator+=(const months& dm) noexcept;
    constexpr year_month& operator-=(const months& dm) noexcept;
    constexpr year_month& operator+=(const years& dy)  noexcept;
    constexpr year_month& operator-=(const years& dy)  noexcept;

    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{year_month} represents a specific month of a specific year,
but with an unspecified day.
\tcode{year_month} is a field-based time point with a resolution of \tcode{months}.
\tcode{year_month} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable})
and \oldconcept{LessThanComparable} (\tref{cpp17.lessthancomparable}) requirements.

\pnum
\tcode{year_month} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.ym.members]{Member functions}

\indexlibraryctor{year_month}%
\begin{itemdecl}
constexpr year_month(const chrono::year& y, const chrono::month& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{y_} with \tcode{y}, and \tcode{m_} with \tcode{m}.
\end{itemdescr}

\indexlibrarymember{year}{year_month}%
\begin{itemdecl}
constexpr chrono::year year() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_}.
\end{itemdescr}

\indexlibrarymember{month}{year_month}%
\begin{itemdecl}
constexpr chrono::month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month}%
\begin{itemdecl}
constexpr year_month& operator+=(const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this + dm}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month}%
\begin{itemdecl}
constexpr year_month& operator-=(const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this - dm}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month}%
\begin{itemdecl}
constexpr year_month& operator+=(const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + dy}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month}%
\begin{itemdecl}
constexpr year_month& operator-=(const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - dy}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{ok}{year_month}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_.ok() \&\& m_.ok()}.
\end{itemdescr}

\rSec3[time.cal.ym.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{year_month}%
\begin{itemdecl}
constexpr bool operator==(const year_month& x, const year_month& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.year() == y.year() \&\& x.month() == y.month()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{year_month}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const year_month& x, const year_month& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
if (auto c = x.year() <=> y.year(); c != 0) return c;
return x.month() <=> y.month();
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator+}{year_month}%
\begin{itemdecl}
constexpr year_month operator+(const year_month& ym, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
A \tcode{year_month} value \tcode{z} such that \tcode{z.ok() \&\& z - ym == dm}
is \tcode{true}.

\pnum
\complexity
\bigoh{1} with respect to the value of \tcode{dm}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month}%
\begin{itemdecl}
constexpr year_month operator+(const months& dm, const year_month& ym) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ym + dm}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month}%
\begin{itemdecl}
constexpr year_month operator-(const year_month& ym, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ym + -dm}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month}%
\begin{itemdecl}
constexpr months operator-(const year_month& x, const year_month& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
x.year() - y.year() + months{static_cast<int>(unsigned{x.month()}) -
                             static_cast<int>(unsigned{y.month()})}
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator+}{year_month}%
\begin{itemdecl}
constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{(ym.year() + dy) / ym.month()}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month}%
\begin{itemdecl}
constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ym + dy}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month}%
\begin{itemdecl}
constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ym + -dy}.
\end{itemdescr}

\indexlibrarymember{operator<<}{year_month}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const year_month& ym);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{}/{:L}"),
                    ym.year(), ym.month());
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{from_stream}{year_month}%
\begin{itemdecl}
template<class charT, class traits, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                year_month& ym, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{year_month} \tcode{ym} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid \tcode{year_month},
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{ym} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.cal.ymd]{Class \tcode{year_month_day}}

\rSec3[time.cal.ymd.overview]{Overview}
\indexlibraryglobal{year_month_day}

\begin{codeblock}
namespace std::chrono {
  class year_month_day {
    chrono::year  y_;           // \expos
    chrono::month m_;           // \expos
    chrono::day   d_;           // \expos

  public:
    year_month_day() = default;
    constexpr year_month_day(const chrono::year& y, const chrono::month& m,
                             const chrono::day& d) noexcept;
    constexpr year_month_day(const year_month_day_last& ymdl) noexcept;
    constexpr year_month_day(const sys_days& dp) noexcept;
    constexpr explicit year_month_day(const local_days& dp) noexcept;

    constexpr year_month_day& operator+=(const months& m) noexcept;
    constexpr year_month_day& operator-=(const months& m) noexcept;
    constexpr year_month_day& operator+=(const years& y)  noexcept;
    constexpr year_month_day& operator-=(const years& y)  noexcept;

    constexpr chrono::year  year()  const noexcept;
    constexpr chrono::month month() const noexcept;
    constexpr chrono::day   day()   const noexcept;

    constexpr          operator sys_days()   const noexcept;
    constexpr explicit operator local_days() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{year_month_day} represents a specific year, month, and day.
\tcode{year_month_day} is a field-based time point with a resolution of \tcode{days}.
\begin{note}
\tcode{year_month_day} supports \tcode{years}- and \tcode{months}-oriented arithmetic,
but not \tcode{days}-oriented arithmetic.
For the latter, there is a conversion to \tcode{sys_days},
which efficiently supports \tcode{days}-oriented arithmetic.
\end{note}
\tcode{year_month_day} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable})
and \oldconcept{LessThanComparable} (\tref{cpp17.lessthancomparable}) requirements.

\pnum
\tcode{year_month_day} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.ymd.members]{Member functions}

\indexlibraryctor{year_month_day}%
\begin{itemdecl}
constexpr year_month_day(const chrono::year& y, const chrono::month& m,
                         const chrono::day& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes
\tcode{y_} with \tcode{y},
\tcode{m_} with \tcode{m}, and
\tcode{d_} with \tcode{d}.
\end{itemdescr}

\indexlibraryctor{year_month_day}%
\begin{itemdecl}
constexpr year_month_day(const year_month_day_last& ymdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes
\tcode{y_} with \tcode{ymdl.year()},
\tcode{m_} with \tcode{ymdl.month()}, and
\tcode{d_} with \tcode{ymdl.day()}.
\begin{note}
This conversion from \tcode{year_month_day_last} to \tcode{year_month_day}
can be more efficient than converting a \tcode{year_month_day_last} to a \tcode{sys_days},
and then converting that \tcode{sys_days} to a \tcode{year_month_day}.
\end{note}
\end{itemdescr}

\indexlibraryctor{year_month_day}%
\begin{itemdecl}
constexpr year_month_day(const sys_days& dp) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of type \tcode{year_month_day}
that corresponds to the date represented by \tcode{dp}.

\pnum
\remarks
For any value \tcode{ymd} of type \tcode{year_month_day}
for which \tcode{ymd.ok()} is \tcode{true},
\tcode{ymd == year_month_day\{sys_days\{ymd\}\}}
is \tcode{true}.
\end{itemdescr}

\indexlibraryctor{year_month_day}%
\begin{itemdecl}
constexpr explicit year_month_day(const local_days& dp) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to constructing with \tcode{sys_days\{dp.time_since_epoch()\}}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day& operator+=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this + m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day& operator-=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this - m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day& year_month_day::operator+=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day& year_month_day::operator-=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{year}{year_month_day}%
\begin{itemdecl}
constexpr chrono::year year() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_}.
\end{itemdescr}

\indexlibrarymember{month}{year_month_day}%
\begin{itemdecl}
constexpr chrono::month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{day}{year_month_day}%
\begin{itemdecl}
constexpr chrono::day day() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{d_}.
\end{itemdescr}

\indexlibrarymember{operator sys_days}{year_month_day}%
\begin{itemdecl}
constexpr operator sys_days() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{ok()},
returns a \tcode{sys_days}
holding a count of days from the \tcode{sys_days} epoch to \tcode{*this}
(a negative value if \tcode{*this} represents a date prior to the \tcode{sys_days} epoch).
Otherwise, if \tcode{y_.ok() \&\& m_.ok()} is \tcode{true},
returns \tcode{sys_days\{y_/m_/1d\} + (d_ - 1d)}.
Otherwise the value returned is unspecified.

\pnum
\remarks
A \tcode{sys_days} in the range \crange{days\{-12687428\}}{days\{11248737\}}
which is converted to a \tcode{year_month_day}
has the same value when converted back to a \tcode{sys_days}.

\pnum
\begin{example}
\begin{codeblock}
static_assert(year_month_day{sys_days{2017y/January/0}}  == 2016y/December/31);
static_assert(year_month_day{sys_days{2017y/January/31}} == 2017y/January/31);
static_assert(year_month_day{sys_days{2017y/January/32}} == 2017y/February/1);
\end{codeblock}
\end{example}
\end{itemdescr}

\indexlibrarymember{operator local_days}{year_month_day}%
\begin{itemdecl}
constexpr explicit operator local_days() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}.
\end{itemdescr}

\indexlibrarymember{ok}{year_month_day}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{y_.ok()} is \tcode{true},
and \tcode{m_.ok()} is \tcode{true},
and \tcode{d_} is in the range \crange{1d}{(y_/m_/last).day()},
then returns \tcode{true}; otherwise returns \tcode{false}.
\end{itemdescr}

\rSec3[time.cal.ymd.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{year_month_day}%
\begin{itemdecl}
constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.year() == y.year() \&\& x.month() == y.month() \&\& x.day() == y.day()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{year_month_day}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const year_month_day& x, const year_month_day& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
if (auto c = x.year() <=> y.year(); c != 0) return c;
if (auto c = x.month() <=> y.month(); c != 0) return c;
return x.day() <=> y.day();
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{(ymd.year() / ymd.month() + dm) / ymd.day()}.

\pnum
\begin{note}
If \tcode{ymd.day()} is in the range \crange{1d}{28d},
\tcode{ok()} will return \tcode{true} for
the resultant \tcode{year_month_day}.
\end{note}
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ymd + dm}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ymd + (-dm)}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{(ymd.year() + dy) / ymd.month() / ymd.day()}.

\pnum
\begin{note}
If \tcode{ymd.month()} is February
and \tcode{ymd.day()} is not in the range \crange{1d}{28d},
\tcode{ok()} can return \tcode{false} for
the resultant \tcode{year_month_day}.
\end{note}
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ymd + dy}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month_day}%
\begin{itemdecl}
constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ymd + (-dy)}.
\end{itemdescr}

\indexlibrarymember{operator<<}{year_month_day}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const year_month_day& ymd);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << (ymd.ok() ?
  format(@\placeholder{STATICALLY-WIDEN}@<charT>("{:%F}"), ymd) :
  format(@\placeholder{STATICALLY-WIDEN}@<charT>("{:%F} is not a valid date"), ymd));
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{from_stream}{year_month_day}%
\begin{itemdecl}
template<class charT, class traits, class Alloc = allocator<charT>>
  basic_istream<charT, traits>&
    from_stream(basic_istream<charT, traits>& is, const charT* fmt,
                year_month_day& ymd, basic_string<charT, traits, Alloc>* abbrev = nullptr,
                minutes* offset = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Attempts to parse the input stream \tcode{is}
into the \tcode{year_month_day} \tcode{ymd} using
the format flags given in the NTCTS \tcode{fmt}
as specified in \ref{time.parse}.
If the parse fails to decode a valid \tcode{year_month_day},
\tcode{is.setstate(ios_base::failbit)} is called and
\tcode{ymd} is not modified.
If \tcode{\%Z} is used and successfully parsed,
that value will be assigned to \tcode{*abbrev} if \tcode{abbrev} is non-null.
If \tcode{\%z} (or a modified variant) is used and successfully parsed,
that value will be assigned to \tcode{*offset} if \tcode{offset} is non-null.

\pnum
\returns
\tcode{is}.
\end{itemdescr}

\rSec2[time.cal.ymdlast]{Class \tcode{year_month_day_last}}

\rSec3[time.cal.ymdlast.overview]{Overview}
\indexlibraryglobal{year_month_day_last}

\begin{codeblock}
namespace std::chrono {
  class year_month_day_last {
    chrono::year           y_;          // \expos
    chrono::month_day_last mdl_;        // \expos

  public:
    constexpr year_month_day_last(const chrono::year& y,
                                  const chrono::month_day_last& mdl) noexcept;

    constexpr year_month_day_last& operator+=(const months& m) noexcept;
    constexpr year_month_day_last& operator-=(const months& m) noexcept;
    constexpr year_month_day_last& operator+=(const years& y)  noexcept;
    constexpr year_month_day_last& operator-=(const years& y)  noexcept;

    constexpr chrono::year           year()           const noexcept;
    constexpr chrono::month          month()          const noexcept;
    constexpr chrono::month_day_last month_day_last() const noexcept;
    constexpr chrono::day            day()            const noexcept;

    constexpr          operator sys_days()   const noexcept;
    constexpr explicit operator local_days() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{year_month_day_last} represents the last day of a specific year and month.
\tcode{year_month_day_last} is a field-based time point with a resolution of \tcode{days},
except that it is restricted to pointing to the last day of a year and month.
\begin{note}
\tcode{year_month_day_last} supports \tcode{years}- and \tcode{months}-oriented arithmetic,
but not \tcode{days}-oriented arithmetic.
For the latter, there is a conversion to \tcode{sys_days},
which efficiently supports \tcode{days}-oriented arithmetic.
\end{note}
\tcode{year_month_day_last} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable})
and \oldconcept{LessThanComparable} (\tref{cpp17.lessthancomparable}) requirements.

\pnum
\tcode{year_month_day_last} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.ymdlast.members]{Member functions}

\indexlibraryctor{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last(const chrono::year& y,
                              const chrono::month_day_last& mdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{y_} with \tcode{y} and \tcode{mdl_} with \tcode{mdl}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last& operator+=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this + m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last& operator-=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this - m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last& operator+=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last& operator-=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{year}{year_month_day_last}%
\begin{itemdecl}
constexpr chrono::year year() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_}.
\end{itemdescr}

\indexlibrarymember{month}{year_month_day_last}%
\begin{itemdecl}
constexpr chrono::month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{mdl_.month()}.
\end{itemdescr}

\indexlibrarymember{month_day_last}{year_month_day_last}%
\begin{itemdecl}
constexpr chrono::month_day_last month_day_last() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{mdl_}.
\end{itemdescr}

\indexlibrarymember{day}{year_month_day_last}%
\begin{itemdecl}
constexpr chrono::day day() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{ok()} is \tcode{true},
returns a \tcode{day} representing
the last day of the (\tcode{year}, \tcode{month}) pair
represented by \tcode{*this}.
Otherwise, the returned value is unspecified.

\pnum
\begin{note}
This value might be computed on demand.
\end{note}
\end{itemdescr}

\indexlibrarymember{operator sys_days}{year_month_day_last}%
\begin{itemdecl}
constexpr operator sys_days() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{sys_days\{year()/month()/day()\}}.
\end{itemdescr}

\indexlibrarymember{operator local_days}{year_month_day_last}%
\begin{itemdecl}
constexpr explicit operator local_days() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}.
\end{itemdescr}

\indexlibrarymember{ok}{year_month_day_last}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_.ok() \&\& mdl_.ok()}.
\end{itemdescr}

\rSec3[time.cal.ymdlast.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{year_month_day_last}%
\begin{itemdecl}
constexpr bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.year() == y.year() \&\& x.month_day_last() == y.month_day_last()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{year_month_day_last}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const year_month_day_last& x,
                                      const year_month_day_last& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
if (auto c = x.year() <=> y.year(); c != 0) return c;
return x.month_day_last() <=> y.month_day_last();
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last
  operator+(const year_month_day_last& ymdl, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{(ymdl.year() / ymdl.month() + dm) / last}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last
  operator+(const months& dm, const year_month_day_last& ymdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ymdl + dm}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last
  operator-(const year_month_day_last& ymdl, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ymdl + (-dm)}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last
  operator+(const year_month_day_last& ymdl, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{ymdl.year()+dy, ymdl.month_day_last()\}}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last
  operator+(const years& dy, const year_month_day_last& ymdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ymdl + dy}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month_day_last}%
\begin{itemdecl}
constexpr year_month_day_last
  operator-(const year_month_day_last& ymdl, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ymdl + (-dy)}.
\end{itemdescr}

\indexlibrarymember{operator<<}{year_month_day_last}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const year_month_day_last& ymdl);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{}/{:L}"),
                    ymdl.year(), ymdl.month_day_last());
\end{codeblock}
\end{itemdescr}

\rSec2[time.cal.ymwd]{Class \tcode{year_month_weekday}}

\rSec3[time.cal.ymwd.overview]{Overview}
\indexlibraryglobal{year_month_weekday}

\begin{codeblock}
namespace std::chrono {
  class year_month_weekday {
    chrono::year            y_;         // \expos
    chrono::month           m_;         // \expos
    chrono::weekday_indexed wdi_;       // \expos

  public:
    year_month_weekday() = default;
    constexpr year_month_weekday(const chrono::year& y, const chrono::month& m,
                                 const chrono::weekday_indexed& wdi) noexcept;
    constexpr year_month_weekday(const sys_days& dp) noexcept;
    constexpr explicit year_month_weekday(const local_days& dp) noexcept;

    constexpr year_month_weekday& operator+=(const months& m) noexcept;
    constexpr year_month_weekday& operator-=(const months& m) noexcept;
    constexpr year_month_weekday& operator+=(const years& y)  noexcept;
    constexpr year_month_weekday& operator-=(const years& y)  noexcept;

    constexpr chrono::year            year()            const noexcept;
    constexpr chrono::month           month()           const noexcept;
    constexpr chrono::weekday         weekday()         const noexcept;
    constexpr unsigned                index()           const noexcept;
    constexpr chrono::weekday_indexed weekday_indexed() const noexcept;

    constexpr          operator sys_days()   const noexcept;
    constexpr explicit operator local_days() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{year_month_weekday} represents a specific year, month,
and $n^\text{th}$ weekday of the month.
\tcode{year_month_weekday} is a field-based time point with a resolution of \tcode{days}.
\begin{note}
\tcode{year_month_weekday} supports \tcode{years}- and \tcode{months}-oriented arithmetic,
but not \tcode{days}-oriented arithmetic.
For the latter, there is a conversion to \tcode{sys_days},
which efficiently supports \tcode{days}-oriented arithmetic.
\end{note}
\tcode{year_month_weekday} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable}) requirements.

\pnum
\tcode{year_month_weekday} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.ymwd.members]{Member functions}

\indexlibraryctor{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday(const chrono::year& y, const chrono::month& m,
                             const chrono::weekday_indexed& wdi) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{y_} with \tcode{y}, \tcode{m_} with \tcode{m}, and \tcode{wdi_} with \tcode{wdi}.
\end{itemdescr}

\indexlibraryctor{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday(const sys_days& dp) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of type \tcode{year_month_weekday}
which corresponds to the date represented by \tcode{dp}.

\pnum
\remarks
For any value \tcode{ymwd} of type \tcode{year_month_weekday}
for which \tcode{ymwd.ok()} is \tcode{true},
\tcode{ymwd == year_month_weekday\{sys_days\{ymwd\}\}} is \tcode{true}.
\end{itemdescr}

\indexlibraryctor{year_month_weekday}%
\begin{itemdecl}
constexpr explicit year_month_weekday(const local_days& dp) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to constructing with \tcode{sys_days\{dp.time_since_epoch()\}}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday& operator+=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this + m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday& operator-=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this - m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday& operator+=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday& operator-=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{year}{year_month_weekday}%
\begin{itemdecl}
constexpr chrono::year year() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_}.
\end{itemdescr}

\indexlibrarymember{month}{year_month_weekday}%
\begin{itemdecl}
constexpr chrono::month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{weekday}{year_month_weekday}%
\begin{itemdecl}
constexpr chrono::weekday weekday() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wdi_.weekday()}.
\end{itemdescr}

\indexlibrarymember{index}{year_month_weekday}%
\begin{itemdecl}
constexpr unsigned index() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wdi_.index()}.
\end{itemdescr}

\indexlibrarymember{weekday_indexed}{year_month_weekday}%
\begin{itemdecl}
constexpr chrono::weekday_indexed weekday_indexed() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wdi_}.
\end{itemdescr}

\indexlibrarymember{operator sys_days}{year_month_weekday}%
\begin{itemdecl}
constexpr operator sys_days() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{y_.ok() \&\& m_.ok() \&\& wdi_.weekday().ok()},
returns a \tcode{sys_days} that
represents the date \tcode{(index() - 1) * 7} days after
the first \tcode{weekday()} of \tcode{year()/month()}.
If \tcode{index()} is 0
the returned \tcode{sys_days}
represents the date 7 days prior to
the first \tcode{weekday()} of \tcode{year()/month()}.
Otherwise the returned value is unspecified.
\end{itemdescr}

\indexlibrarymember{operator local_days}{year_month_weekday}%
\begin{itemdecl}
constexpr explicit operator local_days() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}.
\end{itemdescr}

\indexlibrarymember{ok}{year_month_weekday}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If any of
\tcode{y_.ok()},
\tcode{m_.ok()}, or
\tcode{wdi_.ok()}
is \tcode{false}, returns \tcode{false}.
Otherwise, if \tcode{*this} represents a valid date,
returns \tcode{true}.
Otherwise, returns \tcode{false}.
\end{itemdescr}

\rSec3[time.cal.ymwd.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{year_month_weekday}%
\begin{itemdecl}
constexpr bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
x.year() == y.year() && x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed()
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{(ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed()}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday operator+(const months& dm, const year_month_weekday& ymwd) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ymwd + dm}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ymwd + (-dm)}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday operator+(const year_month_weekday& ymwd, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()\}}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday operator+(const years& dy, const year_month_weekday& ymwd) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ymwd + dy}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month_weekday}%
\begin{itemdecl}
constexpr year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ymwd + (-dy)}.
\end{itemdescr}

\indexlibrarymember{operator<<}{year_month_weekday}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const year_month_weekday& ymwd);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{}/{:L}/{:L}"),
                    ymwd.year(), ymwd.month(), ymwd.weekday_indexed());
\end{codeblock}
\end{itemdescr}

\rSec2[time.cal.ymwdlast]{Class \tcode{year_month_weekday_last}}

\rSec3[time.cal.ymwdlast.overview]{Overview}
\indexlibraryglobal{year_month_weekday_last}

\begin{codeblock}
namespace std::chrono {
  class year_month_weekday_last {
    chrono::year         y_;    // \expos
    chrono::month        m_;    // \expos
    chrono::weekday_last wdl_;  // \expos

  public:
    constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m,
                                      const chrono::weekday_last& wdl) noexcept;

    constexpr year_month_weekday_last& operator+=(const months& m) noexcept;
    constexpr year_month_weekday_last& operator-=(const months& m) noexcept;
    constexpr year_month_weekday_last& operator+=(const years& y)  noexcept;
    constexpr year_month_weekday_last& operator-=(const years& y)  noexcept;

    constexpr chrono::year         year()         const noexcept;
    constexpr chrono::month        month()        const noexcept;
    constexpr chrono::weekday      weekday()      const noexcept;
    constexpr chrono::weekday_last weekday_last() const noexcept;

    constexpr          operator sys_days()   const noexcept;
    constexpr explicit operator local_days() const noexcept;
    constexpr bool ok() const noexcept;
  };
}
\end{codeblock}

\pnum
\tcode{year_month_weekday_last} represents a specific year, month,
and last weekday of the month.
\tcode{year_month_weekday_last} is a field-based time point with a resolution of \tcode{days},
except that it is restricted to pointing to the last weekday of a year and month.
\begin{note}
\tcode{year_month_weekday_last} supports \tcode{years}- and \tcode{months}-oriented arithmetic,
but not \tcode{days}-oriented arithmetic.
For the latter, there is a conversion to \tcode{sys_days},
which efficiently supports \tcode{days}-oriented arithmetic.
\end{note}
\tcode{year_month_weekday_last} meets the \oldconcept{EqualityComparable} (\tref{cpp17.equalitycomparable}) requirements.

\pnum
\tcode{year_month_weekday_last} is a trivially copyable and standard-layout class type.

\rSec3[time.cal.ymwdlast.members]{Member functions}

\indexlibraryctor{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last(const chrono::year& y, const chrono::month& m,
                                  const chrono::weekday_last& wdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Initializes \tcode{y_} with \tcode{y}, \tcode{m_} with \tcode{m}, and \tcode{wdl_} with \tcode{wdl}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last& operator+=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this + m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last& operator-=(const months& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\effects
\tcode{*this = *this - m}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator+=}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last& operator+=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this + y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator-=}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last& operator-=(const years& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
\tcode{*this = *this - y}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{year}{year_month_weekday_last}%
\begin{itemdecl}
constexpr chrono::year year() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_}.
\end{itemdescr}

\indexlibrarymember{month}{year_month_weekday_last}%
\begin{itemdecl}
constexpr chrono::month month() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m_}.
\end{itemdescr}

\indexlibrarymember{weekday}{year_month_weekday_last}%
\begin{itemdecl}
constexpr chrono::weekday weekday() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wdl_.weekday()}.
\end{itemdescr}

\indexlibrarymember{weekday_last}{year_month_weekday_last}%
\begin{itemdecl}
constexpr chrono::weekday_last weekday_last() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{wdl_}.
\end{itemdescr}

\indexlibrarymember{operator sys_days}{year_month_weekday_last}%
\begin{itemdecl}
constexpr operator sys_days() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{ok() == true},
returns a \tcode{sys_days} that represents
the last \tcode{weekday()} of \tcode{year()/month()}.
Otherwise the returned value is unspecified.
\end{itemdescr}

\indexlibrarymember{operator local_days}{year_month_weekday_last}%
\begin{itemdecl}
constexpr explicit operator local_days() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{local_days\{sys_days\{*this\}.time_since_epoch()\}}.
\end{itemdescr}

\indexlibrarymember{ok}{year_month_weekday_last}%
\begin{itemdecl}
constexpr bool ok() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y_.ok() \&\& m_.ok() \&\& wdl_.ok()}.
\end{itemdescr}

\rSec3[time.cal.ymwdlast.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{year_month_weekday_last}%
\begin{itemdecl}
constexpr bool operator==(const year_month_weekday_last& x,
                          const year_month_weekday_last& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{codeblock}
x.year() == y.year() && x.month() == y.month() && x.weekday_last() == y.weekday_last()
\end{codeblock}
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last
  operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{(ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last()}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last
  operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ymwdl + dm}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last
  operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
If the argument supplied by the caller for the \tcode{months} parameter
is convertible to \tcode{years},
its implicit conversion sequence to \tcode{years}
is worse than its implicit conversion sequence to
\tcode{months}\iref{over.ics.rank}.

\pnum
\returns
\tcode{ymwdl + (-dm)}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last
  operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()\}}.
\end{itemdescr}

\indexlibrarymember{operator+}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last
  operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ymwdl + dy}.
\end{itemdescr}

\indexlibrarymember{operator-}{year_month_weekday_last}%
\begin{itemdecl}
constexpr year_month_weekday_last
  operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ymwdl + (-dy)}.
\end{itemdescr}

\indexlibrarymember{operator<<}{year_month_weekday_last}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const year_month_weekday_last& ymwdl);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{}/{:L}/{:L}"),
                    ymwdl.year(), ymwdl.month(), ymwdl.weekday_last());
\end{codeblock}
\end{itemdescr}

\rSec2[time.cal.operators]{Conventional syntax operators}
\indexlibrary{\idxcode{operator/}!calendar types|(}

\pnum
A set of overloaded \tcode{operator/} functions provides
a conventional syntax for the creation of civil calendar dates.

\pnum
\begin{note}
The year, month, and day are accepted in any of the following 3 orders:

\begin{codeblock}
@\tcode{\placeholder{year}}@/@\tcode{\placeholder{month}}@/@\tcode{\placeholder{day}}@
@\tcode{\placeholder{month}}@/@\tcode{\placeholder{day}}@/@\tcode{\placeholder{year}}@
@\tcode{\placeholder{day}}@/@\tcode{\placeholder{month}}@/@\tcode{\placeholder{year}}@
\end{codeblock}

Anywhere a \tcode{\placeholder{day}} is needed, any of the following can also be specified:

\begin{codeblock}
last
@\tcode{\placeholder{weekday}}@[@\tcode{\placeholder{i}}@]
@\tcode{\placeholder{weekday}}@[last]
\end{codeblock}
\end{note}

\pnum
\begin{note}
Partial-date types such as \tcode{year_month} and \tcode{month_day}
can be created by not applying the second division operator
for any of the three orders. For example:

\begin{codeblock}
year_month ym = 2015y/April;
month_day md1 = April/4;
month_day md2 = 4d/April;
\end{codeblock}
\end{note}

\pnum
\begin{example}
\begin{codeblock}
auto a = 2015/4/4;          // \tcode{a == int(125)}
auto b = 2015y/4/4;         // \tcode{b == year_month_day\{year(2015), month(4), day(4)\}}
auto c = 2015y/4d/April;    // error: no viable \tcode{operator/} for first \tcode{/}
auto d = 2015/April/4;      // error: no viable \tcode{operator/} for first \tcode{/}
\end{codeblock}
\end{example}

\begin{itemdecl}
constexpr year_month
  operator/(const year& y, const month& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{y, m\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month
  operator/(const year& y, int   m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y / month(m)}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day
  operator/(const month& m, const day& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{m, d\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day
  operator/(const month& m, int d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m / day(d)}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day
  operator/(int m, const day& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month(m) / d}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day
  operator/(const day& d, const month& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m / d}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day
  operator/(const day& d, int m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month(m) / d}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day_last
  operator/(const month& m, last_spec) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month_day_last\{m\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day_last
  operator/(int m, last_spec) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month(m) / last}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day_last
  operator/(last_spec, const month& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m / last}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_day_last
  operator/(last_spec, int m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month(m) / last}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_weekday
  operator/(const month& m, const weekday_indexed& wdi) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{m, wdi\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_weekday
  operator/(int m, const weekday_indexed& wdi) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month(m) / wdi}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_weekday
  operator/(const weekday_indexed& wdi, const month& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m / wdi}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_weekday
  operator/(const weekday_indexed& wdi, int m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month(m) / wdi}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_weekday_last
  operator/(const month& m, const weekday_last& wdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{m, wdl\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_weekday_last
  operator/(int m, const weekday_last& wdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month(m) / wdl}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_weekday_last
  operator/(const weekday_last& wdl, const month& m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m / wdl}.
\end{itemdescr}

\begin{itemdecl}
constexpr month_weekday_last
  operator/(const weekday_last& wdl, int m) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{month(m) / wdl}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day
  operator/(const year_month& ym, const day& d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{ym.year(), ym.month(), d\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day
  operator/(const year_month& ym, int d) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ym / day(d)}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day
  operator/(const year& y, const month_day& md) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y / md.month() / md.day()}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day
  operator/(int y, const month_day& md) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year(y) / md}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day
  operator/(const month_day& md, const year& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y / md}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day
  operator/(const month_day& md, int y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year(y) / md}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day_last
  operator/(const year_month& ym, last_spec) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{ym.year(), month_day_last\{ym.month()\}\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day_last
  operator/(const year& y, const month_day_last& mdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{y, mdl\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day_last
  operator/(int y, const month_day_last& mdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year(y) / mdl}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day_last
  operator/(const month_day_last& mdl, const year& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y / mdl}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_day_last
  operator/(const month_day_last& mdl, int y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year(y) / mdl}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday
  operator/(const year_month& ym, const weekday_indexed& wdi) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{ym.year(), ym.month(), wdi\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday
  operator/(const year& y, const month_weekday& mwd) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{y, mwd.month(), mwd.weekday_indexed()\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday
  operator/(int y, const month_weekday& mwd) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year(y) / mwd}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday
  operator/(const month_weekday& mwd, const year& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y / mwd}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday
  operator/(const month_weekday& mwd, int y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year(y) / mwd}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday_last
  operator/(const year_month& ym, const weekday_last& wdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{ym.year(), ym.month(), wdl\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday_last
  operator/(const year& y, const month_weekday_last& mwdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{y, mwdl.month(), mwdl.weekday_last()\}}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday_last
  operator/(int y, const month_weekday_last& mwdl) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year(y) / mwdl}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday_last
  operator/(const month_weekday_last& mwdl, const year& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y / mwdl}.
\end{itemdescr}

\begin{itemdecl}
constexpr year_month_weekday_last
  operator/(const month_weekday_last& mwdl, int y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{year(y) / mwdl}.
\end{itemdescr}

\indexlibrary{\idxcode{operator/}!calendar types|)}

\rSec1[time.hms]{Class template \tcode{hh_mm_ss}}

\rSec2[time.hms.overview]{Overview}
\indexlibraryglobal{hms}

\begin{codeblock}
namespace std::chrono {
  template<class Duration> class hh_mm_ss {
  public:
    static constexpr unsigned fractional_width = @\seebelow@;
    using precision                            = @\seebelow@;

    constexpr hh_mm_ss() noexcept : hh_mm_ss{Duration::zero()} {}
    constexpr explicit hh_mm_ss(Duration d);

    constexpr bool is_negative() const noexcept;
    constexpr chrono::hours hours() const noexcept;
    constexpr chrono::minutes minutes() const noexcept;
    constexpr chrono::seconds seconds() const noexcept;
    constexpr precision subseconds() const noexcept;

    constexpr explicit operator precision() const noexcept;
    constexpr precision to_duration() const noexcept;

  private:
    bool            is_neg;     // \expos
    chrono::hours   h;          // \expos
    chrono::minutes m;          // \expos
    chrono::seconds s;          // \expos
    precision       ss;         // \expos
  };
}
\end{codeblock}

\pnum
The \tcode{hh_mm_ss} class template
splits a \tcode{duration}
into a multi-field time structure
\placeholdernc{hours}:\placeholdernc{minutes}:\placeholder{seconds} and
possibly \placeholder{subseconds},
where \placeholder{subseconds} will be a duration unit
based on a non-positive power of 10.
The \tcode{Duration} template parameter dictates the precision
to which the time is split.
A \tcode{hh_mm_ss} models negative durations
with a distinct \tcode{is_negative} getter
that returns \tcode{true} when the input duration is negative.
The individual duration fields always return non-negative durations
even when \tcode{is_negative()} indicates
the structure is representing a negative duration.

\pnum
If \tcode{Duration} is not a specialization of \tcode{duration},
the program is ill-formed.

\rSec2[time.hms.members]{Members}

\begin{itemdecl}
static constexpr unsigned fractional_width = @\seebelow@;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{fractional_width} is the number of fractional decimal digits
represented by \tcode{precision}.
\tcode{fractional_width} has the value
of the smallest possible integer in the range \crange{0}{18} such that
\tcode{precision} will exactly represent all values of \tcode{Duration}.
If no such value of \tcode{fractional_width} exists, then
\tcode{fractional_width} is 6.
\begin{example}
See~\tref{time.hms.width}
for some durations,
the resulting \tcode{fractional_width}, and
the formatted fractional second output of \tcode{Duration\{1\}}.
\begin{LongTable}
  {Examples for \tcode{fractional_width}}
  {time.hms.width}
  {llx{.3\hsize}}
\\ \topline
\lhdr{Duration} &
\chdr{\tcode{fractional_width}} &
\rhdr{Formatted fractional second output} \\ \capsep
\endfirsthead
\continuedcaption\\
\hline
\lhdr{Duration} &
\chdr{\tcode{fractional_width}} &
\rhdr{Formatted fractional second output} \\ \capsep
\endhead
\tcode{hours}, \tcode{minutes}, and \tcode{seconds} & \tcode{0} &    \\ \rowsep
\tcode{milliseconds}               & \tcode{3} & \tcode{0.001}       \\ \rowsep
\tcode{microseconds}               & \tcode{6} & \tcode{0.000001}    \\ \rowsep
\tcode{nanoseconds}                & \tcode{9} & \tcode{0.000000001} \\ \rowsep
\tcode{duration<int, ratio<1, 2>>} & \tcode{1} & \tcode{0.5}         \\ \rowsep
\tcode{duration<int, ratio<1, 3>>} & \tcode{6} & \tcode{0.333333}    \\ \rowsep
\tcode{duration<int, ratio<1, 4>>} & \tcode{2} & \tcode{0.25}        \\ \rowsep
\tcode{duration<int, ratio<1, 5>>} & \tcode{1} & \tcode{0.2}         \\ \rowsep
\tcode{duration<int, ratio<1, 6>>} & \tcode{6} & \tcode{0.166666}    \\ \rowsep
\tcode{duration<int, ratio<1, 7>>} & \tcode{6} & \tcode{0.142857}    \\ \rowsep
\tcode{duration<int, ratio<1, 8>>} & \tcode{3} & \tcode{0.125}       \\ \rowsep
\tcode{duration<int, ratio<1, 9>>} & \tcode{6} & \tcode{0.111111}    \\ \rowsep
\tcode{duration<int, ratio<1, 10>>} & \tcode{1} & \tcode{0.1}        \\ \rowsep
\tcode{duration<int, ratio<756, 625>>} & \tcode{4} & \tcode{0.2096}  \\
\end{LongTable}
\end{example}
\end{itemdescr}

\begin{itemdecl}
using precision = @\seebelow@;
\end{itemdecl}

\begin{itemdescr}
\pnum
\tcode{precision} is
\begin{codeblock}
duration<common_type_t<Duration::rep, seconds::rep>, ratio<1, @$10^\tcode{fractional_width}$@>>
\end{codeblock}
\end{itemdescr}

\begin{itemdecl}
constexpr explicit hh_mm_ss(Duration d);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Constructs an object of type \tcode{hh_mm_ss}
which represents the \tcode{Duration d} with precision \tcode{precision}.
\begin{itemize}
\item
  Initializes \tcode{is_neg} with \tcode{d < Duration::zero()}.
  Let \tcode{\placeholder{ABS_D}} represent
  \tcode{-d} if \tcode{is_neg} is \tcode{true} and
  \tcode{d} otherwise.
\item
  Initializes \tcode{h} with \tcode{duration_cast<chrono::hours>(\placeholder{ABS_D})}.
\item
  Initializes \tcode{m}
  with \tcode{duration_cast<chrono::minutes>(\placeholder{ABS_D} - hours())}.
\item
  Initializes \tcode{s}
  with \tcode{duration_cast<chrono::seconds>(\placeholder{ABS_D} - hours() - minutes())}.
\item
  If \tcode{treat_as_floating_point_v<precision::rep>} is \tcode{true},
  initializes \tcode{ss} with \tcode{\placeholder{ABS_D} - hours() - minutes() - seconds()}.
  Otherwise, initializes \tcode{ss}
  with \tcode{duration_cast<precision>(\placeholder{ABS_D} - hours() - minutes() - seconds())}.
\end{itemize}
\begin{note}
When \tcode{precision::rep} is integral and
\tcode{precision::period} is \tcode{ratio<1>},
\tcode{subseconds()} always returns a value equal to \tcode{0s}.
\end{note}

\pnum
\ensures
If \tcode{treat_as_floating_point_v<precision::rep>} is \tcode{true},
\tcode{to_duration()} returns \tcode{d},
otherwise \tcode{to_duration()} returns \tcode{duration_cast<precision>(d)}.
\end{itemdescr}

\indexlibrarymember{is_negative}{hh_mm_ss}%
\begin{itemdecl}
constexpr bool is_negative() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{is_neg}.
\end{itemdescr}

\indexlibrarymember{hours}{hh_mm_ss}%
\begin{itemdecl}
constexpr chrono::hours hours() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{h}.
\end{itemdescr}

\indexlibrarymember{minutes}{hh_mm_ss}%
\begin{itemdecl}
constexpr chrono::minutes minutes() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{m}.
\end{itemdescr}

\indexlibrarymember{seconds}{hh_mm_ss}%
\begin{itemdecl}
constexpr chrono::seconds seconds() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{s}.
\end{itemdescr}

\indexlibrarymember{subseconds}{hh_mm_ss}%
\begin{itemdecl}
constexpr precision subseconds() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{ss}.
\end{itemdescr}

\indexlibrarymember{to_duration}{hh_mm_ss}%
\begin{itemdecl}
constexpr precision to_duration() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{is_neg}, returns \tcode{-(h + m + s + ss)},
otherwise returns \tcode{h + m + s + ss}.
\end{itemdescr}

\indexlibrarymember{operator precision}{hh_mm_ss}%
\begin{itemdecl}
constexpr explicit operator precision() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{to_duration()}.
\end{itemdescr}

\rSec2[time.hms.nonmembers]{Non-members}

\begin{itemdecl}
template<class charT, class traits, class Duration>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const hh_mm_ss<Duration>& hms);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%T}"), hms);
\end{codeblock}

\pnum
\begin{example}
\begin{codeblock}
for (auto ms : {-4083007ms, 4083007ms, 65745123ms}) {
  hh_mm_ss hms{ms};
  cout << hms << '\n';
}
cout << hh_mm_ss{65745s} << '\n';
\end{codeblock}
Produces the output (assuming the "C" locale):
\begin{codeblock}
-01:08:03.007
01:08:03.007
18:15:45.123
18:15:45
\end{codeblock}
\end{example}
\end{itemdescr}

\rSec1[time.12]{12/24 hours functions}

\pnum
These functions aid in translating between a 12h format time of day
and a 24h format time of day.

\indexlibraryglobal{is_am}%
\begin{itemdecl}
constexpr bool is_am(const hours& h) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{0h <= h \&\& h <= 11h}.
\end{itemdescr}

\indexlibraryglobal{is_pm}%
\begin{itemdecl}
constexpr bool is_pm(const hours& h) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{12h <= h \&\& h <= 23h}.
\end{itemdescr}

\indexlibraryglobal{make12}%
\begin{itemdecl}
constexpr hours make12(const hours& h) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The 12-hour equivalent of \tcode{h} in the range \crange{1h}{12h}.
If \tcode{h} is not in the range \crange{0h}{23h},
the value returned is unspecified.
\end{itemdescr}

\indexlibraryglobal{make24}%
\begin{itemdecl}
constexpr hours make24(const hours& h, bool is_pm) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
If \tcode{is_pm} is \tcode{false},
returns the 24-hour equivalent of \tcode{h}
in the range \crange{0h}{11h},
assuming \tcode{h} represents an ante meridiem hour.
Otherwise,
returns the 24-hour equivalent of \tcode{h}
in the range \crange{12h}{23h},
assuming \tcode{h} represents a post meridiem hour.
If \tcode{h} is not in the range \crange{1h}{12h},
the value returned is unspecified.
\end{itemdescr}

\rSec1[time.zone]{Time zones}

\rSec2[time.zone.general]{General}

\pnum
\ref{time.zone} describes an interface for accessing
the IANA Time Zone Database\supercite{iana-tz}
that interoperates with \tcode{sys_time} and \tcode{local_time}.
This interface provides time zone support to
both the civil calendar types\iref{time.cal}
and to user-defined calendars.

\rSec2[time.zone.db]{Time zone database}

\rSec3[time.zone.db.tzdb]{Class \tcode{tzdb}}
\indexlibraryglobal{tzdb}

\begin{codeblock}
namespace std::chrono {
  struct tzdb {
    string                 version;
    vector<time_zone>      zones;
    vector<time_zone_link> links;
    vector<leap_second>    leap_seconds;

    const time_zone* locate_zone(string_view tz_name) const;
    const time_zone* current_zone() const;
  };
}
\end{codeblock}

\pnum
Each \tcode{vector} in a \tcode{tzdb} object
is sorted to enable fast lookup.

\indexlibrarymember{locate_zone}{tzdb}%
\begin{itemdecl}
const time_zone* locate_zone(string_view tz_name) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\begin{itemize}
\item
If \tcode{zones} contains an element \tcode{tz}
for which \tcode{tz.name() == tz_name},
a pointer to \tcode{tz};
\item
otherwise,
if \tcode{links} contains an element \tcode{tz_l}
for which \tcode{tz_l.name() == tz_name},
then a pointer to the element \tcode{tz} of \tcode{zones}
for which \tcode{tz.name() == tz_l.target()}.
\end{itemize}
\begin{note}
A \tcode{time_zone_link} specifies an alternative name for a \tcode{time_zone}.
\end{note}

\pnum
\throws
If a \tcode{const time_zone*} cannot be found
as described in the \returns element,
throws a \tcode{runtime_error}.
\begin{note}
On non-exceptional return, the return value is always a pointer to a valid \tcode{time_zone}.
\end{note}
\end{itemdescr}

\indexlibrarymember{current_zone}{tzdb}%
\begin{itemdecl}
const time_zone* current_zone() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A pointer to the time zone which the computer has set as its local time zone.
\end{itemdescr}

\rSec3[time.zone.db.list]{Class \tcode{tzdb_list}}
\indexlibraryglobal{tzdb_list}

\begin{codeblock}
namespace std::chrono {
  class tzdb_list {
  public:
    tzdb_list(const tzdb_list&) = delete;
    tzdb_list& operator=(const tzdb_list&) = delete;

    // unspecified additional constructors

    class const_iterator;

    const tzdb& front() const noexcept;

    const_iterator erase_after(const_iterator p);

    const_iterator begin() const noexcept;
    const_iterator end()   const noexcept;

    const_iterator cbegin() const noexcept;
    const_iterator cend()   const noexcept;
  };
}
\end{codeblock}

\pnum
The \tcode{tzdb_list} database is a singleton;
the unique object of type \tcode{tzdb_list} can be
accessed via the \tcode{get_tzdb_list()} function.
\begin{note}
This access is only needed for those applications
that need to have long uptimes and
have a need to update the time zone database while running.
Other applications can implicitly access the \tcode{front()} of this list
via the read-only namespace scope functions
\tcode{get_tzdb()},
\tcode{locate_zone()}, and
\tcode{current_zone()}.
\end{note}
The \tcode{tzdb_list} object contains a list of \tcode{tzdb} objects.

\pnum
\tcode{tzdb_list::const_iterator} is a constant iterator
which meets the \oldconcept{ForwardIterator} requirements
and has a value type of \tcode{tzdb}.

\indexlibrarymember{front}{tzdb_list}%
\begin{itemdecl}
const tzdb& front() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\sync
This operation is thread-safe with respect to \tcode{reload_tzdb()}.
\begin{note}
\tcode{reload_tzdb()} pushes a new \tcode{tzdb}
onto the front of this container.
\end{note}

\pnum
\returns
A reference to the first \tcode{tzdb} in the container.
\end{itemdescr}

\indexlibrarymember{erase_after}{tzdb_list}%
\begin{itemdecl}
const_iterator erase_after(const_iterator p);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
The iterator following \tcode{p} is dereferenceable.

\pnum
\effects
Erases the \tcode{tzdb} referred to by the iterator following \tcode{p}.

\pnum
\ensures
No pointers, references, or iterators are invalidated
except those referring to the erased \tcode{tzdb}.
\begin{note}
It is not possible to erase the \tcode{tzdb}
referred to by \tcode{begin()}.
\end{note}

\pnum
\returns
An iterator pointing to the element following the one that was erased,
or \tcode{end()} if no such element exists.

\pnum
\throws
Nothing.
\end{itemdescr}

\indexlibrarymember{begin}{tzdb_list}%
\begin{itemdecl}
const_iterator begin() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An iterator referring to the first \tcode{tzdb} in the container.
\end{itemdescr}

\indexlibrarymember{end}{tzdb_list}%
\begin{itemdecl}
const_iterator end() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
An iterator referring to the position one past the last \tcode{tzdb} in the container.
\end{itemdescr}

\indexlibrarymember{cbegin}{tzdb_list}%
\begin{itemdecl}
const_iterator cbegin() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{begin()}.
\end{itemdescr}

\indexlibrarymember{cend}{tzdb_list}%
\begin{itemdecl}
const_iterator cend() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{end()}.
\end{itemdescr}

\rSec3[time.zone.db.access]{Time zone database access}

\indexlibraryglobal{get_tzdb_list}%
\begin{itemdecl}
tzdb_list& get_tzdb_list();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
If this is the first access to the time zone database,
initializes the database.
If this call initializes the database,
the resulting database will be a \tcode{tzdb_list}
holding a single initialized \tcode{tzdb}.

\pnum
\sync
It is safe to call this function from multiple threads at one time.

\pnum
\returns
A reference to the database.

\pnum
\throws
\tcode{runtime_error} if for any reason
a reference cannot be returned to a valid \tcode{tzdb_list}
containing one or more valid \tcode{tzdb}s.
\end{itemdescr}

\indexlibraryglobal{get_tzdb}%
\begin{itemdecl}
const tzdb& get_tzdb();
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{get_tzdb_list().front()}.
\end{itemdescr}

\indexlibraryglobal{locate_zone}%
\begin{itemdecl}
const time_zone* locate_zone(string_view tz_name);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{get_tzdb().locate_zone(tz_name)}.

\pnum
\begin{note}
The time zone database will be initialized
if this is the first reference to the database.
\end{note}
\end{itemdescr}

\indexlibraryglobal{current_zone}%
\begin{itemdecl}
const time_zone* current_zone();
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{get_tzdb().current_zone()}.
\end{itemdescr}

\rSec3[time.zone.db.remote]{Remote time zone database support}

\pnum
The local time zone database
is that supplied by the implementation
when the program first accesses the database,
for example via \tcode{current_zone()}.
While the program is running,
the implementation may choose to update the time zone database.
This update shall not impact the program in any way
unless the program calls the functions in this subclause.
This potentially updated time zone database
is referred to as the \defn{remote time zone database}.

\indexlibraryglobal{reload_tzdb}%
\begin{itemdecl}
const tzdb& reload_tzdb();
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
This function first checks
the version of the remote time zone database.
If the versions of the local and remote databases are the same,
there are no effects.
Otherwise the remote database is pushed
to the front of the \tcode{tzdb_list}
accessed by \tcode{get_tzdb_list()}.

\pnum
\sync
This function is thread-safe with respect to
\tcode{get_tzdb_list().front()} and \tcode{get_tzdb_list().erase_after()}.

\pnum
\ensures
No pointers, references, or iterators are invalidated.

\pnum
\returns
\tcode{get_tzdb_list().front()}.

\pnum
\throws
\tcode{runtime_error} if for any reason
a reference cannot be returned to a valid \tcode{tzdb}.
\end{itemdescr}

\indexlibraryglobal{remote_version}%
\begin{itemdecl}
string remote_version();
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The latest remote database version.

\begin{note}
This can be compared with \tcode{get_tzdb().version}
to discover if the local and remote databases are equivalent.
\end{note}
\end{itemdescr}

\rSec2[time.zone.exception]{Exception classes}

\rSec3[time.zone.exception.nonexist]{Class \tcode{nonexistent_local_time}}
\indexlibraryglobal{nonexistent_local_time}

\begin{codeblock}
namespace std::chrono {
  class nonexistent_local_time : public runtime_error {
  public:
    template<class Duration>
      nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
  };
}
\end{codeblock}

\pnum
\tcode{nonexistent_local_time} is thrown when
an attempt is made
to convert a non-existent \tcode{local_time} to a \tcode{sys_time}
without specifying \tcode{choose::earliest} or \tcode{choose::latest}.

\indexlibraryctor{nonexistent_local_time}%
\begin{itemdecl}
template<class Duration>
  nonexistent_local_time(const local_time<Duration>& tp, const local_info& i);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{i.result == local_info::nonexistent} is \tcode{true}.

\pnum
\effects
Initializes the base class with a sequence of \tcode{char}
equivalent to that produced by \tcode{os.str()}
initialized as shown below:

\begin{codeblock}
ostringstream os;
os << tp << " is in a gap between\n"
   << local_seconds{i.first.end.time_since_epoch()} + i.first.offset << ' '
   << i.first.abbrev << " and\n"
   << local_seconds{i.second.begin.time_since_epoch()} + i.second.offset << ' '
   << i.second.abbrev
   << " which are both equivalent to\n"
   << i.first.end << " UTC";
\end{codeblock}

\pnum
\begin{example}
\begin{codeblock}
#include <chrono>
#include <iostream>

int main() {
  using namespace std::chrono;
  try {
    auto zt = zoned_time{"America/New_York",
                         local_days{Sunday[2]/March/2016} + 2h + 30min};
  } catch (const nonexistent_local_time& e) {
    std::cout << e.what() << '\n';
  }
}
\end{codeblock}

Produces the output:

\begin{outputblock}
2016-03-13 02:30:00 is in a gap between
2016-03-13 02:00:00 EST and
2016-03-13 03:00:00 EDT which are both equivalent to
2016-03-13 07:00:00 UTC
\end{outputblock}
\end{example}
\end{itemdescr}

\rSec3[time.zone.exception.ambig]{Class \tcode{ambiguous_local_time}}
\indexlibraryglobal{ambiguous_local_time}

\begin{codeblock}
namespace std::chrono {
  class ambiguous_local_time : public runtime_error {
  public:
    template<class Duration>
      ambiguous_local_time(const local_time<Duration>& tp, const local_info& i);
  };
}
\end{codeblock}

\pnum
\tcode{ambiguous_local_time} is thrown when
an attempt is made
to convert an ambiguous \tcode{local_time} to a \tcode{sys_time}
without specifying \tcode{choose::earliest} or \tcode{choose::latest}.

\indexlibraryctor{ambiguous_local_time}%
\begin{itemdecl}
template<class Duration>
  ambiguous_local_time(const local_time<Duration>& tp, const local_info& i);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{i.result == local_info::ambiguous} is \tcode{true}.

\pnum
\effects
Initializes the base class with a sequence of \tcode{char}
equivalent to that produced by \tcode{os.str()}
initialized as shown below:

\begin{codeblock}
ostringstream os;
os << tp << " is ambiguous.  It could be\n"
   << tp << ' ' << i.first.abbrev << " == "
   << tp - i.first.offset << " UTC or\n"
   << tp << ' ' << i.second.abbrev  << " == "
   << tp - i.second.offset  << " UTC";
\end{codeblock}

\pnum
\begin{example}
\begin{codeblock}
#include <chrono>
#include <iostream>

int main() {
  using namespace std::chrono;
  try {
    auto zt = zoned_time{"America/New_York",
                         local_days{Sunday[1]/November/2016} + 1h + 30min};
  } catch (const ambiguous_local_time& e) {
    std::cout << e.what() << '\n';
  }
}
\end{codeblock}

Produces the output:

\begin{outputblock}
2016-11-06 01:30:00 is ambiguous.  It could be
2016-11-06 01:30:00 EDT == 2016-11-06 05:30:00 UTC or
2016-11-06 01:30:00 EST == 2016-11-06 06:30:00 UTC
\end{outputblock}
\end{example}
\end{itemdescr}

\rSec2[time.zone.info]{Information classes}

\rSec3[time.zone.info.sys]{Class \tcode{sys_info}}
\indexlibraryglobal{sys_info}

\begin{codeblock}
namespace std::chrono {
  struct sys_info {
    sys_seconds begin;
    sys_seconds end;
    seconds     offset;
    minutes     save;
    string      abbrev;
  };
}
\end{codeblock}

\pnum
A \tcode{sys_info} object can be obtained
from the combination of a \tcode{time_zone} and
either a \tcode{sys_time} or \tcode{local_time}.
It can also be obtained from a \tcode{zoned_time},
which is effectively a pair of a \tcode{time_zone} and \tcode{sys_time}.

\pnum
\begin{note}
This type provides a low-level interface to time zone information.
Typical conversions from \tcode{sys_time} to \tcode{local_time}
will use this class implicitly, not explicitly.
\end{note}

\pnum
\indexlibrarymember{begin}{sys_info}%
\indexlibrarymember{end}{sys_info}%
The \tcode{begin} and \tcode{end} data members indicate that,
for the associated \tcode{time_zone} and \tcode{time_point},
the \tcode{offset} and \tcode{abbrev} are in effect in the range \range{begin}{end}.
This information can be used to efficiently iterate the transitions of a \tcode{time_zone}.

\pnum
\indexlibrarymember{offset}{sys_info}%
The \tcode{offset} data member indicates
the UTC offset in effect
for the associated \tcode{time_zone} and \tcode{time_point}.
The relationship between \tcode{local_time} and \tcode{sys_time} is:

\begin{codeblock}
offset = local_time - sys_time
\end{codeblock}

\pnum
\indexlibrarymember{save}{sys_info}%
The \tcode{save} data member is extra information not normally needed
for conversion between \tcode{local_time} and \tcode{sys_time}.
If \tcode{save != 0min}, this \tcode{sys_info} is said to be on ``daylight saving'' time,
and \tcode{offset - save} suggests what offset this \tcode{time_zone} might use
if it were off daylight saving time.
However, this information should not be taken as authoritative.
The only sure way to get such information
is to query the \tcode{time_zone} with a \tcode{time_point}
that returns a \tcode{sys_info} where \tcode{save == 0min}.
There is no guarantee what \tcode{time_point} might return such a \tcode{sys_info}
except that it is guaranteed not to be in the range \range{begin}{end}
(if \tcode{save != 0min} for this \tcode{sys_info}).

\pnum
\indexlibrarymember{abbrev}{sys_info}%
The \tcode{abbrev} data member indicates
the current abbreviation used for the associated \tcode{time_zone} and \tcode{time_point}.
Abbreviations are not unique among the \tcode{time_zones},
and so one cannot reliably map abbreviations back to a \tcode{time_zone} and UTC offset.

\indexlibrarymember{operator<<}{sys_info}
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const sys_info& r);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Streams out the \tcode{sys_info} object \tcode{r} in an unspecified format.

\pnum
\returns
\tcode{os}.
\end{itemdescr}

\rSec3[time.zone.info.local]{Class \tcode{local_info}}
\indexlibraryglobal{local_info}

\indexlibrarymember{unique}{local_info}%
\indexlibrarymember{nonexistent}{local_info}%
\indexlibrarymember{ambiguous}{local_info}%
\indexlibrarymember{result}{local_info}%
\indexlibrarymember{first}{local_info}%
\indexlibrarymember{second}{local_info}%
\begin{codeblock}
namespace std::chrono {
  struct local_info {
    static constexpr int unique      = 0;
    static constexpr int nonexistent = 1;
    static constexpr int ambiguous   = 2;

    int result;
    sys_info first;
    sys_info second;
  };
}
\end{codeblock}

\pnum
\begin{note}
This type provides a low-level interface to time zone information.
Typical conversions from \tcode{local_time} to \tcode{sys_time}
will use this class implicitly, not explicitly.
\end{note}

\pnum
Describes the result of converting a \tcode{local_time} to a \tcode{sys_time}
as follows:
\begin{itemize}
\item
When a \tcode{local_time} to \tcode{sys_time} conversion is unique,
\tcode{result == unique},
\tcode{first} will be filled out with the correct \tcode{sys_info},
and
\tcode{second} will be zero-initialized.

\item
If the conversion stems from a nonexistent \tcode{local_time}
then \tcode{result == nonexistent},
\tcode{first} will be filled out with the \tcode{sys_info}
that ends just prior to the \tcode{local_time},
and
\tcode{second} will be filled out with the \tcode{sys_info}
that begins just after the \tcode{local_time}.

\item
If the conversion stems from an ambiguous \tcode{local_time},
then \tcode{result == ambiguous},
\tcode{first} will be filled out with the \tcode{sys_info}
that ends just after the \tcode{local_time},
and
\tcode{second} will be filled out with the \tcode{sys_info}
that starts just before the \tcode{local_time}.
\end{itemize}

\indexlibrarymember{operator<<}{local_info}%
\begin{itemdecl}
template<class charT, class traits>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os, const local_info& r);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Streams out the \tcode{local_info} object \tcode{r} in an unspecified format.

\pnum
\returns
\tcode{os}.
\end{itemdescr}

\rSec2[time.zone.timezone]{Class \tcode{time_zone}}

\rSec3[time.zone.overview]{Overview}
\indexlibraryglobal{time_zone}

\begin{codeblock}
namespace std::chrono {
  class time_zone {
  public:
    time_zone(time_zone&&) = default;
    time_zone& operator=(time_zone&&) = default;

    // unspecified additional constructors

    string_view name() const noexcept;

    template<class Duration> sys_info   get_info(const sys_time<Duration>& st)   const;
    template<class Duration> local_info get_info(const local_time<Duration>& tp) const;

    template<class Duration>
      sys_time<common_type_t<Duration, seconds>>
        to_sys(const local_time<Duration>& tp) const;

    template<class Duration>
      sys_time<common_type_t<Duration, seconds>>
        to_sys(const local_time<Duration>& tp, choose z) const;

    template<class Duration>
      local_time<common_type_t<Duration, seconds>>
        to_local(const sys_time<Duration>& tp) const;
  };
}
\end{codeblock}

\pnum
A \tcode{time_zone} represents all time zone transitions
for a specific geographic area.
\tcode{time_zone} construction is unspecified,
and performed as part of database initialization.
\begin{note}
\tcode{const time_zone} objects can be accessed
via functions such as \tcode{locate_zone}.
\end{note}

\rSec3[time.zone.members]{Member functions}

\indexlibrarymember{name}{time_zone}%
\begin{itemdecl}
string_view name() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The name of the \tcode{time_zone}.

\pnum
\begin{example}
\tcode{"America/New_York"}.
\end{example}
\end{itemdescr}

\indexlibrarymember{get_info}{time_zone}%
\begin{itemdecl}
template<class Duration>
  sys_info get_info(const sys_time<Duration>& st) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{sys_info} \tcode{i} for which
\tcode{st} is in the range \range{i.begin}{i.end}.
\end{itemdescr}

\indexlibrarymember{get_info}{time_zone}%
\begin{itemdecl}
template<class Duration>
  local_info get_info(const local_time<Duration>& tp) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{local_info} for \tcode{tp}.
\end{itemdescr}

\indexlibrarymember{to_sys}{time_zone}%
\begin{itemdecl}
template<class Duration>
  sys_time<common_type_t<Duration, seconds>>
    to_sys(const local_time<Duration>& tp) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{sys_time} that is at least as fine as \tcode{seconds},
and will be finer if the argument \tcode{tp} has finer precision.
This \tcode{sys_time} is the UTC equivalent of \tcode{tp}
according to the rules of this \tcode{time_zone}.

\pnum
\throws
If the conversion from \tcode{tp} to a \tcode{sys_time} is ambiguous,
throws \tcode{ambiguous_local_time}.
If the \tcode{tp} represents a non-existent time between two UTC \tcode{time_points},
throws \tcode{nonexistent_local_time}.
\end{itemdescr}

\indexlibrarymember{to_sys}{time_zone}%
\begin{itemdecl}
template<class Duration>
  sys_time<common_type_t<Duration, seconds>>
    to_sys(const local_time<Duration>& tp, choose z) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
A \tcode{sys_time} that is at least as fine as \tcode{seconds},
and will be finer if the argument \tcode{tp} has finer precision.
This \tcode{sys_time} is the UTC equivalent of \tcode{tp}
according to the rules of this \tcode{time_zone}.
If the conversion from \tcode{tp} to a \tcode{sys_time} is ambiguous,
returns the earlier \tcode{sys_time} if \tcode{z == choose::earliest}, and
returns the later \tcode{sys_time} if \tcode{z == choose::latest}.
If the \tcode{tp} represents a non-existent time between two UTC \tcode{time_points},
then the two UTC \tcode{time_points} will be the same,
and that UTC \tcode{time_point} will be returned.
\end{itemdescr}

\indexlibrarymember{to_local}{time_zone}%
\begin{itemdecl}
template<class Duration>
  local_time<common_type_t<Duration, seconds>>
    to_local(const sys_time<Duration>& tp) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The \tcode{local_time} associated with \tcode{tp} and this \tcode{time_zone}.
\end{itemdescr}

\rSec3[time.zone.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{time_zone}%
\begin{itemdecl}
bool operator==(const time_zone& x, const time_zone& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.name() == y.name()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{time_zone}%
\begin{itemdecl}
strong_ordering operator<=>(const time_zone& x, const time_zone& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.name() <=> y.name()}.
\end{itemdescr}

\rSec2[time.zone.zonedtraits]{Class template \tcode{zoned_traits}}
\indexlibraryglobal{zoned_traits}

\begin{codeblock}
namespace std::chrono {
  template<class T> struct zoned_traits {};
}
\end{codeblock}

\pnum
\tcode{zoned_traits} provides a means for customizing
the behavior of \tcode{zoned_time<Duration, TimeZonePtr>}
for the \tcode{zoned_time} default constructor,
and constructors taking \tcode{string_view}.
A specialization for \tcode{const time_zone*} is provided by the implementation:

\begin{codeblock}
namespace std::chrono {
  template<> struct zoned_traits<const time_zone*> {
    static const time_zone* default_zone();
    static const time_zone* locate_zone(string_view name);
  };
}
\end{codeblock}

\indexlibrarymember{default_zone}{zoned_traits<const time_zone*>}%
\begin{itemdecl}
static const time_zone* default_zone();
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{std::chrono::locate_zone("UTC")}.
\end{itemdescr}

\indexlibrarymember{locate_zone}{zoned_traits<const time_zone*>}%
\begin{itemdecl}
static const time_zone* locate_zone(string_view name);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{std::chrono::locate_zone(name)}.
\end{itemdescr}

\rSec2[time.zone.zonedtime]{Class template \tcode{zoned_time}}

\rSec3[time.zone.zonedtime.overview]{Overview}
\indexlibraryglobal{zoned_time}

\begin{codeblock}
namespace std::chrono {
  template<class Duration, class TimeZonePtr = const time_zone*>
  class zoned_time {
  public:
    using duration = common_type_t<Duration, seconds>;

  private:
    TimeZonePtr        zone_;                   // \expos
    sys_time<duration> tp_;                     // \expos

    using traits = zoned_traits<TimeZonePtr>;   // \expos

  public:
    zoned_time();
    zoned_time(const zoned_time&) = default;
    zoned_time& operator=(const zoned_time&) = default;

    zoned_time(const sys_time<Duration>& st);
    explicit zoned_time(TimeZonePtr z);
    explicit zoned_time(string_view name);

    template<class Duration2>
      zoned_time(const zoned_time<Duration2, TimeZonePtr>& y);

    zoned_time(TimeZonePtr z,    const sys_time<Duration>& st);
    zoned_time(string_view name, const sys_time<Duration>& st);

    zoned_time(TimeZonePtr z,    const local_time<Duration>& tp);
    zoned_time(string_view name, const local_time<Duration>& tp);
    zoned_time(TimeZonePtr z,    const local_time<Duration>& tp, choose c);
    zoned_time(string_view name, const local_time<Duration>& tp, choose c);

    template<class Duration2, class TimeZonePtr2>
      zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& y);
    template<class Duration2, class TimeZonePtr2>
      zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& y, choose);

    template<class Duration2, class TimeZonePtr2>
      zoned_time(string_view name, const zoned_time<Duration2, TimeZonePtr2>& y);
    template<class Duration2, class TimeZonePtr2>
      zoned_time(string_view name, const zoned_time<Duration2, TimeZonePtr2>& y, choose c);

    zoned_time& operator=(const sys_time<Duration>& st);
    zoned_time& operator=(const local_time<Duration>& lt);

    operator sys_time<duration>() const;
    explicit operator local_time<duration>() const;

    TimeZonePtr          get_time_zone()  const;
    local_time<duration> get_local_time() const;
    sys_time<duration>   get_sys_time()   const;
    sys_info             get_info()       const;
  };

  zoned_time() -> zoned_time<seconds>;

  template<class Duration>
    zoned_time(sys_time<Duration>)
      -> zoned_time<common_type_t<Duration, seconds>>;

  template<class TimeZonePtrOrName>
    using @\exposid{time-zone-representation}@ =        // \expos
      conditional_t<is_convertible_v<TimeZonePtrOrName, string_view>,
                    const time_zone*,
                    remove_cvref_t<TimeZonePtrOrName>>;

  template<class TimeZonePtrOrName>
    zoned_time(TimeZonePtrOrName&&)
      -> zoned_time<seconds, @\exposid{time-zone-representation}@<TimeZonePtrOrName>>;

  template<class TimeZonePtrOrName, class Duration>
    zoned_time(TimeZonePtrOrName&&, sys_time<Duration>)
      -> zoned_time<common_type_t<Duration, seconds>,
                    @\exposid{time-zone-representation}@<TimeZonePtrOrName>>;

  template<class TimeZonePtrOrName, class Duration>
    zoned_time(TimeZonePtrOrName&&, local_time<Duration>,
               choose = choose::earliest)
      -> zoned_time<common_type_t<Duration, seconds>,
                    @\exposid{time-zone-representation}@<TimeZonePtrOrName>>;

  template<class Duration, class TimeZonePtrOrName, class TimeZonePtr2>
    zoned_time(TimeZonePtrOrName&&, zoned_time<Duration, TimeZonePtr2>,
               choose = choose::earliest)
      -> zoned_time<common_type_t<Duration, seconds>,
                    @\exposid{time-zone-representation}@<TimeZonePtrOrName>>;
}
\end{codeblock}

\pnum
\tcode{zoned_time} represents a logical pairing of
a \tcode{time_zone} and a \tcode{time_point} with precision \tcode{Duration}.
\tcode{zoned_time<Duration>} maintains the invariant that
it always refers to a valid time zone and
represents a point in time that exists and is not ambiguous
in that time zone.

\pnum
If \tcode{Duration} is not a specialization of \tcode{chrono::duration},
the program is ill-formed.

\pnum
Every constructor of \tcode{zoned_time} that
accepts a \tcode{string_view} as its first parameter
does not participate in
class template argument deduction\iref{over.match.class.deduct}.

\rSec3[time.zone.zonedtime.ctor]{Constructors}

\indexlibrary{\idxcode{zoned_time}!constructor|(}%
\begin{itemdecl}
zoned_time();
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{traits::default_zone()} is a well-formed expression.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{traits::default_zone()} and
default constructs \tcode{tp_}.
\end{itemdescr}

\begin{itemdecl}
zoned_time(const sys_time<Duration>& st);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{traits::default_zone()} is a well-formed expression.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{traits::default_zone()} and \tcode{tp_} with \tcode{st}.
\end{itemdescr}

\begin{itemdecl}
explicit zoned_time(TimeZonePtr z);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{z} refers to a time zone.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{std::move(z)} and
default constructs \tcode{tp_}.
\end{itemdescr}

\begin{itemdecl}
explicit zoned_time(string_view name);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{traits::locate_zone(string_view\{\})} is a well-formed expression and
\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(string_view\{\})}.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{traits::locate_zone(name)} and
default constructs \tcode{tp_}.
\end{itemdescr}

\begin{itemdecl}
template<class Duration2>
  zoned_time(const zoned_time<Duration2, TimeZonePtr>& y);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<sys_time<Duration2>, sys_time<Duration>>} is \tcode{true}.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{y.zone_} and \tcode{tp_} with \tcode{y.tp_}.
\end{itemdescr}

\begin{itemdecl}
zoned_time(TimeZonePtr z, const sys_time<Duration>& st);
\end{itemdecl}

\begin{itemdescr}
\pnum
\expects
\tcode{z} refers to a time zone.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{st}.
\end{itemdescr}

\begin{itemdecl}
zoned_time(string_view name, const sys_time<Duration>& st);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{st}.

\pnum
\effects
Equivalent to construction with \tcode{\{traits::locate_zone(name), st\}}.
\end{itemdescr}

\begin{itemdecl}
zoned_time(TimeZonePtr z, const local_time<Duration>& tp);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\begin{codeblock}
is_convertible_v<
  decltype(declval<TimeZonePtr&>()->to_sys(local_time<Duration>{})),
  sys_time<duration>>
\end{codeblock}
is \tcode{true}.

\pnum
\expects
\tcode{z} refers to a time zone.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{zone_->to_sys(tp)}.
\end{itemdescr}

\begin{itemdecl}
zoned_time(string_view name, const local_time<Duration>& tp);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{zoned_time} is constructible from the return type of \tcode{traits::locate_zone(name)} and \tcode{tp}.

\pnum
\effects
Equivalent to construction with \tcode{\{traits::locate_zone(name), tp\}}.
\end{itemdescr}

\begin{itemdecl}
zoned_time(TimeZonePtr z, const local_time<Duration>& tp, choose c);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\begin{codeblock}
is_convertible_v<
  decltype(declval<TimeZonePtr&>()->to_sys(local_time<Duration>{}, choose::earliest)),
  sys_time<duration>>
\end{codeblock}
is \tcode{true}.

\pnum
\expects
\tcode{z} refers to a time zone.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{zone_->to_sys(tp, c)}.
\end{itemdescr}

\begin{itemdecl}
zoned_time(string_view name, const local_time<Duration>& tp, choose c);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{zoned_time} is constructible from
the return type of \tcode{traits::locate_zone(name)}, \tcode{local_time<Duration>}, and \tcode{choose}.

\pnum
\effects
Equivalent to construction with \tcode{\{traits::locate_zone(name), tp, c\}}.
\end{itemdescr}

\begin{itemdecl}
template<class Duration2, class TimeZonePtr2>
  zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& y);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<sys_time<Duration2>, sys_time<Duration>>} is \tcode{true}.

\pnum
\expects
\tcode{z} refers to a valid time zone.

\pnum
\effects
Initializes \tcode{zone_} with \tcode{std::move(z)} and \tcode{tp_} with \tcode{y.tp_}.
\end{itemdescr}

\begin{itemdecl}
template<class Duration2, class TimeZonePtr2>
  zoned_time(TimeZonePtr z, const zoned_time<Duration2, TimeZonePtr2>& y, choose);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{is_convertible_v<sys_time<Duration2>, sys_time<Duration>>} is \tcode{true}.

\pnum
\expects
\tcode{z} refers to a valid time zone.

\pnum
\effects
Equivalent to construction with \tcode{\{z, y\}}.

\pnum
\begin{note}
The \tcode{choose} parameter has no effect.
\end{note}
\end{itemdescr}

\begin{itemdecl}
template<class Duration2, class TimeZonePtr2>
  zoned_time(string_view name, const zoned_time<Duration2, TimeZonePtr2>& y);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{zoned_time} is constructible from
the return type of \tcode{traits::locate_zone(name)} and
the type \tcode{zoned_time<Duration2, TimeZonePtr2>}.

\pnum
\effects
Equivalent to construction with \tcode{\{traits::locate_zone(name), y\}}.
\end{itemdescr}

\begin{itemdecl}
template<class Duration2, class TimeZonePtr2>
  zoned_time(string_view name, const zoned_time<Duration2, TimeZonePtr2>& y, choose c);
\end{itemdecl}

\begin{itemdescr}
\pnum
\constraints
\tcode{zoned_time} is constructible from
the return type of \tcode{traits::locate_zone(name)},
the type \tcode{zoned_time<Duration2, TimeZonePtr2>}, and
the type \tcode{choose}.

\pnum
\effects
Equivalent to construction with \tcode{\{traits::locate_zone(name), y, c\}}.

\pnum
\begin{note}
The \tcode{choose} parameter has no effect.
\end{note}
\end{itemdescr}
\indexlibrary{\idxcode{zoned_time}!constructor|)}%

\rSec3[time.zone.zonedtime.members]{Member functions}

\indexlibrarymember{operator=}{zoned_time}%
\begin{itemdecl}
zoned_time& operator=(const sys_time<Duration>& st);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
After assignment, \tcode{get_sys_time() == st}.
This assignment has no effect on the return value of \tcode{get_time_zone()}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator=}{zoned_time}%
\begin{itemdecl}
zoned_time& operator=(const local_time<Duration>& lt);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
After assignment, \tcode{get_local_time() == lt}.
This assignment has no effect on the return value of \tcode{get_time_zone()}.

\pnum
\returns
\tcode{*this}.
\end{itemdescr}

\indexlibrarymember{operator sys_time}{zoned_time}%
\begin{itemdecl}
operator sys_time<duration>() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{get_sys_time()}.
\end{itemdescr}

\indexlibrarymember{operator local_time}{zoned_time}%
\begin{itemdecl}
explicit operator local_time<duration>() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{get_local_time()}.
\end{itemdescr}

\indexlibrarymember{get_time_zone}{zoned_time}%
\begin{itemdecl}
TimeZonePtr get_time_zone() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{zone_}.
\end{itemdescr}

\indexlibrarymember{get_local_time}{zoned_time}%
\begin{itemdecl}
local_time<duration> get_local_time() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{zone_->to_local(tp_)}.
\end{itemdescr}

\indexlibrarymember{get_sys_time}{zoned_time}%
\begin{itemdecl}
sys_time<duration> get_sys_time() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{tp_}.
\end{itemdescr}

\indexlibrarymember{get_info}{zoned_time}%
\begin{itemdecl}
sys_info get_info() const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{zone_->get_info(tp_)}.
\end{itemdescr}

\rSec3[time.zone.zonedtime.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{zoned_time}%
\begin{itemdecl}
template<class Duration1, class Duration2, class TimeZonePtr>
  bool operator==(const zoned_time<Duration1, TimeZonePtr>& x,
                  const zoned_time<Duration2, TimeZonePtr>& y);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.zone_ == y.zone_ \&\& x.tp_ == y.tp_}.
\end{itemdescr}

\indexlibrarymember{operator<<}{zoned_time}%
\begin{itemdecl}
template<class charT, class traits, class Duration, class TimeZonePtr>
  basic_ostream<charT, traits>&
    operator<<(basic_ostream<charT, traits>& os,
               const zoned_time<Duration, TimeZonePtr>& t);
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
return os << format(os.getloc(), @\placeholder{STATICALLY-WIDEN}@<charT>("{:L%F %T %Z}"), t);
\end{codeblock}
\end{itemdescr}

\rSec2[time.zone.leap]{Class \tcode{leap_second}}

\rSec3[time.zone.leap.overview]{Overview}
\indexlibraryglobal{leap_second}

\begin{codeblock}
namespace std::chrono {
  class leap_second {
  public:
    leap_second(const leap_second&)            = default;
    leap_second& operator=(const leap_second&) = default;

    // unspecified additional constructors

    constexpr sys_seconds date() const noexcept;
    constexpr seconds value() const noexcept;
  };
}
\end{codeblock}

\pnum
Objects of type \tcode{leap_second} representing
the date and value of the leap second insertions
are constructed and stored in the time zone database when initialized.

\pnum
\begin{example}
\begin{codeblock}
for (auto& l : get_tzdb().leap_seconds)
  if (l <= sys_days{2018y/March/17d})
    cout << l.date() << ": " << l.value() << '\n';
\end{codeblock}

Produces the output:

\begin{outputblock}
1972-07-01 00:00:00: 1s
1973-01-01 00:00:00: 1s
1974-01-01 00:00:00: 1s
1975-01-01 00:00:00: 1s
1976-01-01 00:00:00: 1s
1977-01-01 00:00:00: 1s
1978-01-01 00:00:00: 1s
1979-01-01 00:00:00: 1s
1980-01-01 00:00:00: 1s
1981-07-01 00:00:00: 1s
1982-07-01 00:00:00: 1s
1983-07-01 00:00:00: 1s
1985-07-01 00:00:00: 1s
1988-01-01 00:00:00: 1s
1990-01-01 00:00:00: 1s
1991-01-01 00:00:00: 1s
1992-07-01 00:00:00: 1s
1993-07-01 00:00:00: 1s
1994-07-01 00:00:00: 1s
1996-01-01 00:00:00: 1s
1997-07-01 00:00:00: 1s
1999-01-01 00:00:00: 1s
2006-01-01 00:00:00: 1s
2009-01-01 00:00:00: 1s
2012-07-01 00:00:00: 1s
2015-07-01 00:00:00: 1s
2017-01-01 00:00:00: 1s
\end{outputblock}
\end{example}

\rSec3[time.zone.leap.members]{Member functions}

\indexlibrarymember{date}{leap_second}%
\begin{itemdecl}
constexpr sys_seconds date() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The date and time at which the leap second was inserted.
\end{itemdescr}

\indexlibrarymember{value}{leap_second}%
\begin{itemdecl}
constexpr seconds value() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{+1s} to indicate a positive leap second or
\tcode{-1s} to indicate a negative leap second.
\begin{note}
All leap seconds inserted up through 2022 were positive leap seconds.
\end{note}
\end{itemdescr}

\rSec3[time.zone.leap.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{leap_second}%
\begin{itemdecl}
constexpr bool operator==(const leap_second& x, const leap_second& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.date() == y.date()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{leap_second}%
\begin{itemdecl}
constexpr strong_ordering operator<=>(const leap_second& x, const leap_second& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.date() <=> y.date()}.
\end{itemdescr}

\indexlibrarymember{operator==}{leap_second}%
\indexlibrarymember{operator==}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator==(const leap_second& x, const sys_time<Duration>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.date() == y}.
\end{itemdescr}

\indexlibrarymember{operator<}{leap_second}%
\indexlibrarymember{operator<}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator<(const leap_second& x, const sys_time<Duration>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.date() < y}.
\end{itemdescr}

\indexlibrarymember{operator<}{leap_second}%
\indexlibrarymember{operator<}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator<(const sys_time<Duration>& x, const leap_second& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x < y.date()}.
\end{itemdescr}

\indexlibrarymember{operator>}{leap_second}%
\indexlibrarymember{operator>}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator>(const leap_second& x, const sys_time<Duration>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y < x}.
\end{itemdescr}

\indexlibrarymember{operator>}{leap_second}%
\indexlibrarymember{operator>}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator>(const sys_time<Duration>& x, const leap_second& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{y < x}.
\end{itemdescr}

\indexlibrarymember{operator<=}{leap_second}%
\indexlibrarymember{operator<=}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator<=(const leap_second& x, const sys_time<Duration>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!(y < x)}.
\end{itemdescr}

\indexlibrarymember{operator<=}{leap_second}%
\indexlibrarymember{operator<=}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator<=(const sys_time<Duration>& x, const leap_second& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!(y < x)}.
\end{itemdescr}

\indexlibrarymember{operator>=}{leap_second}%
\indexlibrarymember{operator>=}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator>=(const leap_second& x, const sys_time<Duration>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!(x < y)}.
\end{itemdescr}

\indexlibrarymember{operator>=}{leap_second}%
\indexlibrarymember{operator>=}{sys_time}%
\begin{itemdecl}
template<class Duration>
  constexpr bool operator>=(const sys_time<Duration>& x, const leap_second& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{!(x < y)}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{leap_second}%
\indexlibrarymember{operator<=>}{sys_time}%
\begin{itemdecl}
template<class Duration>
  requires @\libconcept{three_way_comparable_with}@<sys_seconds, sys_time<Duration>>
  constexpr auto operator<=>(const leap_second& x, const sys_time<Duration>& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.date() <=> y}.
\end{itemdescr}

\rSec2[time.zone.link]{Class \tcode{time_zone_link}}

\rSec3[time.zone.link.overview]{Overview}
\indexlibraryglobal{time_zone_link}

\begin{codeblock}
namespace std::chrono {
  class time_zone_link {
  public:
    time_zone_link(time_zone_link&&)            = default;
    time_zone_link& operator=(time_zone_link&&) = default;

    // unspecified additional constructors

    string_view name()   const noexcept;
    string_view target() const noexcept;
  };
}
\end{codeblock}

\pnum
A \tcode{time_zone_link} specifies an alternative name for a \tcode{time_zone}.
\tcode{time_zone_link}s are constructed when the time zone database is initialized.

\rSec3[time.zone.link.members]{Member functions}

\indexlibrarymember{name}{time_zone_link}%
\begin{itemdecl}
string_view name() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The alternative name for the time zone.
\end{itemdescr}

\indexlibrarymember{target}{time_zone_link}%
\begin{itemdecl}
string_view target() const noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
The name of the \tcode{time_zone} for which
this \tcode{time_zone_link} provides an alternative name.
\end{itemdescr}

\rSec3[time.zone.link.nonmembers]{Non-member functions}

\indexlibrarymember{operator==}{time_zone_link}%
\begin{itemdecl}
bool operator==(const time_zone_link& x, const time_zone_link& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.name() == y.name()}.
\end{itemdescr}

\indexlibrarymember{operator<=>}{time_zone_link}%
\begin{itemdecl}
strong_ordering operator<=>(const time_zone_link& x, const time_zone_link& y) noexcept;
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{x.name() <=> y.name()}.
\end{itemdescr}

\rSec1[time.format]{Formatting}
\indexlibrary{\idxcode{format}|(}%

\pnum
Each \tcode{formatter}\iref{format.formatter} specialization
in the chrono library\iref{time.syn}
meets the \newoldconcept{Formatter} requirements\iref{formatter.requirements}.
The \tcode{parse} member functions of these formatters
interpret the format specification
as a \fmtgrammarterm{chrono-format-spec}
according to the following syntax:

\begin{ncbnf}
\fmtnontermdef{chrono-format-spec}\br
    \opt{fill-and-align} \opt{width} \opt{precision} \opt{\terminal{L}} \opt{chrono-specs}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{chrono-specs}\br
    conversion-spec\br
    chrono-specs conversion-spec\br
    chrono-specs literal-char
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{literal-char}\br
    \textnormal{any character other than \tcode{\{}, \tcode{\}}, or \tcode{\%}}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{conversion-spec}\br
    \terminal{\%} \opt{modifier} type
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{modifier} \textnormal{one of}\br
    \terminal{E O}
\end{ncbnf}

\begin{ncbnf}
\fmtnontermdef{type} \textnormal{one of}\br
    \terminal{a A b B c C d D e F g G h H I j m M n}\br
    \terminal{p q Q r R S t T u U V w W x X y Y z Z \%}
\end{ncbnf}

The productions
\fmtgrammarterm{fill-and-align},
\fmtgrammarterm{width}, and
\fmtgrammarterm{precision}
are described in \ref{format.string}.
Giving a \fmtgrammarterm{precision} specification
in the \fmtgrammarterm{chrono-format-spec}
is valid only for types that are
specializations of \tcode{std::chrono::duration}
for which the nested \grammarterm{typedef-name} \tcode{rep} denotes
a floating-point type.
For all other types,
an exception of type \tcode{format_error} is thrown
if the \fmtgrammarterm{chrono-format-spec}
contains a \fmtgrammarterm{precision} specification.
All ordinary multibyte characters
represented by \fmtgrammarterm{literal-char}
are copied unchanged to the output.

\pnum
A \defnadj{formatting}{locale} is an instance of \tcode{locale}
used by a formatting function, defined as
\begin{itemize}
\item
the \tcode{"C"} locale if the \tcode{L} option
is not present in \fmtgrammarterm{chrono-format-spec}, otherwise
\item
the locale passed to the formatting function if any, otherwise
\item
the global locale.
\end{itemize}

\pnum
Each conversion specifier \fmtgrammarterm{conversion-spec}
is replaced by appropriate characters
as described in \tref{time.format.spec};
the formats specified in ISO 8601-1:2019 shall be used where so described.
Some of the conversion specifiers
depend on the formatting locale.
If the string literal encoding is a Unicode encoding form and
the locale is among
an \impldef{locales with Unicode support for chrono types} set of locales,
each replacement that depends on the locale is performed as if
the replacement character sequence is converted to the string literal encoding.
If the formatted object does not contain the information
the conversion specifier refers to,
an exception of type \tcode{format_error} is thrown.

\pnum
The result of formatting
a \tcode{std::chrono::duration} instance holding a negative value, or
an \tcode{hh_mm_ss} object \tcode{h} for which \tcode{h.is_negative()} is \tcode{true},
is equivalent to the output of the corresponding positive value,
with a \tcode{\exposid{STATICALLY-WIDEN}<charT>("-")} character sequence
placed before the replacement of the initial conversion specifier.
\begin{example}
\begin{codeblockdigitsep}
cout << format("{:%T}", -10'000s);          // prints: \tcode{-02:46:40}
cout << format("{:%H:%M:%S}", -10'000s);    // prints: \tcode{-02:46:40}
cout << format("minutes {:%M, hours %H, seconds %S}", -10'000s);
                                            // prints: \tcode{minutes -46, hours 02, seconds 40}
\end{codeblockdigitsep}
\end{example}

\pnum
Unless explicitly requested,
the result of formatting a chrono type
does not contain time zone abbreviation
and time zone offset information.
If the information is available,
the conversion specifiers \tcode{\%Z} and \tcode{\%z}
will format this information (respectively).
\begin{note}
If the information is not available and
a \tcode{\%Z} or \tcode{\%z}
conversion specifier appears in
the \fmtgrammarterm{chrono-format-spec},
an exception of type \tcode{format_error} is thrown,
as described above.
\end{note}

\pnum
If the type being formatted does not contain
the information that the format flag needs,
an exception of type \tcode{format_error} is thrown.
\begin{example}
A \tcode{duration} does not contain enough information
to format as a \tcode{weekday}.
\end{example}
However, if a flag refers to a ``time of day''
(e.g., \tcode{\%H}, \tcode{\%I}, \tcode{\%p}, etc.),
then a specialization of \tcode{duration} is interpreted as
the time of day elapsed since midnight.

\begin{LongTable}{Meaning of conversion specifiers}{time.format.spec}{lx{.8\hsize}}
\\ \topline
\lhdr{Specifier} & \rhdr{Replacement} \\ \capsep
\endfirsthead
\continuedcaption\\
\hline
\lhdr{Specifier} & \rhdr{Replacement} \\ \capsep
\endhead
\tcode{\%a} &
The locale's abbreviated weekday name.
If the value does not contain a valid weekday,
an exception of type \tcode{format_error} is thrown.
\\ \rowsep
\tcode{\%A} &
The locale's full weekday name.
If the value does not contain a valid weekday,
an exception of type \tcode{format_error} is thrown.
\\ \rowsep
\tcode{\%b} &
The locale's abbreviated month name.
If the value does not contain a valid month,
an exception of type \tcode{format_error} is thrown.
\\ \rowsep
\tcode{\%B} &
The locale's full month name.
If the value does not contain a valid month,
an exception of type \tcode{format_error} is thrown.
\\ \rowsep
\tcode{\%c} &
The locale's date and time representation.
The modified command \tcode{\%Ec} produces
the locale's alternate date and time representation.
\\ \rowsep
\tcode{\%C} &
The year divided by 100 using floored division.
If the result is a single decimal digit,
it is prefixed with \tcode{0}.
The modified command \tcode{\%EC} produces
the locale's alternative representation of the century.
\\ \rowsep
\tcode{\%d} &
The day of month as a decimal number.
If the result is a single decimal digit,
it is prefixed with \tcode{0}.
The modified command \tcode{\%Od} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%D} &
Equivalent to \tcode{\%m/\%d/\%y}.
\\ \rowsep
\tcode{\%e} &
The day of month as a decimal number.
If the result is a single decimal digit,
it is prefixed with a space.
The modified command \tcode{\%Oe} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%F} &
Equivalent to \tcode{\%Y-\%m-\%d}.
\\ \rowsep
\tcode{\%g} &
The last two decimal digits of the calendar year
as specified in ISO 8601-1:2019 for the week calendar.
If the result is a single digit it is prefixed by \tcode{0}.
\\ \rowsep
\tcode{\%G} &
The calendar year as a decimal number,
as specified in ISO 8601-1:2019 for the week calendar.
If the result is less than four digits
it is left-padded with \tcode{0} to four digits.
\\ \rowsep
\tcode{\%h} &
Equivalent to \tcode{\%b}.
\\ \rowsep
\tcode{\%H} &
The hour (24-hour clock) as a decimal number.
If the result is a single digit,
it is prefixed with \tcode{0}.
The modified command \tcode{\%OH} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%I} &
The hour (12-hour clock) as a decimal number.
If the result is a single digit,
it is prefixed with \tcode{0}.
The modified command \tcode{\%OI} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%j} &
If the type being formatted is a specialization of \tcode{duration},
the decimal number of \tcode{days} without padding.
Otherwise,
the day of the year as a decimal number.
January 1 is \tcode{001}.
If the result is less than three digits,
it is left-padded with \tcode{0} to three digits.
\\ \rowsep
\tcode{\%m} &
The month as a decimal number.
Jan is \tcode{01}.
If the result is a single digit, it is prefixed with \tcode{0}.
The modified command \tcode{\%Om} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%M} &
The minute as a decimal number.
If the result is a single digit, it is prefixed with \tcode{0}.
The modified command \tcode{\%OM} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%n} &
A new-line character.
\\ \rowsep
\tcode{\%p} &
The locale's equivalent of the AM/PM designations associated with a 12-hour clock.
\\ \rowsep
\tcode{\%q} &
The duration's unit suffix as specified in \ref{time.duration.io}.
\\ \rowsep
\tcode{\%Q} &
The duration's numeric value (as if extracted via \tcode{.count()}).
\\ \rowsep
\tcode{\%r} &
The locale's 12-hour clock time.
\\ \rowsep
\tcode{\%R} &
Equivalent to \tcode{\%H:\%M}.
\\ \rowsep
\tcode{\%S} &
Seconds as a decimal number.
If the number of seconds is less than \tcode{10}, the result is prefixed with \tcode{0}.
If the precision of the input cannot be exactly represented with seconds,
then the format is a decimal floating-point number with a fixed format
and a precision matching that of the precision of the input
(or to a microseconds precision if the conversion to floating-point decimal seconds
cannot be made within 18 fractional digits).
The character for the decimal point is localized according to the locale.
The modified command \tcode{\%OS} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%t} &
A horizontal-tab character.
\\ \rowsep
\tcode{\%T} &
Equivalent to \tcode{\%H:\%M:\%S}.
\\ \rowsep
\tcode{\%u} &
The calendar day of week as a decimal number (\tcode{1}-\tcode{7}),
as specified in ISO 8601-1:2019,
where Monday is \tcode{1}.
The modified command \tcode{\%Ou} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%U} &
The week number of the year as a decimal number.
The first Sunday of the year is the first day of week \tcode{01}.
Days of the same year prior to that are in week \tcode{00}.
If the result is a single digit, it is prefixed with \tcode{0}.
The modified command \tcode{\%OU} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%V} &
The calendar week of year as a decimal number,
as specified in ISO 8601-1:2019 for the week calendar.
If the result is a single digit, it is prefixed with \tcode{0}.
The modified command \tcode{\%OV} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%w} &
The weekday as a decimal number (\tcode{0}-\tcode{6}), where Sunday is \tcode{0}.
The modified command \tcode{\%Ow} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%W} &
The week number of the year as a decimal number.
The first Monday of the year is the first day of week \tcode{01}.
Days of the same year prior to that are in week \tcode{00}.
If the result is a single digit, it is prefixed with \tcode{0}.
The modified command \tcode{\%OW} produces
the locale's alternative representation.
\\ \rowsep
\tcode{\%x} &
The locale's date representation.
The modified command \tcode{\%Ex} produces
the locale's alternate date representation.
\\ \rowsep
\tcode{\%X} &
The locale's time representation.
The modified command \tcode{\%EX} produces
the locale's alternate time representation.
\\ \rowsep
\tcode{\%y} &
The last two decimal digits of the year.
If the result is a single digit, it is prefixed by \tcode{0}.
The modified command \tcode{\%Oy} produces the locale's alternative representation.
The modified command \tcode{\%Ey} produces the locale's alternative representation
of offset from \tcode{\%EC} (year only).
\\ \rowsep
\tcode{\%Y} &
The year as a decimal number.
If the result is less than four digits,
it is left-padded with \tcode{0} to four digits.
The modified command \tcode{\%EY} produces
the locale's alternative full year representation.
\\ \rowsep
\tcode{\%z} &
The offset from UTC as specified in ISO 8601-1:2019, 5.3.4.1.
For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC\@.
If the offset is zero, \tcode{+0000} is used.
The modified commands \tcode{\%Ez} and  \tcode{\%Oz}
insert a \tcode{:} between the hours and minutes: \tcode{-04:30}.
If the offset information is not available,
an exception of type \tcode{format_error} is thrown.
\\ \rowsep
\tcode{\%Z} &
The time zone abbreviation.
If the time zone abbreviation is not available,
an exception of type \tcode{format_error} is thrown.
\\ \rowsep
\tcode{\%\%} &
A \tcode{\%} character.
\\
\end{LongTable}

\pnum
Unless otherwise specified,
if the \fmtgrammarterm{chrono-specs} is omitted,
the chrono object is formatted
as if by streaming it to \tcode{basic_ostring\-stream<charT> os}
with the formatting locale imbued
and copying \tcode{os.str()} through the output iterator of the context
with additional padding and adjustments as specified by the format specifiers.
\begin{example}
\begin{codeblock}
string s = format("{:=>8}", 42ms);      // value of \tcode{s} is \tcode{"====42ms"}
\end{codeblock}
\end{example}

\pnum
For \tcode{chrono::duration}
the library only provides the following specialization
of \tcode{enable_nonlocking_formatter_optimization}:
\begin{codeblock}
template<class Rep, class Period>
  constexpr bool enable_nonlocking_formatter_optimization<
    chrono::duration<Rep, Period>> =
      enable_nonlocking_formatter_optimization<Rep>;
\end{codeblock}

\pnum
For \tcode{chrono::zoned_time}
the library only provides the following specialization of
\tcode{enable_nonlocking_formatter_optimization}:
\begin{codeblock}
template<class Duration>
  constexpr bool enable_nonlocking_formatter_optimization<
    chrono::zoned_time<Duration, const std::chrono::time_zone*>> = true;
\end{codeblock}

\indexlibrary{\idxcode{formatter}!specializations!\idxcode{chrono::sys_time}}%
\begin{itemdecl}
template<class Duration, class charT>
  struct formatter<chrono::sys_time<Duration>, charT>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
If \tcode{\%Z} is used,
it is replaced with \tcode{\exposid{STATICALLY-WIDEN}<charT>("UTC")}.
If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used,
an offset of \tcode{0min} is formatted.
\end{itemdescr}

\indexlibrary{\idxcode{formatter}!specializations!\idxcode{chrono::utc_time}}%
\begin{itemdecl}
template<class Duration, class charT>
  struct formatter<chrono::utc_time<Duration>, charT>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
If \tcode{\%Z} is used,
it is replaced with \tcode{\exposid{STATICALLY-WIDEN}<charT>("UTC")}.
If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used,
an offset of \tcode{0min} is formatted.
If the argument represents a time during a positive leap second insertion,
and if a seconds field is formatted,
the integral portion of that format is
\tcode{\exposid{STATICALLY-WIDEN}<charT>("60")}.
\end{itemdescr}

\indexlibrary{\idxcode{formatter}!specializations!\idxcode{chrono::tai_time}}%
\begin{itemdecl}
template<class Duration, class charT>
  struct formatter<chrono::tai_time<Duration>, charT>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
If \tcode{\%Z} is used,
it is replaced with \tcode{\exposid{STATICALLY-WIDEN}<charT>("TAI")}.
If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used,
an offset of \tcode{0min} is formatted.
The date and time formatted are equivalent to
those formatted by a \tcode{sys_time} initialized with
\begin{codeblock}
sys_time<Duration>{tp.time_since_epoch()} -
  (sys_days{1970y/January/1} - sys_days{1958y/January/1})
\end{codeblock}
\end{itemdescr}

\indexlibrary{\idxcode{formatter}!specializations!\idxcode{chrono::gps_time}}%
\begin{itemdecl}
template<class Duration, class charT>
  struct formatter<chrono::gps_time<Duration>, charT>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
If \tcode{\%Z} is used,
it is replaced with \tcode{\exposid{STATICALLY-WIDEN}<charT>("GPS")}.
If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used,
an offset of \tcode{0min} is formatted.
The date and time formatted are equivalent to
those formatted by a \tcode{sys_time} initialized with
\begin{codeblock}
sys_time<Duration>{tp.time_since_epoch()} +
  (sys_days{1980y/January/Sunday[1]} - sys_days{1970y/January/1})
\end{codeblock}
\end{itemdescr}

\indexlibrary{\idxcode{formatter}!specializations!\idxcode{chrono::file_time}}%
\begin{itemdecl}
template<class Duration, class charT>
  struct formatter<chrono::file_time<Duration>, charT>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
If \tcode{\%Z} is used,
it is replaced with \tcode{\exposid{STATICALLY-WIDEN}<charT>("UTC")}.
If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used,
an offset of \tcode{0min} is formatted.
The date and time formatted are equivalent to
those formatted
by a \tcode{sys_time} initialized with \tcode{clock_cast<system_clock>(t)}, or
by a \tcode{utc_time} initialized with \tcode{clock_cast<utc_clock>(t)},
where \tcode{t} is the first argument to \tcode{format}.
\end{itemdescr}

\indexlibrary{\idxcode{formatter}!specializations!\idxcode{chrono::local_time}}%
\begin{itemdecl}
template<class Duration, class charT>
  struct formatter<chrono::local_time<Duration>, charT>;
\end{itemdecl}

\begin{itemdescr}
\pnum
\remarks
If \tcode{\%Z}, \tcode{\%z}, or a modified version of \tcode{\%z} is used,
an exception of type \tcode{format_error} is thrown.
\end{itemdescr}

\indexlibrary{local-time-format-t@\exposid{local-time-format-t}}%
\begin{codeblock}
template<class Duration> struct @\placeholder{local-time-format-t}@ {           // \expos
  local_time<Duration> time;                                    // \expos
  const string* abbrev;                                         // \expos
  const seconds* offset_sec;                                    // \expos
};
\end{codeblock}

\indexlibraryglobal{local_time_format}%
\begin{itemdecl}
template<class Duration>
  @\placeholder{local-time-format-t}@<Duration>
    local_time_format(local_time<Duration> time, const string* abbrev = nullptr,
                      const seconds* offset_sec = nullptr);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{\{time, abbrev, offset_sec\}}.
\end{itemdescr}

\indexlibrary{\idxcode{formatter}!specializations!chrono::local-time-format-t@\tcode{chrono::\exposid{local-time-format-t}}}%
\begin{itemdecl}
template<class Duration, class charT>
  struct formatter<chrono::@\placeholder{local-time-format-t}@<Duration>, charT>;
\end{itemdecl}

\begin{itemdescr}
\pnum
Let \tcode{f} be a \tcode{\exposid{local-time-format-t}<Duration>} object
passed to \tcode{formatter::format}.

\pnum
\remarks
If the \fmtgrammarterm{chrono-specs} is omitted,
the result is equivalent to using \tcode{\%F \%T \%Z} as
the \fmtgrammarterm{chrono-specs}.
If \tcode{\%Z} is used,
it is replaced with \tcode{*f.abbrev}
if \tcode{f.abbrev} is not a null pointer value.
If \tcode{\%Z} is used
and \tcode{f.abbrev} is a null pointer value,
an exception of type \tcode{format_error} is thrown.
If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used,
it is formatted with the value of \tcode{*f.offset_sec}
if \tcode{f.offset_sec} is not a null pointer value.
If \tcode{\%z} (or a modified variant of \tcode{\%z}) is used
and \tcode{f.offset_sec} is a null pointer value,
then an exception of type \tcode{format_error} is thrown.
\end{itemdescr}

\indexlibrary{\idxcode{formatter}!specializations!\idxcode{chrono::zoned_time}}%
\begin{codeblock}
template<class Duration, class TimeZonePtr, class charT>
struct formatter<chrono::zoned_time<Duration, TimeZonePtr>, charT>
    : formatter<chrono::@\placeholder{local-time-format-t}@<common_type_t<Duration, seconds>>, charT> {
  template<class FormatContext>
    typename FormatContext::iterator
      format(const chrono::zoned_time<Duration, TimeZonePtr>& tp, FormatContext& ctx) const;
};
\end{codeblock}

\indexlibrarymember{format}{formatter<chrono::zoned_time>}%
\begin{itemdecl}
template<class FormatContext>
  typename FormatContext::iterator
    format(const chrono::zoned_time<Duration, TimeZonePtr>& tp, FormatContext& ctx) const;
\end{itemdecl}

\begin{itemdescr}
\pnum
\effects
Equivalent to:
\begin{codeblock}
sys_info info = tp.get_info();
return formatter<chrono::@\placeholder{local-time-format-t}@<common_type_t<Duration, seconds>>, charT>::
         format({tp.get_local_time(), &info.abbrev, &info.offset}, ctx);
\end{codeblock}
\end{itemdescr}

\indexlibrary{\idxcode{format}|)}%

\rSec1[time.parse]{Parsing}

\indexlibrary{\idxcode{parse}|(}%

\pnum
Each \tcode{parse} overload specified in this subclause
calls \tcode{from_stream} unqualified,
so as to enable argument-dependent lookup\iref{basic.lookup.argdep}.
In the following paragraphs,
let \tcode{is} denote an object of type \tcode{basic_istream<charT, traits>} and
let \tcode{I} be \tcode{basic_istream<charT, traits>\&},
where \tcode{charT} and \tcode{traits} are template parameters in that context.

\pnum
\recommended
Implementations should make it difficult to accidentally store or use
a manipulator that may contain a dangling reference to a format string,
for example by making the manipulators produced by \tcode{parse} immovable and
preventing stream extraction into an lvalue of such a manipulator type.

\begin{itemdecl}
template<class charT, class Parsable>
  @\unspec@
    parse(const charT* fmt, Parsable& tp);
template<class charT, class traits, class Alloc, class Parsable>
  @\unspec@
    parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let $F$ be \tcode{fmt} for the first overload and
\tcode{fmt.c_str()} for the second overload.
Let \tcode{traits} be \tcode{char_traits<charT>} for the first overload.

\pnum
\constraints
The expression
\begin{codeblock}
from_stream(declval<basic_istream<charT, traits>&>(), @$F$@, tp)
\end{codeblock}
is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}.

\pnum
\returns
A manipulator such that
the expression \tcode{is >> parse(fmt, tp)}
has type \tcode{I},
has value \tcode{is}, and
calls \tcode{from_stream(is, $F$, tp)}.
\end{itemdescr}

\begin{itemdecl}
template<class charT, class traits, class Alloc, class Parsable>
  @\unspec@
    parse(const charT* fmt, Parsable& tp,
          basic_string<charT, traits, Alloc>& abbrev);
template<class charT, class traits, class Alloc, class Parsable>
  @\unspec@
    parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
          basic_string<charT, traits, Alloc>& abbrev);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let $F$ be \tcode{fmt} for the first overload and
\tcode{fmt.c_str()} for the second overload.

\pnum
\constraints
The expression
\begin{codeblock}
from_stream(declval<basic_istream<charT, traits>&>(), @$F$@, tp, addressof(abbrev))
\end{codeblock}
is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}.

\pnum
\returns
A manipulator such that
the expression \tcode{is >> parse(fmt, tp, abbrev)}
has type \tcode{I},
has value \tcode{is}, and
calls \tcode{from_stream(is, $F$, tp, addressof(abbrev))}.
\end{itemdescr}

\begin{itemdecl}
template<class charT, class Parsable>
  @\unspec@
    parse(const charT* fmt, Parsable& tp, minutes& offset);
template<class charT, class traits, class Alloc, class Parsable>
  @\unspec@
    parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
          minutes& offset);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let $F$ be \tcode{fmt} for the first overload and
\tcode{fmt.c_str()} for the second overload.
Let \tcode{traits} be \tcode{char_traits<charT>} and
\tcode{Alloc} be \tcode{allocator<charT>} for the first overload.

\pnum
\constraints
The expression
\begin{codeblock}
from_stream(declval<basic_istream<charT, traits>&>(),
            @$F$@, tp,
            declval<basic_string<charT, traits, Alloc>*>(),
            &offset)
\end{codeblock}
is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}.

\pnum
\returns
A manipulator such that
the expression \tcode{is >> parse(fmt, tp, offset)}
has type \tcode{I},
has value \tcode{is}, and
calls:
\begin{codeblock}
from_stream(is,
            @$F$@, tp,
            static_cast<basic_string<charT, traits, Alloc>*>(nullptr),
            &offset)
\end{codeblock}
\end{itemdescr}

\begin{itemdecl}
template<class charT, class traits, class Alloc, class Parsable>
  @\unspec@
    parse(const charT* fmt, Parsable& tp,
          basic_string<charT, traits, Alloc>& abbrev, minutes& offset);
template<class charT, class traits, class Alloc, class Parsable>
  @\unspec@
    parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
          basic_string<charT, traits, Alloc>& abbrev, minutes& offset);
\end{itemdecl}

\begin{itemdescr}
\pnum
Let $F$ be \tcode{fmt} for the first overload and
\tcode{fmt.c_str()} for the second overload.

\pnum
\constraints
The expression
\begin{codeblock}
from_stream(declval<basic_istream<charT, traits>&>(),
            @$F$@, tp, addressof(abbrev), &offset)
\end{codeblock}
is well-formed when treated as an unevaluated operand\iref{term.unevaluated.operand}.

\pnum
\returns
A manipulator such that
the expression \tcode{is >> parse(fmt, tp, abbrev, offset)}
has type \tcode{I},
has value \tcode{is}, and
calls \tcode{from_stream(is, $F$, tp, addressof(abbrev), \&offset)}.
\end{itemdescr}

\pnum
All \tcode{from_stream} overloads behave as unformatted input functions,
except that they have an unspecified effect
on the value returned by subsequent calls to \tcode{basic_istream<>::gcount()}.
Each overload takes a format string containing ordinary characters
and flags which have special meaning.
Each flag begins with a \tcode{\%}.
Some flags can be modified by \tcode{E} or \tcode{O}.
During parsing each flag interprets characters as parts of date and time types
according to~\tref{time.parse.spec}.
Some flags can be modified by a width parameter
given as a positive decimal integer called out as \tcode{\placeholder{N}} below
which governs how many characters are parsed from the stream in interpreting the flag.
All characters in the format string that are not represented in~\tref{time.parse.spec},
except for whitespace, are parsed unchanged from the stream.
A whitespace character matches zero or more whitespace characters in the input stream.

\pnum
If the type being parsed cannot represent
the information that the format flag refers to,
\tcode{is.setstate(ios_base::failbit)} is called.
\begin{example}
A \tcode{duration} cannot represent a \tcode{weekday}.
\end{example}
However, if a flag refers to a ``time of day''
(e.g., \tcode{\%H}, \tcode{\%I}, \tcode{\%p}, etc.),
then a specialization of \tcode{duration} is parsed as
the time of day elapsed since midnight.

\pnum
If the \tcode{from_stream} overload fails to parse
everything specified by the format string,
or if insufficient information is parsed to specify a complete
duration, time point, or calendrical data structure,
\tcode{setstate(ios_base::failbit)}
is called on the \tcode{basic_istream}.

\begin{LongTable}{Meaning of \tcode{parse} flags}{time.parse.spec}{lx{.8\hsize}}
\\ \topline
\lhdr{Flag} & \rhdr{Parsed value} \\ \capsep
\endfirsthead
\continuedcaption\\
\hline
\lhdr{Flag} & \rhdr{Parsed value} \\ \capsep
\endhead
\tcode{\%a} &
The locale's full or abbreviated case-insensitive weekday name.
\\ \rowsep
\tcode{\%A} &
Equivalent to \tcode{\%a}.
\\ \rowsep
\tcode{\%b} &
The locale's full or abbreviated case-insensitive month name.
\\ \rowsep
\tcode{\%B} &
Equivalent to \tcode{\%b}.
\\ \rowsep
\tcode{\%c} &
The locale's date and time representation.
The modified command \tcode{\%Ec} interprets
the locale's alternate date and time representation.
\\ \rowsep
\tcode{\%C} &
The century as a decimal number.
The modified command \tcode{\%\placeholder{N}C} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified command \tcode{\%EC} interprets
the locale's alternative representation of the century.
\\ \rowsep
\tcode{\%d} &
The day of the month as a decimal number.
The modified command \tcode{\%\placeholder{N}d} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified command \tcode{\%Od} interprets
the locale's alternative representation of the day of the month.
\\ \rowsep
\tcode{\%D} &
Equivalent to \tcode{\%m/\%d/\%y}.
\\ \rowsep
\tcode{\%e} &
Equivalent to \tcode{\%d} and can be modified like \tcode{\%d}.
\\ \rowsep
\tcode{\%F} &
Equivalent to \tcode{\%Y-\%m-\%d}.
If modified with a width \tcode{\placeholder{N}},
the width is applied to only \tcode{\%Y}.
\\ \rowsep
\tcode{\%g} &
The last two decimal digits of the calendar year,
as specified in ISO 8601-1:2019 for the week calendar.
The modified command \tcode{\%\placeholder{N}g} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
\\ \rowsep
\tcode{\%G} &
The calendar year as a decimal number,
as specified in ISO 8601-1:2019 for the week calendar.
The modified command \tcode{\%\placeholder{N}G} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 4.
Leading zeroes are permitted but not required.
\\ \rowsep
\tcode{\%h} &
Equivalent to \tcode{\%b}.
\\ \rowsep
\tcode{\%H} &
The hour (24-hour clock) as a decimal number.
The modified command \tcode{\%\placeholder{N}H} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified command \tcode{\%OH} interprets
the locale's alternative representation.
\\ \rowsep
\tcode{\%I} &
The hour (12-hour clock) as a decimal number.
The modified command \tcode{\%\placeholder{N}I} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified command \tcode{\%OI}
interprets the locale's alternative representation.
\\ \rowsep
\tcode{\%j} &
If the type being parsed is a specialization of \tcode{duration},
a decimal number of \tcode{days}.
Otherwise,
the day of the year as a decimal number.
January 1 is \tcode{1}.
In either case,
the modified command \tcode{\%\placeholder{N}j} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 3.
Leading zeroes are permitted but not required.
\\ \rowsep
\tcode{\%m} &
The month as a decimal number.
January is \tcode{1}.
The modified command \tcode{\%\placeholder{N}m} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified command \tcode{\%Om} interprets
the locale's alternative representation.
\\ \rowsep
\tcode{\%M} &
The minutes as a decimal number.
The modified command \tcode{\%\placeholder{N}M} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified command \tcode{\%OM} interprets
the locale's alternative representation.
\\ \rowsep
\tcode{\%n} &
Matches one whitespace character.
\begin{tailnote}
\tcode{\%n}, \tcode{\%t}, and a space
can be combined to match a wide range of whitespace patterns.
For example,
\tcode{"\%n "} matches one or more whitespace characters, and
\tcode{"\%n\%t\%t"} matches one to three whitespace characters.
\end{tailnote}
\\ \rowsep
\tcode{\%p} &
The locale's equivalent of the AM/PM designations associated with a 12-hour clock.
\\ \rowsep
\tcode{\%r} &
The locale's 12-hour clock time.
\\ \rowsep
\tcode{\%R} &
Equivalent to \tcode{\%H:\%M}.
\\ \rowsep
\tcode{\%S} &
The seconds as a decimal number.
The modified command \tcode{\%\placeholder{N}S} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified,
the default is 2 if the input time has a precision convertible to seconds.
Otherwise the default width is determined by
the decimal precision of the input
and the field is interpreted as a \tcode{long double} in a fixed format.
If encountered, the locale determines the decimal point character.
Leading zeroes are permitted but not required.
The modified command \tcode{\%OS} interprets
the locale's alternative representation.
\\ \rowsep
\tcode{\%t} &
Matches zero or one whitespace characters.
\\ \rowsep
\tcode{\%T} &
Equivalent to \tcode{\%H:\%M:\%S}.
\\ \rowsep
\tcode{\%u} &
The calendar day of week as a decimal number (\tcode{1}-\tcode{7}),
as specified in ISO 8601-1:2019,
where Monday is \tcode{1}.
The modified command \tcode{\%\placeholder{N}u} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is \tcode{1}.
Leading zeroes are permitted but not required.
\\ \rowsep
\tcode{\%U} &
The week number of the year as a decimal number.
The first Sunday of the year is the first day of week \tcode{01}.
Days of the same year prior to that are in week \tcode{00}.
The modified command \tcode{\%\placeholder{N}U} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified command \tcode{\%OU} interprets
the locale's alternative representation.
\\ \rowsep
\tcode{\%V} &
The calendar week of year as a decimal number,
as specified in ISO 8601-1:2019 for the week calendar.
The modified command \tcode{\%\placeholder{N}V} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
\\ \rowsep
\tcode{\%w} &
The weekday as a decimal number (\tcode{0}-\tcode{6}), where Sunday is \tcode{0}.
The modified command \tcode{\%\placeholder{N}w} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is \tcode{1}.
Leading zeroes are permitted but not required.
The modified command \tcode{\%Ow} interprets
the locale's alternative representation.
\\ \rowsep
\tcode{\%W} &
The week number of the year as a decimal number.
The first Monday of the year is the first day of week \tcode{01}.
Days of the same year prior to that are in week \tcode{00}.
The modified command \tcode{\%\placeholder{N}W} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified command \tcode{\%OW} interprets
the locale's alternative representation.
\\ \rowsep
\tcode{\%x} &
The locale's date representation.
The modified command \tcode{\%Ex} interprets the locale's alternate date representation.
\\ \rowsep
\tcode{\%X} &
The locale's time representation.
The modified command \tcode{\%EX} interprets the locale's alternate time representation.
\\ \rowsep
\tcode{\%y} &
The last two decimal digits of the year.
If the century is not otherwise specified
(e.g.,  with \tcode{\%C}),
values in the range \crange{69}{99}
are presumed to refer to the years 1969 to 1999,
and values in the range \crange{00}{68}
are presumed to refer to the years 2000 to 2068.
The modified command \tcode{\%\placeholder{N}y} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 2.
Leading zeroes are permitted but not required.
The modified commands \tcode{\%Ey} and \tcode{\%Oy} interpret
the locale's alternative representation.
\\ \rowsep
\tcode{\%Y} &
The year as a decimal number.
The modified command \tcode{\%\placeholder{N}Y} specifies
the maximum number of characters to read.
If \tcode{\placeholder{N}} is not specified, the default is 4.
Leading zeroes are permitted but not required.
The modified command \tcode{\%EY} interprets
the locale's alternative representation.
\\ \rowsep
\tcode{\%z} &
The offset from UTC in the format \tcode{[+|-]hh[mm]}.
For example \tcode{-0430} refers to 4 hours 30 minutes behind UTC,
and \tcode{04} refers to 4 hours ahead of UTC\@.
The modified commands \tcode{\%Ez} and \tcode{\%Oz}
parse a \tcode{:} between the hours and minutes
and render leading zeroes on the hour field optional:
\tcode{[+|-]h[h][:mm]}.
For example \tcode{-04:30} refers to 4 hours 30 minutes behind UTC,
and \tcode{4} refers to 4 hours ahead of UTC.
\\ \rowsep
\tcode{\%Z} &
The time zone abbreviation or name.
A single word is parsed.
This word can only contain characters
from the basic character set\iref{lex.charset}
that are alphanumeric, or one of
\tcode{'_'}, \tcode{'/'}, \tcode{'-'}, or \tcode{'+'}.
\\ \rowsep
\tcode{\%\%} &
A \tcode{\%} character is extracted.
\\
\end{LongTable}

\indexlibrary{\idxcode{parse}|)}

\rSec1[time.hash]{Hash support}

\indexlibrarymember{hash}{duration}%
\begin{itemdecl}
template<class Rep, class Period> struct hash<chrono::duration<Rep, Period>>;
\end{itemdecl}

\begin{itemdescr}
\pnum
The specialization \tcode{hash<chrono::duration<Rep, Period>>} is enabled\iref{unord.hash}
if and only if \\% newline to fix overfull hbox
\tcode{hash<Rep>} is enabled.
The member functions are not guaranteed to be \keyword{noexcept}.
\end{itemdescr}

\indexlibrarymember{hash}{time_point}%
\begin{itemdecl}
template<class Clock, class Duration> struct hash<chrono::time_point<Clock, Duration>>;
\end{itemdecl}

\begin{itemdescr}
\pnum
The specialization \tcode{hash<chrono::time_point<Clock, Duration>>} is enabled\iref{unord.hash}
if and only if \tcode{hash<Duration>} is enabled.
The member functions are not guaranteed to be \keyword{noexcept}.
\end{itemdescr}

\indexlibrarymember{hash}{day}%
\indexlibrarymember{hash}{month}%
\indexlibrarymember{hash}{year}%
\indexlibrarymember{hash}{weekday}%
\indexlibrarymember{hash}{weekday_indexed}%
\indexlibrarymember{hash}{weekday_last}%
\indexlibrarymember{hash}{month_day}%
\indexlibrarymember{hash}{month_day_last}%
\indexlibrarymember{hash}{month_weekday}%
\indexlibrarymember{hash}{month_weekday_last}%
\indexlibrarymember{hash}{year_month}%
\indexlibrarymember{hash}{year_month_day}%
\indexlibrarymember{hash}{year_month_day_last}%
\indexlibrarymember{hash}{year_month_weekday}%
\indexlibrarymember{hash}{year_month_weekday_last}%
\begin{itemdecl}
template<> struct hash<chrono::day>;
template<> struct hash<chrono::month>;
template<> struct hash<chrono::year>;
template<> struct hash<chrono::weekday>;
template<> struct hash<chrono::weekday_indexed>;
template<> struct hash<chrono::weekday_last>;
template<> struct hash<chrono::month_day>;
template<> struct hash<chrono::month_day_last>;
template<> struct hash<chrono::month_weekday>;
template<> struct hash<chrono::month_weekday_last>;
template<> struct hash<chrono::year_month>;
template<> struct hash<chrono::year_month_day>;
template<> struct hash<chrono::year_month_day_last>;
template<> struct hash<chrono::year_month_weekday>;
template<> struct hash<chrono::year_month_weekday_last>;
\end{itemdecl}

\begin{itemdescr}
\pnum
The specializations are enabled\iref{unord.hash}.
\begin{note}
All the \tcode{hash<Key>} specializations listed above meet the
\oldconcept{Hash} requirements, even when called on objects \tcode{k}
of type \tcode{Key} such that \tcode{k.ok()} is \tcode{false}.
\end{note}
\end{itemdescr}

\indexlibrarymember{hash}{zoned_time}%
\begin{itemdecl}
template<class Duration, class TimeZonePtr>
  struct hash<chrono::zoned_time<Duration, TimeZonePtr>>;
\end{itemdecl}

\begin{itemdescr}
\pnum
The specialization \tcode{hash<chrono::zoned_time<Duration, TimeZonePtr>>}
is enabled\iref{unord.hash}
if and only if \tcode{hash<Duration>} is enabled and
\tcode{hash<TimeZonePtr>} is enabled.
The member functions are not guaranteed to be \keyword{noexcept}.
\end{itemdescr}

\indexlibrarymember{hash}{leap_second}%
\begin{itemdecl}
template<> struct hash<chrono::leap_second>;
\end{itemdecl}

\begin{itemdescr}
\pnum
The specialization is enabled\iref{unord.hash}.
\end{itemdescr}

\rSec1[ctime.syn]{Header \tcode{<ctime>} synopsis}

\indexheader{ctime}%
\indexlibraryglobal{clock_t}%
\indexlibraryglobal{clock}%
\indexlibraryglobal{difftime}%
\indexlibraryglobal{gmtime}%
\indexlibraryglobal{gmtime_r}%
\indexlibraryglobal{localtime}%
\indexlibraryglobal{localtime_r}%
\indexlibraryglobal{mktime}%
\indexlibraryglobal{size_t}%
\indexlibraryglobal{strftime}%
\indexlibraryglobal{time_t}%
\indexlibraryglobal{timespec_get}%
\indexlibraryglobal{timespec_getres}%
\indexlibraryglobal{timespec}%
\indexlibraryglobal{time}%
\indexlibraryglobal{timegm}%
\indexlibraryglobal{tm}%
\begin{codeblock}
#define __STDC_VERSION_TIME_H__ 202311L

#define @\libmacro{NULL}@ @\textit{see \ref{support.types.nullptr}}@
#define @\libmacro{CLOCKS_PER_SEC}@ @\seebelow@
#define @\libmacro{TIME_UTC}@ @\seebelow@
#define @\libmacro{TIME_MONOTONIC}@ @\seebelow@     // optional
#define @\libmacro{TIME_ACTIVE}@ @\seebelow@        // optional
#define @\libmacro{TIME_THREAD_ACTIVE}@ @\seebelow@ // optional

namespace std {
  using size_t = @\textit{see \ref{support.types.layout}}@;
  using clock_t = @\seebelow@;
  using time_t = @\seebelow@;

  struct timespec;
  struct tm;

  clock_t clock();
  double difftime(time_t time1, time_t time0);
  time_t mktime(tm* timeptr);
  time_t timegm(tm* timeptr);
  time_t time(time_t* timer);
  int timespec_get(timespec* ts, int base);
  int timespec_getres(timespec* ts, int base);
  tm* gmtime(const time_t* timer);
  tm* gmtime_r(const time_t* timer, tm* buf);
  tm* localtime(const time_t* timer);
  tm* localtime_r(const time_t* timer, tm* buf);
  size_t strftime(char* s, size_t maxsize, const char* format, const tm* timeptr);
}
\end{codeblock}

\pnum
The contents of the header \libheader{ctime} are the same as the C standard library header \libheader{time.h}.
\begin{footnote}
\tcode{strftime} supports the C conversion specifiers
\tcode{C}, \tcode{D}, \tcode{e}, \tcode{F}, \tcode{g}, \tcode{G}, \tcode{h},
\tcode{r}, \tcode{R}, \tcode{t}, \tcode{T}, \tcode{u}, \tcode{V}, and
\tcode{z}, and the modifiers \tcode{E} and \tcode{O}.
\end{footnote}

\pnum
The functions \tcode{gmtime} and
\tcode{localtime} are not required to avoid data
races\iref{res.on.data.races}.

\xrefc{7.29}
