Path: blob/main/contrib/llvm-project/libcxx/include/__chrono/year_month_day.h
35262 views
// -*- C++ -*-1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//89#ifndef _LIBCPP___CHRONO_YEAR_MONTH_DAY_H10#define _LIBCPP___CHRONO_YEAR_MONTH_DAY_H1112#include <__chrono/calendar.h>13#include <__chrono/day.h>14#include <__chrono/duration.h>15#include <__chrono/month.h>16#include <__chrono/monthday.h>17#include <__chrono/system_clock.h>18#include <__chrono/time_point.h>19#include <__chrono/year.h>20#include <__chrono/year_month.h>21#include <__config>22#include <compare>23#include <limits>2425#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)26# pragma GCC system_header27#endif2829#if _LIBCPP_STD_VER >= 203031_LIBCPP_BEGIN_NAMESPACE_STD3233namespace chrono {3435class year_month_day_last;3637class year_month_day {38private:39chrono::year __y_;40chrono::month __m_;41chrono::day __d_;4243public:44year_month_day() = default;45_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(46const chrono::year& __yval, const chrono::month& __mval, const chrono::day& __dval) noexcept47: __y_{__yval}, __m_{__mval}, __d_{__dval} {}48_LIBCPP_HIDE_FROM_ABI constexpr year_month_day(const year_month_day_last& __ymdl) noexcept;49_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day(const sys_days& __sysd) noexcept50: year_month_day(__from_days(__sysd.time_since_epoch())) {}51_LIBCPP_HIDE_FROM_ABI inline explicit constexpr year_month_day(const local_days& __locd) noexcept52: year_month_day(__from_days(__locd.time_since_epoch())) {}5354_LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const months& __dm) noexcept;55_LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const months& __dm) noexcept;56_LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator+=(const years& __dy) noexcept;57_LIBCPP_HIDE_FROM_ABI constexpr year_month_day& operator-=(const years& __dy) noexcept;5859_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; }60_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; }61_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day day() const noexcept { return __d_; }62_LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept { return sys_days{__to_days()}; }63_LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept {64return local_days{__to_days()};65}6667_LIBCPP_HIDE_FROM_ABI constexpr bool ok() const noexcept;6869_LIBCPP_HIDE_FROM_ABI static constexpr year_month_day __from_days(days __d) noexcept;70_LIBCPP_HIDE_FROM_ABI constexpr days __to_days() const noexcept;71};7273// https://howardhinnant.github.io/date_algorithms.html#civil_from_days74_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day year_month_day::__from_days(days __d) noexcept {75static_assert(numeric_limits<unsigned>::digits >= 18, "");76static_assert(numeric_limits<int>::digits >= 20, "");77const int __z = __d.count() + 719468;78const int __era = (__z >= 0 ? __z : __z - 146096) / 146097;79const unsigned __doe = static_cast<unsigned>(__z - __era * 146097); // [0, 146096]80const unsigned __yoe = (__doe - __doe / 1460 + __doe / 36524 - __doe / 146096) / 365; // [0, 399]81const int __yr = static_cast<int>(__yoe) + __era * 400;82const unsigned __doy = __doe - (365 * __yoe + __yoe / 4 - __yoe / 100); // [0, 365]83const unsigned __mp = (5 * __doy + 2) / 153; // [0, 11]84const unsigned __dy = __doy - (153 * __mp + 2) / 5 + 1; // [1, 31]85const unsigned __mth = __mp + (__mp < 10 ? 3 : -9); // [1, 12]86return year_month_day{chrono::year{__yr + (__mth <= 2)}, chrono::month{__mth}, chrono::day{__dy}};87}8889// https://howardhinnant.github.io/date_algorithms.html#days_from_civil90_LIBCPP_HIDE_FROM_ABI inline constexpr days year_month_day::__to_days() const noexcept {91static_assert(numeric_limits<unsigned>::digits >= 18, "");92static_assert(numeric_limits<int>::digits >= 20, "");9394const int __yr = static_cast<int>(__y_) - (__m_ <= February);95const unsigned __mth = static_cast<unsigned>(__m_);96const unsigned __dy = static_cast<unsigned>(__d_);9798const int __era = (__yr >= 0 ? __yr : __yr - 399) / 400;99const unsigned __yoe = static_cast<unsigned>(__yr - __era * 400); // [0, 399]100const unsigned __doy = (153 * (__mth + (__mth > 2 ? -3 : 9)) + 2) / 5 + __dy - 1; // [0, 365]101const unsigned __doe = __yoe * 365 + __yoe / 4 - __yoe / 100 + __doy; // [0, 146096]102return days{__era * 146097 + static_cast<int>(__doe) - 719468};103}104105_LIBCPP_HIDE_FROM_ABI inline constexpr bool106operator==(const year_month_day& __lhs, const year_month_day& __rhs) noexcept {107return __lhs.year() == __rhs.year() && __lhs.month() == __rhs.month() && __lhs.day() == __rhs.day();108}109110_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering111operator<=>(const year_month_day& __lhs, const year_month_day& __rhs) noexcept {112if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0)113return __c;114if (auto __c = __lhs.month() <=> __rhs.month(); __c != 0)115return __c;116return __lhs.day() <=> __rhs.day();117}118119_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year_month& __lhs, const day& __rhs) noexcept {120return year_month_day{__lhs.year(), __lhs.month(), __rhs};121}122123_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year_month& __lhs, int __rhs) noexcept {124return __lhs / day(__rhs);125}126127_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const year& __lhs, const month_day& __rhs) noexcept {128return __lhs / __rhs.month() / __rhs.day();129}130131_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(int __lhs, const month_day& __rhs) noexcept {132return year(__lhs) / __rhs;133}134135_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const month_day& __lhs, const year& __rhs) noexcept {136return __rhs / __lhs;137}138139_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day operator/(const month_day& __lhs, int __rhs) noexcept {140return year(__rhs) / __lhs;141}142143_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day144operator+(const year_month_day& __lhs, const months& __rhs) noexcept {145return (__lhs.year() / __lhs.month() + __rhs) / __lhs.day();146}147148_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day149operator+(const months& __lhs, const year_month_day& __rhs) noexcept {150return __rhs + __lhs;151}152153_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day154operator-(const year_month_day& __lhs, const months& __rhs) noexcept {155return __lhs + -__rhs;156}157158_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day159operator+(const year_month_day& __lhs, const years& __rhs) noexcept {160return (__lhs.year() + __rhs) / __lhs.month() / __lhs.day();161}162163_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day164operator+(const years& __lhs, const year_month_day& __rhs) noexcept {165return __rhs + __lhs;166}167168_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day169operator-(const year_month_day& __lhs, const years& __rhs) noexcept {170return __lhs + -__rhs;171}172173_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const months& __dm) noexcept {174*this = *this + __dm;175return *this;176}177_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const months& __dm) noexcept {178*this = *this - __dm;179return *this;180}181_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator+=(const years& __dy) noexcept {182*this = *this + __dy;183return *this;184}185_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day& year_month_day::operator-=(const years& __dy) noexcept {186*this = *this - __dy;187return *this;188}189190class year_month_day_last {191private:192chrono::year __y_;193chrono::month_day_last __mdl_;194195public:196_LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last(const year& __yval, const month_day_last& __mdlval) noexcept197: __y_{__yval}, __mdl_{__mdlval} {}198199_LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const months& __m) noexcept;200_LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const months& __m) noexcept;201_LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator+=(const years& __y) noexcept;202_LIBCPP_HIDE_FROM_ABI constexpr year_month_day_last& operator-=(const years& __y) noexcept;203204_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; }205_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __mdl_.month(); }206_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month_day_last month_day_last() const noexcept { return __mdl_; }207_LIBCPP_HIDE_FROM_ABI constexpr chrono::day day() const noexcept;208_LIBCPP_HIDE_FROM_ABI inline constexpr operator sys_days() const noexcept {209return sys_days{year() / month() / day()};210}211_LIBCPP_HIDE_FROM_ABI inline explicit constexpr operator local_days() const noexcept {212return local_days{year() / month() / day()};213}214_LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __mdl_.ok(); }215};216217_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::day year_month_day_last::day() const noexcept {218constexpr chrono::day __d[] = {219chrono::day(31),220chrono::day(28),221chrono::day(31),222chrono::day(30),223chrono::day(31),224chrono::day(30),225chrono::day(31),226chrono::day(31),227chrono::day(30),228chrono::day(31),229chrono::day(30),230chrono::day(31)};231return (month() != February || !__y_.is_leap()) && month().ok()232? __d[static_cast<unsigned>(month()) - 1]233: chrono::day{29};234}235236_LIBCPP_HIDE_FROM_ABI inline constexpr bool237operator==(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept {238return __lhs.year() == __rhs.year() && __lhs.month_day_last() == __rhs.month_day_last();239}240241_LIBCPP_HIDE_FROM_ABI inline constexpr strong_ordering242operator<=>(const year_month_day_last& __lhs, const year_month_day_last& __rhs) noexcept {243if (auto __c = __lhs.year() <=> __rhs.year(); __c != 0)244return __c;245return __lhs.month_day_last() <=> __rhs.month_day_last();246}247248_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(const year_month& __lhs, last_spec) noexcept {249return year_month_day_last{__lhs.year(), month_day_last{__lhs.month()}};250}251252_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last253operator/(const year& __lhs, const month_day_last& __rhs) noexcept {254return year_month_day_last{__lhs, __rhs};255}256257_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(int __lhs, const month_day_last& __rhs) noexcept {258return year_month_day_last{year{__lhs}, __rhs};259}260261_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last262operator/(const month_day_last& __lhs, const year& __rhs) noexcept {263return __rhs / __lhs;264}265266_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last operator/(const month_day_last& __lhs, int __rhs) noexcept {267return year{__rhs} / __lhs;268}269270_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last271operator+(const year_month_day_last& __lhs, const months& __rhs) noexcept {272return (__lhs.year() / __lhs.month() + __rhs) / last;273}274275_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last276operator+(const months& __lhs, const year_month_day_last& __rhs) noexcept {277return __rhs + __lhs;278}279280_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last281operator-(const year_month_day_last& __lhs, const months& __rhs) noexcept {282return __lhs + (-__rhs);283}284285_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last286operator+(const year_month_day_last& __lhs, const years& __rhs) noexcept {287return year_month_day_last{__lhs.year() + __rhs, __lhs.month_day_last()};288}289290_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last291operator+(const years& __lhs, const year_month_day_last& __rhs) noexcept {292return __rhs + __lhs;293}294295_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last296operator-(const year_month_day_last& __lhs, const years& __rhs) noexcept {297return __lhs + (-__rhs);298}299300_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last&301year_month_day_last::operator+=(const months& __dm) noexcept {302*this = *this + __dm;303return *this;304}305_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last&306year_month_day_last::operator-=(const months& __dm) noexcept {307*this = *this - __dm;308return *this;309}310_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last&311year_month_day_last::operator+=(const years& __dy) noexcept {312*this = *this + __dy;313return *this;314}315_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day_last&316year_month_day_last::operator-=(const years& __dy) noexcept {317*this = *this - __dy;318return *this;319}320321_LIBCPP_HIDE_FROM_ABI inline constexpr year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept322: __y_{__ymdl.year()}, __m_{__ymdl.month()}, __d_{__ymdl.day()} {}323324_LIBCPP_HIDE_FROM_ABI inline constexpr bool year_month_day::ok() const noexcept {325if (!__y_.ok() || !__m_.ok())326return false;327return chrono::day{1} <= __d_ && __d_ <= (__y_ / __m_ / last).day();328}329330} // namespace chrono331332_LIBCPP_END_NAMESPACE_STD333334#endif // _LIBCPP_STD_VER >= 20335336#endif // _LIBCPP___CHRONO_YEAR_MONTH_DAY_H337338339