std::chrono...::operator-=(3)

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

πŸ’… std::chrono::year_month_day::operator+= / operator-= πŸ’…

okay so bestie, welcome to the C++ Standard Libary page for the year_month_day date-math operators. This is the one tagged std::chrono...::operator-=(3) down in the footer, and it's lowkey iconic: four overloads, all constexpr, all noexcept, all since C++20, all here to add or subtract std::chrono::years / std::chrono::months from a year_month_day. Dates are about to get main character energy. πŸ—“οΈβœ¨


🌸 NAME 🌸

The original page lists the name twice, so we're serving both, no cap:

  • std::chrono::year_month_day::operator+=,std::chrono::year_month_day::operator-=
  • std::chrono::year_month_day::operator+=,std::chrono::year_month_day::operator-=

There's also a lone - separator in the original between the repeats β€” a tiny formatting moment, but we're keeping the receipts. πŸ’€


✨ Synopsis ✨

Here's the overload squad, copied exactly. Every single one returns std::chrono::year_month_day&, is constexpr, and is noexcept. Also every single one is since C++20, because we're fancy like that. πŸ’…

          constexpr std::chrono::year_month_day&                          (1)
       (since C++20)
              operator+=( const std::chrono::years& dy ) const noexcept;
          constexpr std::chrono::year_month_day&                          (2)
       (since C++20)
              operator+=( const std::chrono::months& dm ) const noexcept;
          constexpr std::chrono::year_month_day&                          (3)
       (since C++20)
              operator-=( const std::chrono::years& dy ) const noexcept;
          constexpr std::chrono::year_month_day&                          (4)
       (since C++20)
              operator-=( const std::chrono::months& dm ) const noexcept;

Okay so what do they actually do? They modify the time point *this represents by the duration dy or dm. That's the whole assignment, fr fr.

  1. Overload (1) is equivalent to *this = *this + dy;.
  2. Overload (2) is equivalent to *this = *this + dm;.
  3. Overload (3) is equivalent to *this = *this - dy;.
  4. Overload (4) is equivalent to *this = *this - dm;.

For durations that are convertible to both std::chrono::years and std::chrono::months, the years overloads (1,3) are preferred if the call would otherwise be ambiguous. Important little tie-breaker, iykyk. 🫢


πŸ§ͺ Example πŸ§ͺ

The original says // Run this code, so obviously we're running it. Here's the code, copied exactly and looking all cute:

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

        int main()
        {
            constexpr auto monthsInYear{12};
            auto ymd{std::chrono::day(1)/std::chrono::July/2020};
            std::cout << "#1 " << ymd << '\n';

            ymd -= std::chrono::years(10);
            std::cout << "#2 " << ymd << '\n';
            assert(ymd.month() == std::chrono::July);
            assert(ymd.year() == std::chrono::year(2010));

            ymd += std::chrono::months(10 * monthsInYear + 11);
            std::cout << "#3 " << ymd << '\n';
            assert(ymd.month() == std::chrono::month(6));
            assert(ymd.year() == std::chrono::year(2021));

            // Handling the ymd += months "overflow" case.
            ymd = std::chrono::May/31/2021; // ok
            std::cout << "#4 " << ymd << '\n';
            assert(ymd.ok());

            ymd += std::chrono::months{1}; // bad date: June has only 30 days
            std::cout << "#5 " << ymd << '\n';
            assert(not ymd.ok());
            assert(ymd == std::chrono::June/31/2021);

            // Snap to the last day of the month, June 30:
            const auto ymd1 = ymd.year()/ymd.month()/std::chrono::last;
            std::cout << "#6 " << ymd1 << '\n';
            assert(ymd1.ok());
            assert(ymd1 == std::chrono::June/30/2021);

            // Overflow into the next month, July 1 (via converting to/from
       sys_days):
            const std::chrono::year_month_day ymd2 =
       std::chrono::sys_days{ymd};
            std::cout << "#7 " << ymd2 << '\n';
            assert(ymd2.ok());
            assert(ymd2 == std::chrono::July/1/2021);
        }

🌈 Output 🌈

And the output is exactly this, not me making it up:

#1 2020-07-01
#2 2010-07-01
#3 2021-06-01
#4 2021-05-31
#5 2021-06-31 is not a valid date
#6 2021/Jun/last
#7 2021-07-01

πŸ‘€ See also πŸ‘€

  • operator+ adds or subtracts a year_month_day and some number of years or months
  • operator- (function)
  • (C++20)

That last (C++20) is its own line in the original, so it gets its own line here too. Periodt. πŸ’…


k bye bestie πŸ’– β€” source: http://cppreference.com, version/date: 2024.06.10, manual page: std::chrono...::operator-=(3).

πŸ“¦ where this page comes from