MT Core (C++)
Core library for replacing C++ standard in project usage
Loading...
Searching...
No Matches
calendars/mtcore_calendars/core.hpp
Go to the documentation of this file.
1/*
2
3Copyright 2025 Matthew Tolman
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16
17*/
18
19#ifndef MTCORE_CALENDARS_CORE_HPP
20#define MTCORE_CALENDARS_CORE_HPP
21
22#include "mtcore.hpp"
23#include "mtcore_calendars.hpp"
24#include "time.hpp"
25#include "zoned.hpp"
26
29 using YearBase = i32;
30
32 class AnnoDominiYear;
33
36 YearBase year = 0;
37
38 public:
39 AstronomicalYear() = default;
40 AstronomicalYear(const YearBase year) : year(year) { ensure(is_valid(year)); }
41
42 explicit operator YearBase() const { return year; }
43 explicit operator AnnoDominiYear() const;
44
45 [[nodiscard]] AstronomicalYear operator+(YearBase years) const { return {year + years}; }
46 [[nodiscard]] AstronomicalYear operator-(YearBase years) const { return {year - years}; }
47 [[nodiscard]] YearBase difference(AstronomicalYear o) const { return year - o.year; }
48 [[nodiscard]] auto operator<=>(const AstronomicalYear &o) const -> std::strong_ordering { return year <=> o.year; }
49 [[nodiscard]] auto operator==(const AstronomicalYear &o) const -> bool { return year == o.year; }
50 [[nodiscard]] auto operator!=(const AstronomicalYear &o) const -> bool { return year != o.year; }
51 [[nodiscard]] auto operator<(const AstronomicalYear &o) const -> bool { return year < o.year; }
52 [[nodiscard]] auto operator>(const AstronomicalYear &o) const -> bool { return year > o.year; }
53 [[nodiscard]] auto operator>=(const AstronomicalYear &o) const -> bool { return year >= o.year; }
54 [[nodiscard]] auto operator<=(const AstronomicalYear &o) const -> bool { return year <= o.year; }
55
56 static bool is_valid(const YearBase year) { return year > std::numeric_limits<YearBase>::min(); }
57 };
58
60 YearBase year = -1;
61
62 public:
63 AnnoDominiYear() = default;
64 AnnoDominiYear(const YearBase year) : year(year) { ensure(is_valid(year)); }
65 explicit operator YearBase() const {
66 ensure(year != 0);
67 return year;
68 }
69 explicit operator AstronomicalYear() const { return {year > 0 ? year : year + 1}; }
70
71 [[nodiscard]] AnnoDominiYear operator+(YearBase years) const {
72 return static_cast<AnnoDominiYear>(static_cast<AstronomicalYear>(*this) + years);
73 }
74 [[nodiscard]] AnnoDominiYear operator-(YearBase years) const { return *this + -years; }
75 [[nodiscard]] YearBase difference(AnnoDominiYear o) const {
76 return static_cast<AstronomicalYear>(*this).difference(static_cast<AstronomicalYear>(o));
77 }
78 [[nodiscard]] auto operator<=>(const AnnoDominiYear &o) const -> std::strong_ordering { return year <=> o.year; }
79 [[nodiscard]] auto operator==(const AnnoDominiYear &o) const -> bool { return year == o.year; }
80 [[nodiscard]] auto operator!=(const AnnoDominiYear &o) const -> bool { return year != o.year; }
81 [[nodiscard]] auto operator<(const AnnoDominiYear &o) const -> bool { return year < o.year; }
82 [[nodiscard]] auto operator>(const AnnoDominiYear &o) const -> bool { return year > o.year; }
83 [[nodiscard]] auto operator>=(const AnnoDominiYear &o) const -> bool { return year >= o.year; }
84 [[nodiscard]] auto operator<=(const AnnoDominiYear &o) const -> bool { return year <= o.year; }
85
86 static bool is_valid(const YearBase year) { return year != 0; }
87 };
88
89 inline AstronomicalYear::operator AnnoDominiYear() const { return {year > 0 ? year : year - 1}; }
90
104} // namespace mtcore::calendars
105
108
109namespace mtcore::calendars {
115 template<IsDayCalendarSystem Calendar>
116 struct CalDate {
117 using CalendarSystem = Calendar;
118 Calendar cal;
119
120 CalDate() = default;
121 CalDate(const CalDate &) = default;
122 CalDate(CalDate &&) = default;
123 CalDate &operator=(const CalDate &) = default;
124 CalDate &operator=(CalDate &&) = default;
125 CalDate(const Calendar &c) : cal(c) {}
126
127 template<typename... Args>
128 constexpr CalDate &init(Args... args) {
129 if constexpr (is_initable<Calendar, Args...>) {
130 cal.init(args...);
131 }
132 else {
133 cal = Calendar{args...};
134 }
135 return *this;
136 }
137
138 template<typename... Args>
139 constexpr static CalDate make(Args... args) {
140 CalDate res;
141 res.init(args...);
142 return res;
143 }
144
145 template<IsDayCalendarSystem Other>
146 [[nodiscard]] constexpr operator CalDate<Other>() const {
147 return {Other::from_fixed(cal.to_fixed())};
148 }
149
155 template<IsDayCalendarSystem Other>
156 [[nodiscard]] constexpr auto operator<=>(const CalDate<Other> &o) const {
157 if constexpr (std::is_same_v<std::remove_cvref_t<Other>, std::remove_cvref_t<Calendar>>) {
158 return cal <=> o.cal;
159 }
160 else {
161 return cal.to_fixed() <=> o.cal.to_fixed();
162 }
163 }
164 template<IsDayCalendarSystem Other>
165 [[nodiscard]] constexpr auto operator==(const CalDate<Other> &o) const -> bool {
166 auto cmp = *this <=> o;
167 return cmp == decltype(cmp)::equivalent;
168 }
169 template<IsDayCalendarSystem Other>
170 [[nodiscard]] constexpr auto operator!=(const CalDate<Other> &o) const -> bool {
171 auto cmp = *this <=> o;
172 return cmp != decltype(cmp)::equivalent;
173 }
174 template<IsDayCalendarSystem Other>
175 [[nodiscard]] constexpr auto operator<=(const CalDate<Other> &o) const -> bool {
176 auto cmp = *this <=> o;
177 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::less;
178 }
179 template<IsDayCalendarSystem Other>
180 [[nodiscard]] constexpr auto operator>=(const CalDate<Other> &o) const -> bool {
181 auto cmp = *this <=> o;
182 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::greater;
183 }
184 template<IsDayCalendarSystem Other>
185 [[nodiscard]] constexpr auto operator<(const CalDate<Other> &o) const -> bool {
186 auto cmp = *this <=> o;
187 return cmp == decltype(cmp)::less;
188 }
189 template<IsDayCalendarSystem Other>
190 [[nodiscard]] constexpr auto operator>(const CalDate<Other> &o) const -> bool {
191 auto cmp = *this <=> o;
192 return cmp == decltype(cmp)::greater;
193 }
194
196 [[nodiscard]] constexpr CalDate nearest_valid() const { return {Calendar::from_fixed(cal.to_fixed())}; }
197
199 [[nodiscard]] constexpr bool is_valid() const { return *this == nearest_valid(); }
200
202 [[nodiscard]] constexpr DayOfWeek day_of_week() const { return cal.to_fixed().day_of_week(); }
203
205 [[nodiscard]] constexpr CalDate add_days(const i32 days) const {
206 return {Calendar::from_fixed(cal.to_fixed().add_days(days))};
207 }
208
210 [[nodiscard]] constexpr CalDate sub_days(const i32 days) const {
211 return {Calendar::from_fixed(cal.to_fixed().sub_days(days))};
212 }
213
215 template<IsDayCalendarSystem Other>
216 [[nodiscard]] constexpr i32 day_difference(const CalDate<Other> &other) const {
217 return cal.to_fixed().day_difference(other.cal.to_fixed());
218 }
219
221 [[nodiscard]] constexpr CalDate nth_week_day(const i32 n, const DayOfWeek k) const {
222 return {Calendar::from_fixed(cal.to_fixed().nth_week_day(n, k))};
223 }
224
226 [[nodiscard]] constexpr CalDate day_of_week_before(const DayOfWeek k) const {
227 return {Calendar::from_fixed(cal.to_fixed().day_of_week_before(k))};
228 }
229
231 [[nodiscard]] constexpr CalDate day_of_week_after(const DayOfWeek k) const {
232 return {Calendar::from_fixed(cal.to_fixed().day_of_week_after(k))};
233 }
234
236 [[nodiscard]] constexpr CalDate day_of_week_nearest(const DayOfWeek k) const {
237 return {Calendar::from_fixed(cal.to_fixed().day_of_week_nearest(k))};
238 }
239
241 [[nodiscard]] constexpr CalDate day_of_week_on_or_before(const DayOfWeek k) const {
242 return {Calendar::from_fixed(cal.to_fixed().day_of_week_on_or_before(k))};
243 }
244
246 [[nodiscard]] constexpr CalDate day_of_week_on_or_after(const DayOfWeek k) const {
247 return {Calendar::from_fixed(cal.to_fixed().day_of_week_on_or_after(k))};
248 }
249
251 [[nodiscard]] constexpr CalDate first_week_day(const DayOfWeek k) const {
252 return {Calendar::from_fixed(cal.to_fixed().first_week_day(k))};
253 }
254
256 [[nodiscard]] constexpr CalDate last_week_day(const DayOfWeek k) const {
257 return {Calendar::from_fixed(cal.to_fixed().last_week_day(k))};
258 }
259
275 template<IsDayCalendarSystem Other>
276 [[nodiscard]] auto positions_in_range(Allocator &alloc, const CalDate<Other> &end, i32 pthMoment, i32 cDayCycle,
279 cal.to_fixed().positions_in_range(alloc, end.cal.to_fixed(), pthMoment, cDayCycle, delta);
280 if (fixedRes.is_error()) {
281 return fixedRes.error();
282 }
283
284 auto fixedDates = fixedRes.value();
285 mtdefer { fixedDates.deinit(alloc); };
287 if (const auto r = res.init(alloc, fixedDates.size()); r.is_error()) {
288 return r.error();
289 }
290
291 auto iter = fixedDates.iter();
292 Fixed cur = {};
293 while (iter.next().copy_if_present(cur)) {
294 ensure(res.push(CalDate{Calendar::from_fixed(cur)}).is_success());
295 }
296
297 return success(res);
298 }
299
305 [[nodiscard]] i32 day_of_m_cycle(i32 m, i32 offset) const { return cal.to_fixed().day_of_m_cycle(m, offset); }
306
314 [[nodiscard]] auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> CalDate {
315 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_on_or_before(k, m, offset))};
316 }
317
325 [[nodiscard]] auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> CalDate {
326 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_before(k, m, offset))};
327 }
328
336 [[nodiscard]] auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> CalDate {
337 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_on_or_after(k, m, offset))};
338 }
339
347 [[nodiscard]] auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> CalDate {
348 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_after(k, m, offset))};
349 }
350
358 [[nodiscard]] auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> CalDate {
359 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_nearest(k, m, offset))};
360 }
361 };
362
368 template<typename C>
370
371 template<IsDayCalendarSystem Calendar>
372 struct CalDateTime<Calendar> {
373 using CalendarSystem = Calendar;
374 Calendar cal;
376
377 [[nodiscard]] constexpr Segments time_segments() const { return time; }
378
379 [[nodiscard]] constexpr operator CalDate<Calendar>() const noexcept { return CalDate<Calendar>{cal}; }
380
382 [[nodiscard]] constexpr bool is_valid() const { return *this == nearest_valid(); }
383
385 [[nodiscard]] constexpr CalDateTime nearest_valid() const {
386 auto nearestDate = cal.to_fixed().day;
387 auto frac = time.to_fraction_unchecked();
388 if (frac < 0) {
389 nearestDate -= math::floor(frac - 1);
390 }
391 else if (frac > 1) {
392 nearestDate += math::floor(frac + 1);
393 }
394 frac = frac - math::floor(frac);
395 return CalDateTime{Calendar::from_fixed(Fixed{nearestDate}), static_cast<Segments>(DayFraction{frac})};
396 }
397
398 template<typename Other>
399 [[nodiscard]] constexpr operator CalDateTime<Other>() const noexcept {
400 if constexpr (IsDayCalendarSystem<Other>) {
401 return {Other::from_fixed(cal.to_fixed()), time};
402 }
403 else {
404 Moment t = {static_cast<f64>(cal.to_fixed().day) + time.to_fraction_unchecked()};
405 return {Other::from_moment(t)};
406 }
407 }
408
409 template<IsTimeCalendarSystem Other>
410 [[nodiscard]] constexpr std::partial_ordering operator<=>(const CalDateTime<Other> &o) const {
411 if constexpr (std::is_same_v<std::remove_cvref_t<Other>, std::remove_cvref_t<Calendar>>) {
412 if (const std::partial_ordering cmp = cal <=> o.cal; cmp != std::partial_ordering::equivalent) {
413 return cmp;
414 }
415 return time <=> o.time;
416 }
417 else {
418 if (const std::partial_ordering cmp = cal.to_moment() <=> o.cal.to_moment();
419 cmp != std::partial_ordering::equivalent) {
420 return cmp;
421 }
422 return time <=> o.time;
423 }
424 }
425
426 template<IsDayCalendarSystem Other>
427 [[nodiscard]] constexpr std::partial_ordering operator<=>(const CalDateTime<Other> &o) const {
428 if constexpr (std::is_same_v<std::remove_cvref_t<Other>, std::remove_cvref_t<Calendar>>) {
429 if (const std::strong_ordering cmp = cal <=> o.cal; cmp != std::strong_ordering::equivalent) {
430 return cmp;
431 }
432 return time <=> o.time;
433 }
434 else {
435 if (const std::strong_ordering cmp = cal.to_fixed() <=> o.cal.to_fixed();
436 cmp != std::strong_ordering::equivalent) {
437 return cmp;
438 }
439 return time <=> o.time;
440 }
441 }
442
443 template<typename Other>
444 [[nodiscard]] constexpr auto operator==(const CalDateTime<Other> &o) const -> bool {
445 auto cmp = *this <=> o;
446 return cmp == decltype(cmp)::equivalent;
447 }
448 template<typename Other>
449 [[nodiscard]] constexpr auto operator!=(const CalDateTime<Other> &o) const -> bool {
450 auto cmp = *this <=> o;
451 return cmp != decltype(cmp)::equivalent;
452 }
453 template<typename Other>
454 [[nodiscard]] constexpr auto operator<=(const CalDateTime<Other> &o) const -> bool {
455 auto cmp = *this <=> o;
456 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::less;
457 }
458 template<typename Other>
459 [[nodiscard]] constexpr auto operator>=(const CalDateTime<Other> &o) const -> bool {
460 auto cmp = *this <=> o;
461 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::greater;
462 }
463 template<typename Other>
464 [[nodiscard]] constexpr auto operator<(const CalDateTime<Other> &o) const -> bool {
465 auto cmp = *this <=> o;
466 return cmp == decltype(cmp)::less;
467 }
468 template<typename Other>
469 [[nodiscard]] constexpr auto operator>(const CalDateTime<Other> &o) const -> bool {
470 auto cmp = *this <=> o;
471 return cmp == decltype(cmp)::greater;
472 }
473
475 [[nodiscard]] constexpr DayOfWeek day_of_week() const { return cal.to_fixed().day_of_week(); }
476
478 [[nodiscard]] constexpr CalDateTime add_days(const i32 days) const {
479 return {Calendar::from_fixed(cal.to_fixed().add_days(days))};
480 }
481
483 [[nodiscard]] constexpr CalDateTime sub_days(const i32 days) const {
484 return {Calendar::from_fixed(cal.to_fixed().sub_days(days))};
485 }
486
488 template<typename Other>
489 [[nodiscard]] constexpr i32 day_difference(const CalDateTime<Other> &other) const {
490 const auto om = static_cast<CalDateTime<Calendar>>(other);
491 return cal.to_fixed().day_difference(om.cal.to_fixed());
492 }
493
495 [[nodiscard]] constexpr CalDateTime nth_week_day(const i32 n, const DayOfWeek k) const {
496 return {Calendar::from_fixed(cal.to_fixed().nth_week_day(n, k))};
497 }
498
500 [[nodiscard]] constexpr CalDateTime day_of_week_before(const DayOfWeek k) const {
501 return {Calendar::from_fixed(cal.to_fixed().day_of_week_before(k))};
502 }
503
505 [[nodiscard]] constexpr CalDateTime day_of_week_after(const DayOfWeek k) const {
506 return {Calendar::from_fixed(cal.to_fixed().day_of_week_after(k))};
507 }
508
510 [[nodiscard]] constexpr CalDateTime day_of_week_nearest(const DayOfWeek k) const {
511 return {Calendar::from_fixed(cal.to_fixed().day_of_week_nearest(k))};
512 }
513
515 [[nodiscard]] constexpr CalDateTime day_of_week_on_or_before(const DayOfWeek k) const {
516 return {Calendar::from_fixed(cal.to_fixed().day_of_week_on_or_before(k))};
517 }
518
520 [[nodiscard]] constexpr CalDateTime day_of_week_on_or_after(const DayOfWeek k) const {
521 return {Calendar::from_fixed(cal.to_fixed().day_of_week_on_or_after(k))};
522 }
523
525 [[nodiscard]] constexpr CalDateTime first_week_day(const DayOfWeek k) const {
526 return {Calendar::from_fixed(cal.to_fixed().first_week_day(k))};
527 }
528
530 [[nodiscard]] constexpr CalDateTime last_week_day(const DayOfWeek k) const {
531 return {Calendar::from_fixed(cal.to_fixed().last_week_day(k))};
532 }
533
549 template<typename Other>
550 [[nodiscard]] auto positions_in_range(Allocator &alloc, const CalDateTime<Other> &end, i32 pthMoment, i32 cDayCycle,
552 Result<ArrayList<Fixed>, AllocationError> fixedRes = cal.to_fixed().positions_in_range(
553 alloc, static_cast<CalDateTime<Fixed>>(end).cal.to_fixed(), pthMoment, cDayCycle, delta);
554 if (fixedRes.is_error()) {
555 return fixedRes.error();
556 }
557
558 auto fixedDates = fixedRes.value();
559 mtdefer { fixedDates.deinit(alloc); };
561 if (const auto r = res.init(alloc, fixedDates.size()); r.is_error()) {
562 return r.error();
563 }
564
565 auto iter = fixedDates.iter();
566 Fixed cur = {};
567 while (iter.next().copy_if_present(cur)) {
568 ensure(res.push(CalDateTime{Calendar::from_fixed(cur), time}).is_success());
569 }
570
571 return success(res);
572 }
573
579 [[nodiscard]] i32 day_of_m_cycle(i32 m, i32 offset) const { return cal.to_fixed().day_of_m_cycle(m, offset); }
580
588 [[nodiscard]] auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
589 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_on_or_before(k, m, offset)), time};
590 }
591
599 [[nodiscard]] auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
600 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_before(k, m, offset)), time};
601 }
602
610 [[nodiscard]] auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
611 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_on_or_after(k, m, offset)), time};
612 }
613
621 [[nodiscard]] auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
622 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_after(k, m, offset)), time};
623 }
624
632 [[nodiscard]] auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
633 return {Calendar::from_fixed(cal.to_fixed().kth_day_of_m_cycle_nearest(k, m, offset)), time};
634 }
635 };
636
637 template<IsTimeCalendarSystem Calendar>
638 struct CalDateTime<Calendar> {
639 Calendar dateTime;
640
642 [[nodiscard]] constexpr bool is_valid() const { return *this == nearest_valid(); }
643
645 [[nodiscard]] constexpr CalDateTime nearest_valid() const {
646 return CalDateTime{Calendar::from_moment(dateTime.to_moment())};
647 }
648
649 [[nodiscard]] constexpr Segments time_segments() const {
650 const auto m = dateTime.to_moment();
651 const auto df = DayFraction{m - math::floor(m)};
652 return static_cast<Segments>(df);
653 }
654
655 [[nodiscard]] constexpr operator CalDate<Fixed>() const noexcept {
656 return CalDate<Fixed>{{math::floor(dateTime.dayAndTime)}};
657 }
658
659 template<typename Other>
660 [[nodiscard]] constexpr operator CalDateTime<Other>() const noexcept {
661 if constexpr (IsTimeCalendarSystem<Other>) {
662 return {Other::from_moment(dateTime.to_moment()), time};
663 }
664 else {
665 const auto m = dateTime.to_moment();
666 const i32 day = math::floor(dateTime.dayAndTime);
667 const auto dayFrac = DayFraction{m.dayAndTime - math::floor(dateTime.dayAndTime)};
668 return {
669 Other::from_fixed(Fixed{day}),
670 static_cast<Segments>(dayFrac),
671 };
672 }
673 }
674
675 template<IsDayCalendarSystem Other>
676 [[nodiscard]] constexpr std::partial_ordering operator<=>(const CalDateTime<Other> &o) const {
677 const auto om = static_cast<CalDateTime<Calendar>>(o);
678 return *this <=> om;
679 }
680
681 template<IsTimeCalendarSystem Other>
682 [[nodiscard]] constexpr std::partial_ordering operator<=>(const CalDateTime<Other> &o) const {
683 if constexpr (std::is_same_v<std::remove_cvref_t<Other>, std::remove_cvref_t<Calendar>>) {
684 return dateTime <=> o.dateTime;
685 }
686 else {
687 return dateTime.to_moment() <=> o.dateTime.to_moment();
688 }
689 }
690
691 template<typename Other>
692 [[nodiscard]] constexpr auto operator==(const CalDateTime<Other> &o) const -> bool {
693 auto cmp = *this <=> o;
694 return cmp == decltype(cmp)::equivalent;
695 }
696 template<typename Other>
697 [[nodiscard]] constexpr auto operator!=(const CalDateTime<Other> &o) const -> bool {
698 auto cmp = *this <=> o;
699 return cmp != decltype(cmp)::equivalent;
700 }
701 template<typename Other>
702 [[nodiscard]] constexpr auto operator<=(const CalDateTime<Other> &o) const -> bool {
703 auto cmp = *this <=> o;
704 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::less;
705 }
706 template<typename Other>
707 [[nodiscard]] constexpr auto operator>=(const CalDateTime<Other> &o) const -> bool {
708 auto cmp = *this <=> o;
709 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::greater;
710 }
711 template<typename Other>
712 [[nodiscard]] constexpr auto operator<(const CalDateTime<Other> &o) const -> bool {
713 auto cmp = *this <=> o;
714 return cmp == decltype(cmp)::less;
715 }
716 template<typename Other>
717 [[nodiscard]] constexpr auto operator>(const CalDateTime<Other> &o) const -> bool {
718 auto cmp = *this <=> o;
719 return cmp == decltype(cmp)::greater;
720 }
721
723 [[nodiscard]] constexpr DayOfWeek day_of_week() const {
724 return Moment::moment_to_fixed(dateTime.to_moment()).day_of_week();
725 }
726
728 [[nodiscard]] constexpr CalDateTime add_days(const i32 days) const {
729 return {Calendar::from_moment(dateTime.to_moment().add_days(days))};
730 }
731
733 [[nodiscard]] constexpr CalDateTime sub_days(const i32 days) const {
734 return {Calendar::from_moment(dateTime.to_moment().sub_days(days))};
735 }
736
738 template<typename Other>
739 [[nodiscard]] constexpr i32 day_difference(const CalDateTime<Other> &other) const {
740 const auto om = static_cast<CalDateTime<Calendar>>(other);
741 return dateTime.to_moment().day_difference(om.dateTime.to_moment());
742 }
743
745 [[nodiscard]] constexpr CalDateTime nth_week_day(const i32 n, const DayOfWeek k) const {
746 return {Calendar::from_moment(
747 Moment::reconstruct(Moment::moment_to_fixed(dateTime.to_moment()).nth_week_day(n, k), dateTime.to_moment()))};
748 }
749
751 [[nodiscard]] constexpr CalDateTime day_of_week_before(const DayOfWeek k) const {
752 return {Calendar::from_moment(Moment::reconstruct(
753 Moment::moment_to_fixed(dateTime.to_moment()).day_of_week_before(k), dateTime.to_moment()))};
754 }
755
757 [[nodiscard]] constexpr CalDateTime day_of_week_after(const DayOfWeek k) const {
758 return {Calendar::from_moment(
759 Moment::reconstruct(Moment::moment_to_fixed(dateTime.to_moment()).day_of_week_after(k), dateTime.to_moment()))};
760 }
761
763 [[nodiscard]] constexpr CalDateTime day_of_week_nearest(const DayOfWeek k) const {
764 return {Calendar::from_moment(Moment::reconstruct(
765 Moment::moment_to_fixed(dateTime.to_moment()).day_of_week_nearest(k), dateTime.to_moment()))};
766 }
767
769 [[nodiscard]] constexpr CalDateTime day_of_week_on_or_before(const DayOfWeek k) const {
770 return {Calendar::from_moment(Moment::reconstruct(
771 Moment::moment_to_fixed(dateTime.to_moment()).day_of_week_on_or_before(k), dateTime.to_moment()))};
772 }
773
775 [[nodiscard]] constexpr CalDateTime day_of_week_on_or_after(const DayOfWeek k) const {
776 return {Calendar::from_moment(Moment::reconstruct(
777 Moment::moment_to_fixed(dateTime.to_moment()).day_of_week_on_or_after(k), dateTime.to_moment()))};
778 }
779
781 [[nodiscard]] constexpr CalDateTime first_week_day(const DayOfWeek k) const {
782 return {Calendar::from_moment(
783 Moment::reconstruct(Moment::moment_to_fixed(dateTime.to_moment()).first_week_day(k), dateTime.to_moment()))};
784 }
785
787 [[nodiscard]] constexpr CalDateTime last_week_day(const DayOfWeek k) const {
788 return {Calendar::from_moment(
789 Moment::reconstruct(Moment::moment_to_fixed(dateTime.to_moment()).last_week_day(k), dateTime.to_moment()))};
790 }
791
807 template<typename Other>
808 [[nodiscard]] auto positions_in_range(Allocator &alloc, const CalDateTime<Other> &end, i32 pthMoment, i32 cDayCycle,
810 const auto moment = dateTime.to_moment();
811
813 alloc, static_cast<CalDateTime<Fixed>>(end).cal.to_fixed(), pthMoment, cDayCycle, delta);
814 if (fixedRes.is_error()) {
815 return fixedRes.error();
816 }
817
818 auto fixedDates = fixedRes.value();
819 mtdefer { fixedDates.deinit(alloc); };
821 if (const auto r = res.init(alloc, fixedDates.size()); r.is_error()) {
822 return r.error();
823 }
824
825 auto iter = fixedDates.iter();
826 Fixed cur = {};
827 while (iter.next().copy_if_present(cur)) {
828 ensure(res.push(CalDateTime{Calendar::from_moment(Moment::reconstruct(cur, moment))}).is_success());
829 }
830
831 return success(res);
832 }
833
839 [[nodiscard]] i32 day_of_m_cycle(i32 m, i32 offset) const {
840 return Moment::moment_to_fixed(dateTime.to_moment()).day_of_m_cycle(m, offset);
841 }
842
850 [[nodiscard]] auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
851 return {Calendar::from_moment(
852 Moment::reconstruct(Moment::moment_to_fixed(dateTime.to_moment()).kth_day_of_m_cycle_on_or_before(k, m, offset),
853 dateTime.to_moment()))};
854 }
855
863 [[nodiscard]] auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
864 return {Calendar::from_moment(Moment::reconstruct(
865 Moment::moment_to_fixed(dateTime.to_moment()).kth_day_of_m_cycle_before(k, m, offset), dateTime.to_moment()))};
866 }
867
875 [[nodiscard]] auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
876 return {Calendar::from_moment(
877 Moment::reconstruct(Moment::moment_to_fixed(dateTime.to_moment()).kth_day_of_m_cycle_on_or_after(k, m, offset),
878 dateTime.to_moment()))};
879 }
880
888 [[nodiscard]] auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
889 return {Calendar::from_moment(Moment::reconstruct(
890 Moment::moment_to_fixed(dateTime.to_moment()).kth_day_of_m_cycle_after(k, m, offset), dateTime.to_moment()))};
891 }
892
900 [[nodiscard]] auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime {
901 return {Calendar::from_moment(Moment::reconstruct(
902 Moment::moment_to_fixed(dateTime.to_moment()).kth_day_of_m_cycle_nearest(k, m, offset), dateTime.to_moment()))};
903 }
904 };
905
911 template<typename Calendar>
914 using CalendarSystem = Calendar;
917
919 [[nodiscard]] constexpr bool is_valid() const {
920 return zone.try_validate().is_success() && *this == nearest_valid();
921 }
922
924 [[nodiscard]] constexpr CalDateTimeZoned nearest_valid() const {
925 auto nz = zone;
926 nz.offsetVal.hours = std::max<i8>(-23, std::min<i8>(23, zone.offsetVal.hours));
927 nz.offsetVal.minutes = std::max<i8>(-60, std::min<i8>(60, zone.offsetVal.minutes));
928 nz.offsetVal.seconds = std::max<i8>(-60, std::min<i8>(60, zone.offsetVal.seconds));
929 return CalDateTimeZoned{dateTime.nearest_valid(), nz};
930 }
931
932 [[nodiscard]] constexpr operator CalDate<Calendar>() const noexcept { return CalDate<Calendar>{dateTime}; }
933 [[nodiscard]] constexpr operator CalDateTime<Calendar>() const noexcept { return dateTime; }
934 [[nodiscard]] constexpr Segments time_segments() const noexcept { return dateTime.time_segments(); }
935
936 template<typename Other>
937 [[nodiscard]] constexpr operator CalDateTimeZoned<Other>() const noexcept {
938 return {static_cast<CalDateTime<Calendar>>(dateTime), zone};
939 }
940
942 [[nodiscard]] constexpr CalDateTimeZoned to_utc() const noexcept {
943 auto nano = static_cast<i64>(static_cast<NanoSeconds>(time_segments()).nano) - zone.offset_in_nanoseconds();
944 auto c = dateTime;
945 if (nano < 0) {
946 c = dateTime.sub_days(1);
947 nano = NANOS_PER_DAY - nano;
948 }
949 else if (nano >= NANOS_PER_DAY) {
950 c = dateTime.add_days(1);
951 nano = nano - NANOS_PER_DAY;
952 }
953 ensure(nano >= 0);
954 ensure(nano < NANOS_PER_DAY);
955
956 if constexpr (IsDayCalendarSystem<Calendar>) {
957 const auto segZoned = static_cast<Segments>(NanoSeconds{static_cast<u64>(nano)});
958 return CalDateTimeZoned{
959 CalDateTime<Calendar>{c.cal, segZoned},
960 zone,
961 };
962 }
963 else {
964 const auto time = static_cast<DayFraction>(NanoSeconds{static_cast<u64>(nano)});
965 const auto moment = Moment::reconstruct(Moment::moment_to_fixed(c.dateTime.to_moment()), time);
966 return CalDateTimeZoned{CalDateTime<Calendar>{Calendar::from_moment(moment)}, zone};
967 }
968 }
969
971 [[nodiscard]] constexpr CalDateTimeZoned to_timezone(const TimeZone &tz) const noexcept {
972 const auto utc = to_utc();
973 auto nano = static_cast<i64>(static_cast<NanoSeconds>(utc.time_segments()).nano) + tz.offset_in_nanoseconds();
974 auto c = dateTime;
975 if (nano < 0) {
976 c = dateTime.sub_days(1);
977 nano = NANOS_PER_DAY - nano;
978 }
979 else if (nano >= NANOS_PER_DAY) {
980 c = dateTime.add_days(1);
981 nano = nano - NANOS_PER_DAY;
982 }
983 ensure(nano >= 0);
984 ensure(nano < NANOS_PER_DAY);
985
986 if constexpr (IsDayCalendarSystem<Calendar>) {
987 const auto segZoned = static_cast<Segments>(NanoSeconds{static_cast<u64>(nano)});
988 return CalDateTimeZoned{
989 CalDateTime<Calendar>{c, segZoned},
990 zone,
991 };
992 }
993 else {
994 const auto time = static_cast<DayFraction>(NanoSeconds{static_cast<u64>(nano)});
995 const auto moment = Moment::reconstruct(Moment::moment_to_fixed(c.to_moment()), time);
996 return CalDateTimeZoned{CalDateTime<Calendar>{Calendar::from_moment(moment)}, zone};
997 }
998 }
999
1000 template<typename Other>
1001 [[nodiscard]] constexpr std::partial_ordering operator<=>(const CalDateTimeZoned<Other> &o) const {
1002 const auto utc = to_utc();
1003 const auto outc = o.to_utc();
1004 return utc.dateTime <=> outc.dateTime;
1005 }
1006
1007 template<typename Other>
1008 [[nodiscard]] constexpr auto operator==(const CalDateTimeZoned<Other> &o) const -> bool {
1009 auto cmp = *this <=> o;
1010 return cmp == decltype(cmp)::equivalent;
1011 }
1012 template<typename Other>
1013 [[nodiscard]] constexpr auto operator!=(const CalDateTimeZoned<Other> &o) const -> bool {
1014 auto cmp = *this <=> o;
1015 return cmp != decltype(cmp)::equivalent;
1016 }
1017 template<typename Other>
1018 [[nodiscard]] constexpr auto operator<=(const CalDateTimeZoned<Other> &o) const -> bool {
1019 auto cmp = *this <=> o;
1020 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::less;
1021 }
1022 template<typename Other>
1023 [[nodiscard]] constexpr auto operator>=(const CalDateTimeZoned<Other> &o) const -> bool {
1024 auto cmp = *this <=> o;
1025 return cmp == decltype(cmp)::equivalent || cmp == decltype(cmp)::greater;
1026 }
1027 template<typename Other>
1028 [[nodiscard]] constexpr auto operator<(const CalDateTimeZoned<Other> &o) const -> bool {
1029 auto cmp = *this <=> o;
1030 return cmp == decltype(cmp)::less;
1031 }
1032 template<typename Other>
1033 [[nodiscard]] constexpr auto operator>(const CalDateTimeZoned<Other> &o) const -> bool {
1034 auto cmp = *this <=> o;
1035 return cmp == decltype(cmp)::greater;
1036 }
1037
1039 [[nodiscard]] constexpr DayOfWeek day_of_week() const { return dateTime.day_of_week(); }
1040
1042 [[nodiscard]] constexpr CalDateTimeZoned add_days(const i32 days) const { return {dateTime.add_days(days), zone}; }
1043
1045 [[nodiscard]] constexpr CalDateTimeZoned sub_days(const i32 days) const { return {dateTime.sub_days(days), zone}; }
1046
1048 template<typename Other>
1049 [[nodiscard]] constexpr i32 day_difference(const CalDateTimeZoned<Other> &other) const {
1050 return dateTime.day_difference(other.dateTime);
1051 }
1052
1054 [[nodiscard]] constexpr CalDateTimeZoned nth_week_day(const i32 n, const DayOfWeek k) const {
1055 return {dateTime.nth_week_day(n, k), zone};
1056 }
1057
1059 [[nodiscard]] constexpr CalDateTimeZoned day_of_week_before(const DayOfWeek k) const {
1060 return {dateTime.day_of_week_before(k), zone};
1061 }
1062
1064 [[nodiscard]] constexpr CalDateTimeZoned day_of_week_after(const DayOfWeek k) const {
1065 return {dateTime.day_of_week_after(k), zone};
1066 }
1067
1069 [[nodiscard]] constexpr CalDateTimeZoned day_of_week_nearest(const DayOfWeek k) const {
1070 return {dateTime.day_of_week_nearest(k), zone};
1071 }
1072
1074 [[nodiscard]] constexpr CalDateTimeZoned day_of_week_on_or_before(const DayOfWeek k) const {
1075 return {dateTime.day_of_week_on_or_before(k), zone};
1076 }
1077
1079 [[nodiscard]] constexpr CalDateTimeZoned day_of_week_on_or_after(const DayOfWeek k) const {
1080 return {dateTime.day_of_week_on_or_after(k), zone};
1081 }
1082
1084 [[nodiscard]] constexpr CalDateTimeZoned first_week_day(const DayOfWeek k) const {
1085 return {dateTime.first_week_day(k), zone};
1086 }
1087
1089 [[nodiscard]] constexpr CalDateTimeZoned last_week_day(const DayOfWeek k) const {
1090 return {dateTime.last_week_day(k), zone};
1091 }
1092
1108 template<typename Other>
1109 [[nodiscard]] auto positions_in_range(Allocator &alloc, const CalDateTime<Other> &end, i32 pthMoment, i32 cDayCycle,
1111 Result<ArrayList<Fixed>, AllocationError> pos = dateTime.positions_in_range(
1112 alloc, static_cast<CalDateTime<Fixed>>(end).cal.to_fixed(), pthMoment, cDayCycle, delta);
1113 if (pos.is_error()) {
1114 return pos.error();
1115 }
1116
1117 auto dates = pos.value();
1118 mtdefer { dates.deinit(alloc); };
1120 if (const auto r = res.init(alloc, dates.size()); r.is_error()) {
1121 return r.error();
1122 }
1123
1124 auto iter = dates.iter();
1125 CalDateTime<Calendar> cur = {};
1126 while (iter.next().copy_if_present(cur)) {
1127 ensure(res.push(CalDateTimeZoned{cur, zone}).is_success());
1128 }
1129
1130 return success(res);
1131 }
1132
1138 [[nodiscard]] i32 day_of_m_cycle(i32 m, i32 offset) const { return dateTime.day_of_m_cycle(m, offset); }
1139
1147 [[nodiscard]] auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned {
1148 return {dateTime.kth_day_of_m_cycle_on_or_before(k, m, offset), zone};
1149 }
1150
1158 [[nodiscard]] auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned {
1159 return {dateTime.kth_day_of_m_cycle_before(k, m, offset), zone};
1160 }
1161
1169 [[nodiscard]] auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned {
1170 return {dateTime.kth_day_of_m_cycle_on_or_after(k, m, offset), zone};
1171 }
1172
1180 [[nodiscard]] auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned {
1181 return {dateTime.kth_day_of_m_cycle_after(k, m, offset), zone};
1182 }
1183
1191 [[nodiscard]] auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned {
1192 return {dateTime.kth_day_of_m_cycle_nearest(k, m, offset), zone};
1193 }
1194 };
1195
1196 static_assert(IsTimeCalendarSystem<Moment>);
1197 static_assert(IsDayCalendarSystem<Fixed>);
1198
1204 template<typename DateType>
1205 struct Range {
1206 DateType start;
1207 DateType end;
1208
1210 struct Iter {
1211 DateType cur;
1212 DateType end;
1213
1215 if (cur >= end) {
1216 return nullopt;
1217 }
1218 mtdefer { cur = cur.add_days(1); };
1219 return cur;
1220 }
1221 };
1222
1224 auto iter() const { return Iter{start, end}; }
1225
1227 auto size() const {
1228 if (end <= start) {
1229 return 0;
1230 }
1231 return end.day_difference(start);
1232 }
1233 };
1234} // namespace mtcore::calendars
1235
1236#endif // MTCORE_CALENDARS_CORE_HPP
auto operator!=(const AnnoDominiYear &o) const -> bool
auto operator<(const AnnoDominiYear &o) const -> bool
auto operator<=(const AnnoDominiYear &o) const -> bool
AnnoDominiYear operator+(YearBase years) const
auto operator>=(const AnnoDominiYear &o) const -> bool
AnnoDominiYear operator-(YearBase years) const
auto operator<=>(const AnnoDominiYear &o) const -> std::strong_ordering
auto operator==(const AnnoDominiYear &o) const -> bool
auto operator>(const AnnoDominiYear &o) const -> bool
auto operator!=(const AstronomicalYear &o) const -> bool
auto operator>(const AstronomicalYear &o) const -> bool
AstronomicalYear operator+(YearBase years) const
auto operator==(const AstronomicalYear &o) const -> bool
auto operator>=(const AstronomicalYear &o) const -> bool
auto operator<=>(const AstronomicalYear &o) const -> std::strong_ordering
AstronomicalYear operator-(YearBase years) const
auto operator<=(const AstronomicalYear &o) const -> bool
auto operator<(const AstronomicalYear &o) const -> bool
constexpr i64 NANOS_PER_DAY
Number of nanoseconds per day.
DayOfWeek
Enum class for the day of week.
constexpr auto nullopt
Placeholder value for an empty Optional.
Definition optional.hpp:409
AllocationError
Error indicating failed allocation.
#define ensure(check,...)
Ensures that a check holds true, aborts the program if not true Will print error if the condition is ...
#define mtdefer
Defer statement that will mtdefer execution until the scope is left, at which point the code will run...
constexpr R floor(T num) noexcept
Floors a number with support for constexpr and fast runtime compilation.
Success< void > success()
Creates a successful void Result object.
Definition result.hpp:398
constexpr bool is_initable
Checks if a type has an init with the param types.
uint64_t u64
Alias for 64-bit unsigned ints.
int32_t i32
Alias for 32-bit ints.
int64_t i64
Alias for 64-bit ints.
double f64
Alias for 64-bit floats.
constexpr TimeZone utc()
Definition zoned.hpp:88
Namespace for calendaring systems.
Generic iterator defaults built on common contracts Does not guarantee performance of iterators Actua...
Definition iter.hpp:91
Represents a memory allocator Exact behavior depends on the underlying VTable used Should use the a_*...
Array list is a growable, dynamic array with elements inside Elements are stored in an array,...
Result< void, AllocationError > init(Allocator &alloc, size_t initCapacity=10) noexcept
Initializes an empty ArrayList with an initial capacity.
Result< void, AllocationError > push(Allocator &alloc, const Slice< std::add_const_t< T > > &elems) noexcept
Pushes a list of items onto an array list.
Represents a value that may or may not exist (an "Optional" value) Similar concept to std::optional,...
Definition optional.hpp:235
Represents a Result that may have an error (error code) or a success value A type of "void" means the...
Definition result.hpp:170
T value() const noexcept
Checks if is a successful Result (aka.
Definition result.hpp:258
bool is_error() const noexcept
Checks if is an error Result.
Definition result.hpp:266
ErrVal error() const noexcept
Returns the associated error Fails if there is no error;.
Definition result.hpp:294
Wrapper for a date with a time component and timezone.
constexpr CalDateTimeZoned to_timezone(const TimeZone &tz) const noexcept
Convert to a specific timezone.
auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned
Finds the kth day of the m-cycle that occurs before the current date.
constexpr CalDateTimeZoned sub_days(const i32 days) const
Subtracts n days from a date.
auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned
Finds the kth day of the m-cycle that occurs nearest the current date.
constexpr auto operator==(const CalDateTimeZoned< Other > &o) const -> bool
constexpr auto operator>(const CalDateTimeZoned< Other > &o) const -> bool
constexpr CalDateTimeZoned day_of_week_before(const DayOfWeek k) const
Gets the day of week before current date.
auto positions_in_range(Allocator &alloc, const CalDateTime< Other > &end, i32 pthMoment, i32 cDayCycle, i32 delta) const -> Result< ArrayList< CalDateTimeZoned >, AllocationError >
Return the cyclic positions in the range of the current date to the end date (exclusive) Used to coll...
constexpr CalDateTimeZoned nearest_valid() const
Moves the date to the nearest valid date.
constexpr CalDateTimeZoned day_of_week_after(const DayOfWeek k) const
Gets the day of week after the current date.
constexpr CalDateTimeZoned to_utc() const noexcept
Convert to UTC timezone.
constexpr i32 day_difference(const CalDateTimeZoned< Other > &other) const
Difference between two dates in days.
constexpr CalDateTimeZoned nth_week_day(const i32 n, const DayOfWeek k) const
Gets the nth day of week.
constexpr CalDateTimeZoned day_of_week_on_or_before(const DayOfWeek k) const
Gets the day of week on or before the current date.
auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned
Finds the kth day of the m-cycle that occurs on or after the current date.
constexpr Segments time_segments() const noexcept
constexpr CalDateTimeZoned day_of_week_on_or_after(const DayOfWeek k) const
Gets the day of week on or after the current date.
constexpr CalDateTimeZoned add_days(const i32 days) const
Adds n days to a date.
auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned
Finds the kth day of the m-cycle that occurs after the current date.
constexpr bool is_valid() const
Checks that a date is valid.
constexpr CalDateTimeZoned first_week_day(const DayOfWeek k) const
Gets the first week day in a month (assuming current date is the start of the month)
constexpr auto operator>=(const CalDateTimeZoned< Other > &o) const -> bool
constexpr CalDateTimeZoned day_of_week_nearest(const DayOfWeek k) const
Gets the day of week nearest to the current date.
constexpr auto operator<=(const CalDateTimeZoned< Other > &o) const -> bool
constexpr DayOfWeek day_of_week() const
Gets the day of week for a date.
constexpr auto operator<(const CalDateTimeZoned< Other > &o) const -> bool
constexpr auto operator!=(const CalDateTimeZoned< Other > &o) const -> bool
auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTimeZoned
Finds the kth day of the m-cycle that occurs on or before the current date.
i32 day_of_m_cycle(i32 m, i32 offset) const
Gets which day the current date occurs in an m-length ("month") cycle.
constexpr std::partial_ordering operator<=>(const CalDateTimeZoned< Other > &o) const
constexpr CalDateTimeZoned last_week_day(const DayOfWeek k) const
Gets the last week day in a month (assuming current date is the end of the month)
constexpr DayOfWeek day_of_week() const
Gets the day of week for a date.
constexpr auto operator>(const CalDateTime< Other > &o) const -> bool
i32 day_of_m_cycle(i32 m, i32 offset) const
Gets which day the current date occurs in an m-length ("month") cycle.
auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime
Finds the kth day of the m-cycle that occurs on or after the current date.
constexpr CalDateTime day_of_week_before(const DayOfWeek k) const
Gets the day of week before current date.
auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime
Finds the kth day of the m-cycle that occurs nearest the current date.
auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime
Finds the kth day of the m-cycle that occurs before the current date.
constexpr i32 day_difference(const CalDateTime< Other > &other) const
Difference between two dates in days.
constexpr CalDateTime sub_days(const i32 days) const
Subtracts n days from a date.
constexpr std::partial_ordering operator<=>(const CalDateTime< Other > &o) const
constexpr bool is_valid() const
Checks that a date is valid.
constexpr CalDateTime day_of_week_on_or_after(const DayOfWeek k) const
Gets the day of week on or after the current date.
constexpr auto operator<(const CalDateTime< Other > &o) const -> bool
constexpr auto operator<=(const CalDateTime< Other > &o) const -> bool
constexpr CalDateTime nearest_valid() const
Moves the date to the nearest valid date.
constexpr auto operator>=(const CalDateTime< Other > &o) const -> bool
auto positions_in_range(Allocator &alloc, const CalDateTime< Other > &end, i32 pthMoment, i32 cDayCycle, i32 delta) const -> Result< ArrayList< CalDateTime >, AllocationError >
Return the cyclic positions in the range of the current date to the end date (exclusive) Used to coll...
auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime
Finds the kth day of the m-cycle that occurs after the current date.
constexpr CalDateTime day_of_week_nearest(const DayOfWeek k) const
Gets the day of week nearest to the current date.
constexpr CalDateTime nth_week_day(const i32 n, const DayOfWeek k) const
Gets the nth day of week.
constexpr CalDateTime first_week_day(const DayOfWeek k) const
Gets the first week day in a month (assuming current date is the start of the month)
constexpr CalDateTime day_of_week_after(const DayOfWeek k) const
Gets the day of week after the current date.
constexpr auto operator==(const CalDateTime< Other > &o) const -> bool
constexpr CalDateTime add_days(const i32 days) const
Adds n days to a date.
auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> CalDateTime
Finds the kth day of the m-cycle that occurs on or before the current date.
constexpr auto operator!=(const CalDateTime< Other > &o) const -> bool
constexpr CalDateTime last_week_day(const DayOfWeek k) const
Gets the last week day in a month (assuming current date is the end of the month)
constexpr CalDateTime day_of_week_on_or_before(const DayOfWeek k) const
Gets the day of week on or before the current date.
Wrapper for a date with a time component.
Represents a date without a time component.
auto positions_in_range(Allocator &alloc, const CalDate< Other > &end, i32 pthMoment, i32 cDayCycle, i32 delta) const -> Result< ArrayList< CalDate >, AllocationError >
Return the cyclic positions in the range of the current date to the end date (exclusive) Used to coll...
constexpr CalDate first_week_day(const DayOfWeek k) const
Gets the first week day in a month (assuming current date is the start of the month)
constexpr CalDate day_of_week_nearest(const DayOfWeek k) const
Gets the day of week nearest to the current date.
constexpr CalDate add_days(const i32 days) const
Adds days to a date.
constexpr auto operator<=(const CalDate< Other > &o) const -> bool
auto kth_day_of_m_cycle_before(i32 k, i32 m, i32 offset) const noexcept -> CalDate
Finds the kth day of the m-cycle that occurs before the current date.
CalDate(const CalDate &)=default
constexpr CalDate day_of_week_on_or_after(const DayOfWeek k) const
Gets the day of week on or after the current date.
constexpr auto operator<=>(const CalDate< Other > &o) const
Compares dates between two different calendar systems.
constexpr auto operator<(const CalDate< Other > &o) const -> bool
constexpr auto operator>(const CalDate< Other > &o) const -> bool
auto kth_day_of_m_cycle_after(i32 k, i32 m, i32 offset) const noexcept -> CalDate
Finds the kth day of the m-cycle that occurs after the current date.
auto kth_day_of_m_cycle_on_or_after(i32 k, i32 m, i32 offset) const noexcept -> CalDate
Finds the kth day of the m-cycle that occurs on or after the current date.
auto kth_day_of_m_cycle_nearest(i32 k, i32 m, i32 offset) const noexcept -> CalDate
Finds the kth day of the m-cycle that occurs nearest the current date.
CalDate & operator=(const CalDate &)=default
constexpr CalDate nearest_valid() const
Moves the date to the nearest valid date.
constexpr auto operator==(const CalDate< Other > &o) const -> bool
CalDate & operator=(CalDate &&)=default
constexpr CalDate day_of_week_after(const DayOfWeek k) const
Gets the day of week after the current date.
static constexpr CalDate make(Args... args)
constexpr auto operator!=(const CalDate< Other > &o) const -> bool
constexpr CalDate nth_week_day(const i32 n, const DayOfWeek k) const
Gets the nth day of week.
constexpr bool is_valid() const
Checks that a date is valid.
i32 day_of_m_cycle(i32 m, i32 offset) const
Gets which day the current date occurs in an m-length ("month") cycle.
constexpr DayOfWeek day_of_week() const
Gets the day of week for a calendar.
auto kth_day_of_m_cycle_on_or_before(i32 k, i32 m, i32 offset) const noexcept -> CalDate
Finds the kth day of the m-cycle that occurs on or before the current date.
constexpr CalDate day_of_week_on_or_before(const DayOfWeek k) const
Gets the day of week on or before the current date.
constexpr CalDate & init(Args... args)
CalDate(CalDate &&)=default
constexpr CalDate day_of_week_before(const DayOfWeek k) const
Gets the day of week before current date.
constexpr auto operator>=(const CalDate< Other > &o) const -> bool
constexpr CalDate last_week_day(const DayOfWeek k) const
Gets the last week day in a month (assuming current date is the end of the month)
constexpr i32 day_difference(const CalDate< Other > &other) const
Gets the difference in days between dates.
constexpr CalDate sub_days(const i32 days) const
Subtracts days from a date.
Base calendar system tracking the number of days since its epoch.
Definition fixed.hpp:42
auto positions_in_range(Allocator &alloc, const Fixed &end, i32 pthMoment, i32 cDayCycle, i32 delta) const -> Result< mtcore::ArrayList< Fixed >, AllocationError >
Return the cyclic positions in the range of the current date to the end date (exclusive) Used to coll...
Definition fixed.hpp:161
constexpr i32 day_of_m_cycle(i32 m, i32 offset) const
Gets which day the current date occurs in an m-length ("month") cycle.
Definition fixed.hpp:185
constexpr DayOfWeek day_of_week() const
Gets the day of week for a date.
Definition fixed.hpp:83
Base calendar system tracking the number of days (and fraction of days) since its epoch.
Definition fixed.hpp:264
static constexpr Moment reconstruct(const Fixed &f, const Moment &m)
Reconstructs a moment from a fixed date and the time portion of a moment.
Definition fixed.hpp:286
static constexpr Fixed moment_to_fixed(const Moment &m)
Converts a moment to fixed date (drops time)
Definition fixed.hpp:281
Range of dates with start and end.
Represents time in segments (hour, minute, etc.).