27 Time library [time]

27.8 The civil calendar [time.cal]

27.8.14 Class year_­month_­day [time.cal.ymd]

27.8.14.1 Overview [time.cal.ymd.overview]

namespace std::chrono {
  class year_month_day {
    chrono::year  y_;           // exposition only
    chrono::month m_;           // exposition only
    chrono::day   d_;           // exposition only

  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;
  };
}
year_­month_­day represents a specific year, month, and day.
year_­month_­day is a field-based time point with a resolution of days.
Note
:
year_­month_­day supports years- and months-oriented arithmetic, but not days-oriented arithmetic.
For the latter, there is a conversion to sys_­days, which efficiently supports days-oriented arithmetic.
— end note
 ]
year_­month_­day meets the Cpp17EqualityComparable (Table 25) and Cpp17LessThanComparable (Table 26) requirements.
year_­month_­day is a trivially copyable and standard-layout class type.

27.8.14.2 Member functions [time.cal.ymd.members]

constexpr year_month_day(const chrono::year& y, const chrono::month& m, const chrono::day& d) noexcept;
Effects: Initializes y_­ with y, m_­ with m, and d_­ with d.
constexpr year_month_day(const year_month_day_last& ymdl) noexcept;
Effects: Initializes y_­ with ymdl.year(), m_­ with ymdl.month(), and d_­ with ymdl.day().
Note
:
This conversion from year_­month_­day_­last to year_­month_­day may be more efficient than converting a year_­month_­day_­last to a sys_­days, and then converting that sys_­days to a year_­month_­day.
— end note
 ]
constexpr year_month_day(const sys_days& dp) noexcept;
Effects: Constructs an object of type year_­month_­day that corresponds to the date represented by dp.
Remarks: For any value ymd of type year_­month_­day for which ymd.ok() is true, ymd == year_­month_­day{sys_­days{ymd}} is true.
constexpr explicit year_month_day(const local_days& dp) noexcept;
Effects: Equivalent to constructing with sys_­days{dp.time_­since_­epoch()}.
constexpr year_month_day& operator+=(const months& m) noexcept;
Constraints: If the argument supplied by the caller for the months parameter is convertible to years, its implicit conversion sequence to years is worse than its implicit conversion sequence to months ([over.ics.rank]).
Effects: *this = *this + m.
Returns: *this.
constexpr year_month_day& operator-=(const months& m) noexcept;
Constraints: If the argument supplied by the caller for the months parameter is convertible to years, its implicit conversion sequence to years is worse than its implicit conversion sequence to months ([over.ics.rank]).
Effects: *this = *this - m.
Returns: *this.
constexpr year_month_day& year_month_day::operator+=(const years& y) noexcept;
Effects: *this = *this + y.
Returns: *this.
constexpr year_month_day& year_month_day::operator-=(const years& y) noexcept;
Effects: *this = *this - y.
Returns: *this.
constexpr chrono::year year() const noexcept;
Returns: y_­.
constexpr chrono::month month() const noexcept;
Returns: m_­.
constexpr chrono::day day() const noexcept;
Returns: d_­.
constexpr operator sys_days() const noexcept;
Returns: If ok(), returns a sys_­days holding a count of days from the sys_­days epoch to *this (a negative value if *this represents a date prior to the sys_­days epoch).
Otherwise, if y_­.ok() && m_­.ok() is true, returns sys_­days{y_­/m_­/1d} + (d_­ - 1d).
Otherwise the value returned is unspecified.
Remarks: A sys_­days in the range [days{-12687428}, days{11248737}] which is converted to a year_­month_­day has the same value when converted back to a sys_­days.
Example
:
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 example
 ]
constexpr explicit operator local_days() const noexcept;
Returns: local_­days{sys_­days{*this}.time_­since_­epoch()}.
constexpr bool ok() const noexcept;
Returns: If y_­.ok() is true, and m_­.ok() is true, and d_­ is in the range [1d, (y_­/m_­/last).day()], then returns true; otherwise returns false.

27.8.14.3 Non-member functions [time.cal.ymd.nonmembers]

constexpr bool operator==(const year_month_day& x, const year_month_day& y) noexcept;
Returns: x.year() == y.year() && x.month() == y.month() && x.day() == y.day().
constexpr strong_ordering operator<=>(const year_month_day& x, const year_month_day& y) noexcept;
Effects: Equivalent to:
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();
constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
Constraints: If the argument supplied by the caller for the months parameter is convertible to years, its implicit conversion sequence to years is worse than its implicit conversion sequence to months ([over.ics.rank]).
Returns: (ymd.year() / ymd.month() + dm) / ymd.day().
Note
:
If ymd.day() is in the range [1d, 28d], ok() will return true for the resultant year_­month_­day.
— end note
 ]
constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
Constraints: If the argument supplied by the caller for the months parameter is convertible to years, its implicit conversion sequence to years is worse than its implicit conversion sequence to months ([over.ics.rank]).
Returns: ymd + dm.
constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
Constraints: If the argument supplied by the caller for the months parameter is convertible to years, its implicit conversion sequence to years is worse than its implicit conversion sequence to months ([over.ics.rank]).
Returns: ymd + (-dm).
constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
Returns: (ymd.year() + dy) / ymd.month() / ymd.day().
Note
:
If ymd.month() is February and ymd.day() is not in the range [1d, 28d], ok() may return false for the resultant year_­month_­day.
— end note
 ]
constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
Returns: ymd + dy.
constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
Returns: ymd + (-dy).
template<class charT, class traits> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const year_month_day& ymd);
Effects: Equivalent to:
return os << (ymd.ok() ?
  format(STATICALLY-WIDEN<charT>("{:%F}"), ymd) :
  format(STATICALLY-WIDEN<charT>("{:%F} is not a valid date"), 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);
Effects: Attempts to parse the input stream is into the year_­month_­day ymd using the format flags given in the NTCTS fmt as specified in [time.parse].
If the parse fails to decode a valid year_­month_­day, is.setstate(ios_­base​::​failbit) is called and ymd is not modified.
If %Z is used and successfully parsed, that value will be assigned to *abbrev if abbrev is non-null.
If %z (or a modified variant) is used and successfully parsed, that value will be assigned to *offset if offset is non-null.
Returns: is.