std::chrono...th_weekday)(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

✨ NAME ✨

Hey bestie, welcome to the std::chrono...th_weekday)(3) page from the C++ Standard Libary man-page collection πŸ’–. This one is all about std::chrono::year_month_weekday math, and the name is, and I quote:

std::chrono::operator+,std::chrono::operator-(std::chrono::year_month_weekday)

And yeah, the page echoes the exact same name right after a dash, because man pages love a dramatic repeat πŸ’…. It’s giving β€œtwo operators, one extremely long type name,” and we’re gonna make it make sense.


🌸 Synopsis 🌸

Every overload here has (since C++20) energy ✨. They’re all constexpr and noexcept, so the compiler is literally invited to vibe at compile time and promised no exceptions.

(1) (since C++20)

constexpr std::chrono::year_month_weekday
    operator+( const std::chrono::year_month_weekday& ymwd,
               const std::chrono::months& dm ) noexcept;

(2) (since C++20)

constexpr std::chrono::year_month_weekday
    operator+( const std::chrono::months& dm,
               const std::chrono::year_month_weekday& ymwd ) noexcept;

(3) (since C++20)

constexpr std::chrono::year_month_weekday
    operator+( const std::chrono::year_month_weekday& ymwd,
               const std::chrono::years& dy ) noexcept;

(4) (since C++20)

constexpr std::chrono::year_month_weekday
    operator+( const std::chrono::years& dy,
               const std::chrono::year_month_weekday& ymwd ) noexcept;

(5) (since C++20)

constexpr std::chrono::year_month_weekday
    operator-( const std::chrono::year_month_weekday& ymwd,
               const std::chrono::months& dm ) noexcept;

(6) (since C++20)

constexpr std::chrono::year_month_weekday
    operator-( const std::chrono::year_month_weekday& ymwd,
               const std::chrono::years& dy ) noexcept;

Okay so what do they actually do? Here’s the tea πŸ«–:

  • 1,2) β€” Adds dm.count() months to the date represented by ymwd. The result has the same year() and month() as std::chrono::year_month(ymwd.year(), ymwd.month()) + dm, and the same weekday() and index() as ymwd. The weekday vibe stays untouched, periodt.
  • 3,4) β€” Adds dy.count() years to the date represented by ymwd. The result is equivalent to std::chrono::year_month_weekday(ymwd.year() + dy, ymwd.month(), ymwd.weekday_indexed()).
  • 5) β€” Subtracts dm.count() months from the date represented by ymwd. Equivalent to ymwd + -dm.
  • 6) β€” Subtracts dy.count() years from the date represented by ymwd. Equivalent to ymwd + -dy.

And a lil’ extra rule, no cap: for durations that are convertible to both std::chrono::years and std::chrono::months, the years overloads (3,4,6) are preferred if the call would otherwise be ambiguous πŸ‘‘


πŸ¦‹ Notes πŸ¦‹

🚨 Okay bestie, this part matters: even if ymwd.ok() is true, the resulting year_month_weekday may not represent a valid date if ymwd.index() is 5. So don’t let the ok() pass fool you into thinking it’s automatically a valid date β€” that index() of 5 is the plot twist 😭.

πŸ“ Example πŸ“

Run this code, bestie:

#include <cassert>
#include <chrono>
#include <iostream>

int main()
{
    auto ymwdi{1/std::chrono::Wednesday[1]/2021};
    std::cout << ymwdi << '\n';

    ymwdi = std::chrono::years(5) + ymwdi;
    // First Wednesday in January, 2026
    std::cout << ymwdi << '\n';
    assert(static_cast<std::chrono::year_month_day>(ymwdi) ==
           std::chrono::January/7/2026);

    ymwdi = ymwdi - std::chrono::months(6);
    // First Wednesday in July, 2025
    std::cout << ymwdi << '\n';
    assert(static_cast<std::chrono::year_month_day>(ymwdi) ==
           std::chrono::July/2/2025);
}

Output: πŸ’»

2021/Jan/Wed[1]
2026/Jan/Wed[1]
2025/Jul/Wed[1]

Source/version/date cuteness, exactly as the page signs off: http://cppreference.com, 2024.06.10, and the page label std::chrono...th_weekday)(3). Mwah πŸ’…πŸŽ€

πŸ“¦ where this page comes from