std::chrono::year_month_day în C++

O dată calendaristică (an, lună, zi) cu validare, ziua săptămânii și calcule cu luni și ani.

Sintaxă
#include <chrono>
std::chrono::year_month_day d{std::chrono::year{2024}, std::chrono::month{3}, std::chrono::day{15}};
auto d2 = 2024y / std::chrono::March / 15d;
bool ok() const noexcept;

Ce face std::chrono::year_month_day

year_month_day ține o dată din calendar. Se construiește cu operatorul /: 2024y / March / 15d sau 2024y / 3 / 15. year(), month(), day() returnează componentele, iar ok() spune dacă data există (31 februarie nu există).

Transformată în sys_days, data devine un moment, deci poți calcula diferențe în zile sau ziua săptămânii (weekday). Adunarea de luni sau ani (months{1}, years{1}) se face direct pe year_month_day. year_month_day_last (2024y / February / last) dă ultima zi a lunii.

Cu std::println, o dată se afișează ca AAAA-LL-ZZ; cu specificatori ({:%d.%m.%Y}) o formatezi cum vrei.

Ce returnează

Un obiect dată. ok() returnează bool.

Exemple

Exemplul 1: Construire, validare, ziua săptămânii

#include <chrono>
#include <print>

int main() {
    using namespace std::chrono;

    year_month_day ziua = 2024y / December / 1d;
    std::println("{} -> {:%d.%m.%Y}", ziua, sys_days{ziua});
    std::println("an {}, luna {}, ziua {}",
                 static_cast<int>(ziua.year()), static_cast<unsigned>(ziua.month()),
                 static_cast<unsigned>(ziua.day()));
    std::println("ziua săptămânii (0 = duminică): {}", weekday{sys_days{ziua}}.c_encoding());

    year_month_day gresita = 2023y / February / 29d;
    std::println("29 februarie 2023 există: {}", gresita.ok());
}

Rezultat

2024-12-01 -> 01.12.2024
an 2024, luna 12, ziua 1
ziua săptămânii (0 = duminică): 0
29 februarie 2023 există: false

Exemplul 2: Zile până la un eveniment și ultima zi din lună

#include <chrono>
#include <print>

int main() {
    using namespace std::chrono;

    sys_days azi = 2025y / March / 10d;
    sys_days vacanta = 2025y / June / 21d;
    std::println("Zile până la vacanță: {}", (vacanta - azi).count());

    for (int an : {2024, 2025}) {
        year_month_day_last ultima = year{an} / February / last;
        std::println("Februarie {} are {} zile", an, static_cast<unsigned>(ultima.day()));
    }
}

Rezultat

Zile până la vacanță: 103
Februarie 2024 are 29 zile
Februarie 2025 are 28 zile

Exemplul 3: Adăugarea de luni

Adunarea de luni păstrează ziua; dacă data rezultată nu există (31 aprilie), ok() devine false și trebuie tratată separat.

#include <chrono>
#include <print>

int main() {
    using namespace std::chrono;

    year_month_day scadenta = 2025y / January / 15d;
    for (int i = 0; i < 3; ++i) {
        std::println("Rata {}: {}", i + 1, scadenta);
        scadenta += months{1};
    }

    year_month_day d = 2025y / March / 31d;
    d += months{1};
    std::println("31 martie + o lună valid: {}", d.ok());
}

Rezultat

Rata 1: 2025-01-15
Rata 2: 2025-02-15
Rata 3: 2025-03-15
31 martie + o lună valid: false

Greșeli frecvente

  • Scrii 2024y / 15 / 3 crezând că este 15 martie. Ordinea este an / lună / zi; luna 15 nu există și ok() dă false. Pentru ordinea zi / lună / an folosește 15d / March / 2024y.
  • Afișezi componentele direct cu {} și primești text neașteptat. month se afișează ca nume (Dec); pentru număr, convertește cu static_cast<unsigned>.

Comenzi înrudite

  • std::chrono::time_point: Un moment în timp măsurat după un anumit ceas. Diferența a două momente este o durată.
  • std::chrono::system_clock: Ceasul sistemului: data și ora reale (UTC), care pot fi transformate în dată calendaristică.
  • std::chrono::duration: O durată de timp cu unitate de măsură: secunde, milisecunde, minute, ore. Conversiile sunt automate și sigure.