Embedded Template Library 1.0
Loading...
Searching...
No Matches
year_month_weekday.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2025 John Wellbelove
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_IN_CHRONO_H
32 #error DO NOT DIRECTLY INCLUDE THIS FILE. USE CHRONO.H
33#endif
34
35namespace etl
36{
37 namespace chrono
38 {
39 //*************************************************************************
41 //*************************************************************************
43 {
44 public:
45
46 //*************************************************************************
48 //*************************************************************************
49 ETL_CONSTEXPR year_month_weekday()
50 : y()
51 , m()
52 , wdi()
53 {
54 }
55
56 //*************************************************************************
58 //*************************************************************************
60 ETL_NOEXCEPT
61 : y(y_)
62 , m(m_)
63 , wdi(wdi_)
64 {
65 }
66
67 //*************************************************************************
69 //*************************************************************************
70 ETL_CONSTEXPR14 year_month_weekday(const etl::chrono::sys_days& sd) ETL_NOEXCEPT
71 : y(0)
72 , m(0U)
73 , wdi(etl::chrono::weekday(0), 0U)
74 {
75 // Extract year, month, and day
77
78 etl::chrono::year yr = ymd.year();
79 etl::chrono::month mth = ymd.month();
80 etl::chrono::day dy = ymd.day();
81
82 // Get the weekday from sys_days
84
85 // Count how many times this weekday has occurred in the month so far
86 // We walk backward from the given day in steps of 7 days
87 unsigned index = 1;
88
89 for (int offset = static_cast<int>(static_cast<unsigned>(dy)) - 7; offset > 0; offset -= 7)
90 {
91 ++index;
92 }
93
94 y = yr;
95 m = mth;
97 }
98
99 //*************************************************************************
101 //*************************************************************************
102 ETL_CONSTEXPR14 year_month_weekday(const etl::chrono::local_days& ld) ETL_NOEXCEPT
103 : y(0)
104 , m(0U)
105 , wdi(etl::chrono::weekday(0), 0U)
106 {
107 year_month_weekday ymwd(sys_days(ld.time_since_epoch()));
108
109 y = ymwd.year();
110 m = ymwd.month();
111 wdi = ymwd.weekday_indexed();
112 }
113
114 //*************************************************************************
116 //*************************************************************************
117 ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::year year() const ETL_NOEXCEPT
118 {
119 return y;
120 }
121
122 //*************************************************************************
124 //*************************************************************************
125 ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::month month() const ETL_NOEXCEPT
126 {
127 return m;
128 }
129
130 //*************************************************************************
132 //*************************************************************************
133 ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday weekday() const ETL_NOEXCEPT
134 {
135 return wdi.weekday();
136 }
137
138 //*************************************************************************
140 //*************************************************************************
141 ETL_NODISCARD ETL_CONSTEXPR14 unsigned index() const ETL_NOEXCEPT
142 {
143 return wdi.index();
144 }
145
146 //*************************************************************************
148 //*************************************************************************
149 ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday_indexed weekday_indexed() const ETL_NOEXCEPT
150 {
151 return wdi;
152 }
153
154 //*************************************************************************
156 //*************************************************************************
157 ETL_NODISCARD ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT
158 {
159 return y.ok() && m.ok() && wdi.ok();
160 }
161
162 //***********************************************************************
164 //***********************************************************************
165 ETL_NODISCARD ETL_CONSTEXPR14 operator etl::chrono::sys_days() const ETL_NOEXCEPT
166 {
167 if (ok())
168 {
171
172 etl::chrono::sys_days sd = ymd;
173
174 unsigned int target_wd = ymwd.weekday().c_encoding();
175 unsigned int target_index = ymwd.index();
176
177 etl::chrono::weekday first_weekday(static_cast<unsigned>(sd.time_since_epoch().count()));
178
179 unsigned int first_wd = first_weekday.c_encoding();
180 unsigned int offset = (target_wd - first_wd + 7U) % 7U;
181 unsigned int day_of_month = offset + (target_index - 1U) * 7U;
182
183 etl::chrono::year_month_day result(year(), month(), etl::chrono::day(day_of_month));
184
185 return etl::chrono::sys_days(result);
186 }
187 else
188 {
189 return etl::chrono::sys_days();
190 }
191 }
192
193 //***********************************************************************
195 //***********************************************************************
196 ETL_NODISCARD ETL_CONSTEXPR14 operator etl::chrono::local_days() const ETL_NOEXCEPT
197 {
198 return local_days(sys_days(*this).time_since_epoch());
199 }
200
201 private:
202
206 };
207
208 //*************************************************************************
210 //*************************************************************************
211 inline ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator+(const etl::chrono::year_month_weekday& ymwd, const etl::chrono::years& dy)
212 ETL_NOEXCEPT
213 {
214 return etl::chrono::year_month_weekday(ymwd.year() + dy, ymwd.month(), ymwd.weekday_indexed());
215 }
216
217 //*************************************************************************
219 //*************************************************************************
220 inline ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator+(const etl::chrono::years& dy, const etl::chrono::year_month_weekday& ymwd)
221 ETL_NOEXCEPT
222 {
223 return etl::chrono::year_month_weekday(ymwd.year() + dy, ymwd.month(), ymwd.weekday_indexed());
224 }
225
226 //*************************************************************************
228 //*************************************************************************
229 inline ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator+(const etl::chrono::year_month_weekday& ymwd, const etl::chrono::months& dm)
230 ETL_NOEXCEPT
231 {
232 return etl::chrono::year_month_weekday(ymwd.year(), ymwd.month() + dm, ymwd.weekday_indexed());
233 }
234
235 //*************************************************************************
237 //*************************************************************************
238 inline ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator+(const etl::chrono::months& dm, const etl::chrono::year_month_weekday& ymwd)
239 ETL_NOEXCEPT
240 {
241 return etl::chrono::year_month_weekday(ymwd.year(), ymwd.month() + dm, ymwd.weekday_indexed());
242 }
243
244 //*************************************************************************
246 //*************************************************************************
247 inline ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator-(const etl::chrono::year_month_weekday& ymwd, const etl::chrono::years& dy)
248 ETL_NOEXCEPT
249 {
250 return etl::chrono::year_month_weekday(ymwd.year() - dy, ymwd.month(), ymwd.weekday_indexed());
251 }
252
253 //*************************************************************************
255 //*************************************************************************
256 inline ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator-(const etl::chrono::year_month_weekday& ymwd, const etl::chrono::months& dm)
257 ETL_NOEXCEPT
258 {
259 return etl::chrono::year_month_weekday(ymwd.year(), ymwd.month() - dm, ymwd.weekday_indexed());
260 }
261
262 //*************************************************************************
264 //*************************************************************************
265 inline ETL_CONSTEXPR14 bool operator==(const etl::chrono::year_month_weekday& lhs, const etl::chrono::year_month_weekday& rhs) ETL_NOEXCEPT
266 {
267 return (lhs.year() == rhs.year()) && (lhs.month() == rhs.month()) && (lhs.weekday() == rhs.weekday());
268 }
269
270 //*************************************************************************
272 //*************************************************************************
273 inline ETL_CONSTEXPR14 bool operator!=(const etl::chrono::year_month_weekday& lhs, const etl::chrono::year_month_weekday& rhs) ETL_NOEXCEPT
274 {
275 return !(lhs == rhs);
276 }
277
278 //*************************************************************************
280 //*************************************************************************
282 {
283 public:
284
285 //*************************************************************************
287 //*************************************************************************
289 ETL_NOEXCEPT
290 : y(y_)
291 , m(m_)
292 , wdl(wdl_)
293 {
294 }
295
296 //*************************************************************************
298 //*************************************************************************
299 ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::year year() const ETL_NOEXCEPT
300 {
301 return y;
302 }
303
304 //*************************************************************************
306 //*************************************************************************
307 ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::month month() const ETL_NOEXCEPT
308 {
309 return m;
310 }
311
312 //*************************************************************************
314 //*************************************************************************
315 ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday weekday() const ETL_NOEXCEPT
316 {
317 return wdl.weekday();
318 }
319
320 //*************************************************************************
322 //*************************************************************************
323 ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday_last weekday_last() const ETL_NOEXCEPT
324 {
325 return wdl;
326 }
327
328 //*************************************************************************
330 //*************************************************************************
331 ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last& operator+=(const etl::chrono::years& dy) ETL_NOEXCEPT
332 {
333 y += dy;
334
335 return *this;
336 }
337
338 //*************************************************************************
340 //*************************************************************************
341 ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last& operator+=(const etl::chrono::months& dm) ETL_NOEXCEPT
342 {
343 m += dm;
344
345 return *this;
346 }
347
348 //*************************************************************************
350 //*************************************************************************
351 ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last& operator-=(const etl::chrono::years& dy) ETL_NOEXCEPT
352 {
353 y -= dy;
354
355 return *this;
356 }
357
358 //*************************************************************************
360 //*************************************************************************
361 ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last& operator-=(const etl::chrono::months& dm) ETL_NOEXCEPT
362 {
363 m -= dm;
364
365 return *this;
366 }
367
368 //*************************************************************************
370 //*************************************************************************
371 ETL_NODISCARD ETL_CONSTEXPR14 operator etl::chrono::sys_days() const ETL_NOEXCEPT
372 {
373 // Get the last day of the month
375 etl::chrono::day last_day = ymdl.day();
376
377 // Walk backward from the last day to find the last occurrence of the
378 // target weekday
379 unsigned d = static_cast<unsigned>(last_day);
380
381 for (; d >= 1; --d)
382 {
384 etl::chrono::sys_days ymd_sys_days = static_cast<etl::chrono::sys_days>(ymd);
385 etl::chrono::weekday wd(static_cast<unsigned>(ymd_sys_days.time_since_epoch().count()));
386
387 if (wd == weekday())
388 {
389 return ymd_sys_days;
390 }
391 }
392
393 // If not found (should not happen for valid input), return epoch
394 return etl::chrono::sys_days();
395 }
396
397 //*************************************************************************
399 //*************************************************************************
400 ETL_NODISCARD ETL_CONSTEXPR14 explicit operator etl::chrono::local_days() const ETL_NOEXCEPT
401 {
402 return local_days(sys_days(*this).time_since_epoch());
403 }
404
405 private:
406
410 };
411
412 //*************************************************************************
414 //*************************************************************************
416 const etl::chrono::years& dy) ETL_NOEXCEPT
417 {
418 return etl::chrono::year_month_weekday_last(ymwdl.year() + dy, ymwdl.month(), ymwdl.weekday_last());
419 }
420
421 //*************************************************************************
423 //*************************************************************************
424 inline ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator+(const etl::chrono::years& dy,
425 const etl::chrono::year_month_weekday_last& ymwdl) ETL_NOEXCEPT
426 {
427 return etl::chrono::year_month_weekday_last(ymwdl.year() + dy, ymwdl.month(), ymwdl.weekday_last());
428 }
429
430 //*************************************************************************
432 //*************************************************************************
434 const etl::chrono::months& dm) ETL_NOEXCEPT
435 {
436 return etl::chrono::year_month_weekday_last(ymwdl.year(), ymwdl.month() + dm, ymwdl.weekday_last());
437 }
438
439 //*************************************************************************
441 //*************************************************************************
442 inline ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator+(const etl::chrono::months& dm,
443 const etl::chrono::year_month_weekday_last& ymwdl) ETL_NOEXCEPT
444 {
445 return etl::chrono::year_month_weekday_last(ymwdl.year(), ymwdl.month() + dm, ymwdl.weekday_last());
446 }
447
448 //*************************************************************************
451 //*************************************************************************
453 const etl::chrono::years& dy) ETL_NOEXCEPT
454 {
455 return etl::chrono::year_month_weekday_last(ymwdl.year() - dy, ymwdl.month(), ymwdl.weekday_last());
456 }
457
458 //*************************************************************************
461 //*************************************************************************
463 const etl::chrono::months& dm) ETL_NOEXCEPT
464 {
465 return etl::chrono::year_month_weekday_last(ymwdl.year(), ymwdl.month() - dm, ymwdl.weekday_last());
466 }
467
468 //*************************************************************************
470 //*************************************************************************
472 ETL_NOEXCEPT
473 {
474 return (lhs.year() == rhs.year()) && (lhs.month() == rhs.month()) && (lhs.weekday() == rhs.weekday());
475 }
476
477 //*************************************************************************
479 //*************************************************************************
481 ETL_NOEXCEPT
482 {
483 return !(lhs == rhs);
484 }
485 } // namespace chrono
486
487 //*************************************************************************
489 //*************************************************************************
490#if ETL_USING_8BIT_TYPES
491 template <>
492 struct hash<etl::chrono::year_month_weekday>
493 {
494 size_t operator()(const etl::chrono::year_month_weekday& ymwd) const
495 {
496 etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<int>(ymwd.year()));
497 etl::chrono::month::rep m = static_cast<etl::chrono::month::rep>(static_cast<unsigned>(ymwd.month()));
498 unsigned int wd = ymwd.weekday().c_encoding();
499
500 uint8_t buffer[sizeof(y) + sizeof(m) + sizeof(wd)];
501
502 memcpy(buffer, &y, sizeof(y));
503 memcpy(buffer + sizeof(y), &m, sizeof(m));
504 memcpy(buffer + sizeof(y) + sizeof(m), &wd, sizeof(wd));
505
506 return etl::private_hash::generic_hash<size_t>(buffer, buffer + sizeof(y) + sizeof(m) + sizeof(wd));
507 }
508 };
509#endif
510
511 //*************************************************************************
513 //*************************************************************************
514#if ETL_USING_8BIT_TYPES
515 template <>
516 struct hash<etl::chrono::year_month_weekday_last>
517 {
518 size_t operator()(const etl::chrono::year_month_weekday_last& ymwdl) const
519 {
520 etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<int>(ymwdl.year()));
521 etl::chrono::month::rep m = static_cast<etl::chrono::month::rep>(static_cast<unsigned>(ymwdl.month()));
522 unsigned int wd = ymwdl.weekday().c_encoding();
523
524 uint8_t buffer[sizeof(y) + sizeof(m) + sizeof(wd)];
525
526 memcpy(buffer, &y, sizeof(y));
527 memcpy(buffer + sizeof(y), &m, sizeof(m));
528 memcpy(buffer + sizeof(y) + sizeof(m), &wd, sizeof(wd));
529
530 return etl::private_hash::generic_hash<size_t>(buffer, buffer + sizeof(y) + sizeof(m) + sizeof(wd));
531 }
532 };
533#endif
534} // namespace etl
day
Definition day.h:43
Spaceship operator.
Definition month_day.h:202
month
Definition month.h:54
ETL_NODISCARD ETL_CONSTEXPR14 duration time_since_epoch() const ETL_NOEXCEPT
Definition time_point.h:100
weekday_indexed
Definition weekday.h:338
weekday_last
Definition weekday.h:409
weekday
Definition weekday.h:54
ETL_NODISCARD ETL_CONSTEXPR14 unsigned c_encoding() const ETL_NOEXCEPT
Get the C encoding of the weekday.
Definition weekday.h:210
ETL_CONSTEXPR weekday() ETL_NOEXCEPT
Default constructor.
Definition weekday.h:60
Spaceship operator.
Definition year_month_day.h:455
year_month_day
Definition year_month_day.h:45
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::month month() const ETL_NOEXCEPT
Returns the month.
Definition year_month_day.h:152
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::day day() const ETL_NOEXCEPT
Returns the day.
Definition year_month_day.h:160
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::year year() const ETL_NOEXCEPT
Returns the year.
Definition year_month_day.h:144
year_month_weekday_last
Definition year_month_weekday.h:282
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday weekday() const ETL_NOEXCEPT
Returns the weekday.
Definition year_month_weekday.h:315
ETL_CONSTEXPR14 year_month_weekday_last(const etl::chrono::year &y_, const etl::chrono::month &m_, const etl::chrono::weekday_last &wdl_) ETL_NOEXCEPT
Construct from year, month, weekday_last.
Definition year_month_weekday.h:288
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday_last weekday_last() const ETL_NOEXCEPT
Returns the weekday_last.
Definition year_month_weekday.h:323
ETL_NODISCARD ETL_CONSTEXPR14 operator etl::chrono::sys_days() const ETL_NOEXCEPT
Converts to etl::chrono::sys_days.
Definition year_month_weekday.h:371
ETL_NODISCARD ETL_CONSTEXPR14 operator etl::chrono::local_days() const ETL_NOEXCEPT
Converts to etl::chrono::local_days.
Definition year_month_weekday.h:400
ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last & operator+=(const etl::chrono::months &dm) ETL_NOEXCEPT
Adds etl::chrono::months.
Definition year_month_weekday.h:341
ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last & operator-=(const etl::chrono::years &dy) ETL_NOEXCEPT
Subtracts etl::chrono::years.
Definition year_month_weekday.h:351
ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last & operator-=(const etl::chrono::months &dm) ETL_NOEXCEPT
Subtracts etl::chrono::months.
Definition year_month_weekday.h:361
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::month month() const ETL_NOEXCEPT
Returns the month.
Definition year_month_weekday.h:307
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::year year() const ETL_NOEXCEPT
Returns the year.
Definition year_month_weekday.h:299
ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last & operator+=(const etl::chrono::years &dy) ETL_NOEXCEPT
Adds etl::chrono::years.
Definition year_month_weekday.h:331
year_month_weekday
Definition year_month_weekday.h:43
ETL_CONSTEXPR14 year_month_weekday(const etl::chrono::year &y_, const etl::chrono::month &m_, const etl::chrono::weekday_indexed &wdi_) ETL_NOEXCEPT
Construct from month, day, and weekday_indexed.
Definition year_month_weekday.h:59
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday weekday() const ETL_NOEXCEPT
Returns the weekday.
Definition year_month_weekday.h:133
ETL_CONSTEXPR14 year_month_weekday(const etl::chrono::sys_days &sd) ETL_NOEXCEPT
Construct from sys_days.
Definition year_month_weekday.h:70
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::year year() const ETL_NOEXCEPT
Returns the year.
Definition year_month_weekday.h:117
ETL_NODISCARD ETL_CONSTEXPR14 operator etl::chrono::sys_days() const ETL_NOEXCEPT
Converts to etl::chrono::sys_days.
Definition year_month_weekday.h:165
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday_indexed weekday_indexed() const ETL_NOEXCEPT
Returns the weekday_indexed.
Definition year_month_weekday.h:149
ETL_CONSTEXPR14 year_month_weekday(const etl::chrono::local_days &ld) ETL_NOEXCEPT
Construct from local_days.
Definition year_month_weekday.h:102
ETL_NODISCARD ETL_CONSTEXPR14 operator etl::chrono::local_days() const ETL_NOEXCEPT
Converts to etl::chrono::local_days.
Definition year_month_weekday.h:196
ETL_NODISCARD ETL_CONSTEXPR14 unsigned index() const ETL_NOEXCEPT
Returns the weekday index.
Definition year_month_weekday.h:141
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::month month() const ETL_NOEXCEPT
Returns the month.
Definition year_month_weekday.h:125
ETL_NODISCARD ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT
Returns true if the year/month/day is valid.
Definition year_month_weekday.h:157
ETL_CONSTEXPR year_month_weekday()
Default constructor.
Definition year_month_weekday.h:49
year
Definition year.h:43
ETL_CONSTEXPR14 etl::chrono::day operator+(const etl::chrono::day &d, const etl::chrono::days &ds) ETL_NOEXCEPT
Spaceship operator.
Definition day.h:226
ETL_CONSTEXPR14 etl::chrono::day operator-(const etl::chrono::day &d, const etl::chrono::days &ds) ETL_NOEXCEPT
Definition day.h:252
ETL_CONSTEXPR14 bool operator==(const etl::chrono::day &d1, const etl::chrono::day &d2) ETL_NOEXCEPT
Equality operator.
Definition day.h:166
ETL_CONSTEXPR14 bool operator!=(const etl::chrono::day &d1, const etl::chrono::day &d2) ETL_NOEXCEPT
Inequality operator.
Definition day.h:174
bitset_ext
Definition absolute.h:40