tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
year_month_day.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2023 Tobias Hienzsch
3
4#ifndef TETL_CHRONO_YEAR_MONTH_DAY_HPP
5#define TETL_CHRONO_YEAR_MONTH_DAY_HPP
6
7#include <etl/_chrono/day.hpp>
8#include <etl/_chrono/local_t.hpp>
9#include <etl/_chrono/month.hpp>
10#include <etl/_chrono/system_clock.hpp>
11#include <etl/_chrono/year.hpp>
12#include <etl/_chrono/year_month_day_last.hpp>
13#include <etl/_limits/numeric_limits.hpp>
14
15namespace etl::chrono {
16
17/// \ingroup chrono
19private:
20 // https://howardhinnant.github.io/date_algorithms.html#civil_from_days
21 [[nodiscard]] static constexpr auto civil_from_days(int32_t z) noexcept -> year_month_day
22 {
23 static_assert(etl::numeric_limits<uint32_t>::digits >= 18, "Not yet ported to a 16 bit unsigned integer");
24 static_assert(etl::numeric_limits<int32_t>::digits >= 20, "Not yet ported to a 16 bit signed integer");
25
26 z += 719468;
27 int32_t const era = (z >= 0 ? z : z - 146096) / 146097;
28 auto const doe = static_cast<uint32_t>(z - (era * 146097));
29 uint32_t const yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
30 int32_t const y = static_cast<int32_t>(yoe) + (era * 400);
31 uint32_t const doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
32 uint32_t const mp = (5 * doy + 2) / 153;
33 uint32_t const d = doy - ((153 * mp + 2) / 5) + 1;
34 uint32_t const m = mp < 10 ? mp + 3 : mp - 9;
35
36 return {
37 chrono::year{static_cast<int>(y) + static_cast<int>(m <= 2)},
38 chrono::month{static_cast<unsigned>(m)},
39 chrono::day{static_cast<unsigned>(d)},
40 };
41 }
42
43 // https://howardhinnant.github.io/date_algorithms.html#days_from_civil
44 [[nodiscard]] static constexpr auto days_from_civil(int32_t y, uint32_t m, uint32_t d) noexcept -> days
45 {
46 static_assert(etl::numeric_limits<uint32_t>::digits >= 18, "Not yet ported to a 16 bit unsigned integer");
47 static_assert(etl::numeric_limits<int32_t>::digits >= 20, "Not yet ported to a 16 bit signed integer");
48
49 y -= static_cast<int32_t>(m <= 2);
50 int32_t const era = (y >= 0 ? y : y - 399) / 400;
51 auto const yoe = static_cast<uint32_t>(y - (era * 400)); // [0, 399]
52 uint32_t const doy = ((153 * (m > 2 ? m - 3 : m + 9) + 2) / 5) + d - 1; // [0, 365]
53 uint32_t const doe = (yoe * 365) + (yoe / 4) - (yoe / 100) + doy; // [0, 146096]
54 return days{(era * 146097) + static_cast<int32_t>(doe) - 719468};
55 }
56
57public:
58 year_month_day() = default;
59
60 constexpr year_month_day(chrono::year const& y, chrono::month const& m, chrono::day const& d) noexcept
61 : _y{y}
62 , _m{m}
63 , _d{d}
64 {
65 }
66
67 constexpr year_month_day(year_month_day_last const& ymdl) noexcept
68 : _y{ymdl.year()}
69 , _m{ymdl.month()}
70 , _d{ymdl.day()}
71 {
72 }
73
74 constexpr year_month_day(sys_days const& dp) noexcept
76 {
77 }
78
79 constexpr explicit year_month_day(local_days const& dp) noexcept
81 {
82 }
83
84 constexpr auto operator+=(months const& m) noexcept -> year_month_day&;
85 constexpr auto operator-=(months const& m) noexcept -> year_month_day&;
86 constexpr auto operator+=(years const& y) noexcept -> year_month_day&;
87 constexpr auto operator-=(years const& y) noexcept -> year_month_day&;
88
89 [[nodiscard]] constexpr auto year() const noexcept -> chrono::year
90 {
91 return _y;
92 }
93
94 [[nodiscard]] constexpr auto month() const noexcept -> chrono::month
95 {
96 return _m;
97 }
98
99 [[nodiscard]] constexpr auto day() const noexcept -> chrono::day
100 {
101 return _d;
102 }
103
104 [[nodiscard]] constexpr operator sys_days() const noexcept
105 {
106 return sys_days{days_from_civil(int{year()}, unsigned{month()}, unsigned{day()})};
107 }
108
109 [[nodiscard]] constexpr explicit operator local_days() const noexcept
110 {
111 return local_days{static_cast<sys_days>(*this).time_since_epoch()};
112 }
113
114 [[nodiscard]] constexpr auto ok() const noexcept -> bool
115 {
116 if (not year().ok() or not month().ok()) {
117 return false;
118 }
119 return day() >= chrono::day{1} and day() <= detail::last_day_of_month(year(), month());
120 }
121
122private:
123 chrono::year _y;
124 chrono::month _m;
125 chrono::day _d;
126};
127
128[[nodiscard]] constexpr auto operator==(year_month_day const& lhs, year_month_day const& rhs) noexcept -> bool
129{
130 return lhs.year() == rhs.year() and lhs.month() == rhs.month() and lhs.day() == rhs.day();
131}
132
133[[nodiscard]] constexpr auto operator+(chrono::year_month_day const& lhs, chrono::months const& rhs) noexcept
135{
136 auto const ym = year_month{lhs.year(), lhs.month()} + rhs;
137 return {ym.year(), ym.month(), lhs.day()};
138}
139
140[[nodiscard]] constexpr auto operator+(chrono::months const& lhs, chrono::year_month_day const& rhs) noexcept
142{
143 return rhs + lhs;
144}
145
146[[nodiscard]] constexpr auto operator+(chrono::year_month_day const& lhs, chrono::years const& rhs) noexcept
148{
149 return {lhs.year() + rhs, lhs.month(), lhs.day()};
150}
151
152[[nodiscard]] constexpr auto operator+(chrono::years const& lhs, chrono::year_month_day const& rhs) noexcept
154{
155 return rhs + lhs;
156}
157
158[[nodiscard]] constexpr auto operator-(chrono::year_month_day const& lhs, chrono::months const& rhs) noexcept
160{
161 return lhs + -rhs;
162}
163
164[[nodiscard]] constexpr auto operator-(chrono::year_month_day const& lhs, chrono::years const& rhs) noexcept
166{
167 return lhs + -rhs;
168}
169
170constexpr auto year_month_day::operator+=(months const& m) noexcept -> year_month_day&
171{
172 *this = *this + m;
173 return *this;
174}
175
176constexpr auto year_month_day::operator-=(months const& m) noexcept -> year_month_day&
177{
178 *this = *this - m;
179 return *this;
180}
181
182constexpr auto year_month_day::operator+=(years const& y) noexcept -> year_month_day&
183{
184 *this = *this + y;
185 return *this;
186}
187
188constexpr auto year_month_day::operator-=(years const& y) noexcept -> year_month_day&
189{
190 *this = *this - y;
191 return *this;
192}
193
194[[nodiscard]] constexpr auto operator/(year_month const& ym, day const& d) noexcept -> year_month_day
195{
196 return {ym.year(), ym.month(), d};
197}
198
199[[nodiscard]] constexpr auto operator/(year_month const& ym, int d) noexcept -> year_month_day
200{
201 return {ym.year(), ym.month(), day(static_cast<unsigned>(d))};
202}
203
204[[nodiscard]] constexpr auto operator/(year const& y, month_day const& md) noexcept -> year_month_day
205{
206 return {y, md.month(), md.day()};
207}
208
209[[nodiscard]] constexpr auto operator/(int y, month_day const& md) noexcept -> year_month_day
210{
211 return {year{y}, md.month(), md.day()};
212}
213
214[[nodiscard]] constexpr auto operator/(month_day const& md, year const& y) noexcept -> year_month_day
215{
216 return {y, md.month(), md.day()};
217}
218
219[[nodiscard]] constexpr auto operator/(month_day const& md, int y) noexcept -> year_month_day
220{
221 return {year{y}, md.month(), md.day()};
222}
223
224} // namespace etl::chrono
225
226#endif // TETL_CHRONO_YEAR_MONTH_DAY_HPP
Definition abs.hpp:12
constexpr auto operator/(int y, month_day const &md) noexcept -> year_month_day
Definition year_month_day.hpp:209
constexpr auto operator+(chrono::year_month_day const &lhs, chrono::years const &rhs) noexcept -> chrono::year_month_day
Definition year_month_day.hpp:146
constexpr auto operator/(month_day const &md, year const &y) noexcept -> year_month_day
Definition year_month_day.hpp:214
constexpr auto operator-(chrono::year_month_day const &lhs, chrono::years const &rhs) noexcept -> chrono::year_month_day
Definition year_month_day.hpp:164
constexpr auto operator/(year const &y, int m) noexcept -> year_month
Definition year_month.hpp:120
constexpr auto operator-(chrono::year_month_day const &lhs, chrono::months const &rhs) noexcept -> chrono::year_month_day
Definition year_month_day.hpp:158
constexpr auto operator+(chrono::year_month_day const &lhs, chrono::months const &rhs) noexcept -> chrono::year_month_day
Definition year_month_day.hpp:133
constexpr auto operator/(year const &y, month_day const &md) noexcept -> year_month_day
Definition year_month_day.hpp:204
constexpr auto operator+(chrono::months const &lhs, chrono::year_month_day const &rhs) noexcept -> chrono::year_month_day
Definition year_month_day.hpp:140
constexpr auto operator+(chrono::years const &lhs, chrono::year_month_day const &rhs) noexcept -> chrono::year_month_day
Definition year_month_day.hpp:152
constexpr auto operator==(month lhs, month rhs) noexcept -> bool
Definition month.hpp:53
constexpr auto operator==(year_month_day const &lhs, year_month_day const &rhs) noexcept -> bool
Definition year_month_day.hpp:128
constexpr auto operator/(year_month const &ym, day const &d) noexcept -> year_month_day
Definition year_month_day.hpp:194
constexpr auto operator+(year const &lhs, years const &rhs) noexcept -> year
Definition year.hpp:120
Definition adjacent_find.hpp:9
The class day represents a day in a month.
Definition day.hpp:21
friend constexpr auto operator==(day lhs, day rhs) noexcept -> bool
Definition day.hpp:76
friend constexpr auto operator>=(day lhs, day rhs) noexcept -> bool
Definition day.hpp:96
friend constexpr auto operator<=(day lhs, day rhs) noexcept -> bool
Definition day.hpp:86
constexpr day(unsigned d) noexcept
Definition day.hpp:24
constexpr auto count() const -> rep
Returns the number of ticks for this duration.
Definition duration.hpp:98
constexpr auto operator-() const -> etl::common_type_t< duration >
Implements unary plus and unary minus for the durations.
Definition duration.hpp:128
The class month represents a month in a year.
Definition month.hpp:22
constexpr auto ok() const noexcept -> bool
Definition month.hpp:31
constexpr month(unsigned m) noexcept
Definition month.hpp:25
constexpr auto time_since_epoch() const noexcept -> duration
Returns a duration representing the amount of time between *this and the clock's epoch.
Definition time_point.hpp:62
constexpr time_point(duration const &d) noexcept
Constructs a new time_point from one of several optional data sources. Constructs a time_point at Clo...
Definition time_point.hpp:44
Definition year_month_day_last.hpp:42
constexpr auto month() const noexcept -> chrono::month
Definition year_month_day_last.hpp:59
constexpr auto year() const noexcept -> chrono::year
Definition year_month_day_last.hpp:54
constexpr auto day() const noexcept -> chrono::day
Definition year_month_day_last.hpp:69
Definition year_month_day.hpp:18
constexpr year_month_day(chrono::year const &y, chrono::month const &m, chrono::day const &d) noexcept
Definition year_month_day.hpp:60
constexpr auto ok() const noexcept -> bool
Definition year_month_day.hpp:114
constexpr year_month_day(sys_days const &dp) noexcept
Definition year_month_day.hpp:74
constexpr auto month() const noexcept -> chrono::month
Definition year_month_day.hpp:94
constexpr year_month_day(local_days const &dp) noexcept
Definition year_month_day.hpp:79
constexpr auto operator+=(years const &y) noexcept -> year_month_day &
Definition year_month_day.hpp:182
constexpr year_month_day(year_month_day_last const &ymdl) noexcept
Definition year_month_day.hpp:67
constexpr auto year() const noexcept -> chrono::year
Definition year_month_day.hpp:89
constexpr auto operator+=(months const &m) noexcept -> year_month_day &
Definition year_month_day.hpp:170
constexpr auto operator-=(years const &y) noexcept -> year_month_day &
Definition year_month_day.hpp:188
constexpr auto operator-=(months const &m) noexcept -> year_month_day &
Definition year_month_day.hpp:176
constexpr operator sys_days() const noexcept
Definition year_month_day.hpp:104
constexpr auto day() const noexcept -> chrono::day
Definition year_month_day.hpp:99
Definition year.hpp:14
constexpr auto ok() const noexcept -> bool
Definition year.hpp:76
constexpr year(int y) noexcept
Definition year.hpp:17
friend constexpr auto operator==(year lhs, year rhs) noexcept -> bool
Definition year.hpp:91
static constexpr int digits
Definition numeric_limits.hpp:616
static constexpr int digits
Definition numeric_limits.hpp:687
Definition numeric_limits.hpp:18