HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
date.hpp
1// Copyright Take Vos 2019.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "assert.hpp"
8#include <date/date.h>
9#include <format>
10#include <string>
11#include <compare>
12
13namespace hi::inline v1 {
14
15[[nodiscard]] std::string to_string(std::chrono::year y) noexcept
16{
17 return std::format("{}", static_cast<int>(y));
18}
19
20class quarter {
21 unsigned int q;
22
23public:
24 explicit constexpr quarter(std::chrono::month m) noexcept : q(((static_cast<unsigned>(m) - 1) / 3) + 1) {}
25
26 [[nodiscard]] explicit constexpr operator unsigned() const noexcept
27 {
28 return q;
29 }
30
31 [[nodiscard]] constexpr std::chrono::month first_month() const noexcept
32 {
33 return std::chrono::month{((q - 1) * 3) + 1};
34 }
35
36 [[nodiscard]] constexpr std::chrono::month last_month() const noexcept
37 {
38 return first_month() + std::chrono::months{2};
39 }
40
41 [[nodiscard]] constexpr std::chrono::month_day first() const noexcept
42 {
43 return std::chrono::month_day{first_month(), std::day{1}};
44 }
45
46 [[nodiscard]] constexpr std::chrono::month_day last() const noexcept
47 {
48 switch (q) {
49 case 1: return std::chrono::month_day{last_month(), std::day{31}};
50 case 2: return std::chrono::month_day{last_month(), std::day{30}};
51 case 3: return std::chrono::month_day{last_month(), std::day{30}};
52 case 4: return std::chrono::month_day{last_month(), std::day{31}};
53 default: hi_no_default();
54 }
55 }
56
57 [[nodiscard]] constexpr bool increment_carry() noexcept
58 {
59 if (++q > 4) {
60 q = 1;
61 return true;
62 } else {
63 return false;
64 }
65 }
66
67 [[nodiscard]] bool contains(std::chrono::month_day const &md) const noexcept
68 {
69 return md >= first() && md <= last();
70 }
71
72 [[nodiscard]] friend constexpr bool operator==(quarter const &lhs, quarter const &rhs) noexcept
73 {
74 return lhs.q == rhs.q;
75 }
76
77 [[nodiscard]] friend constexpr auto operator<=>(quarter const &lhs, quarter const &rhs) noexcept
78 {
79 return lhs.q <=> rhs.q;
80 }
81
82 [[nodiscard]] friend std::string to_string(quarter const &rhs) noexcept
83 {
84 return std::format("{}", rhs.q);
85 }
86
87 friend std::ostream &operator<<(std::ostream &lhs, quarter const &rhs) noexcept
88 {
89 return lhs << to_string(rhs);
90 }
91};
92
94 std::chrono::year y;
95 quarter q;
96
97public:
98 explicit constexpr year_quarter(std::chrono::year_month const &ym) : y(ym.year()), q(ym.month()) {}
99
100 explicit constexpr year_quarter(std::chrono::year_month_day const &ymd) :
101 year_quarter(std::chrono::year_month{ymd.year(), ymd.month()})
102 {
103 }
104
105 constexpr year_quarter &operator++() noexcept
106 {
107 if (q.increment_carry()) {
108 ++y;
109 }
110 return *this;
111 }
112
113 [[nodiscard]] constexpr std::chrono::year_month first_year_month() noexcept
114 {
115 return std::chrono::year_month{y, q.first_month()};
116 }
117
118 [[nodiscard]] constexpr std::chrono::year_month last_year_month() noexcept
119 {
120 return std::chrono::year_month{y, q.last_month()};
121 }
122
123 [[nodiscard]] constexpr std::chrono::year_month_day first() noexcept
124 {
125 hilet md = q.first();
126 return std::chrono::year_month_day{y, md.month(), md.day()};
127 }
128
129 [[nodiscard]] constexpr std::chrono::year_month_day last() noexcept
130 {
131 hilet md = q.last();
132 return std::chrono::year_month_day{y, md.month(), md.day()};
133 }
134
135 [[nodiscard]] bool contains(std::chrono::year_month_day const &ymd) const noexcept
136 {
137 return y == ymd.year() && q.contains(std::chrono::month_day(ymd.month(), ymd.day()));
138 }
139
140 [[nodiscard]] friend constexpr bool operator==(year_quarter const &lhs, year_quarter const &rhs) noexcept = default;
141 [[nodiscard]] friend constexpr std::strong_ordering operator<=>(year_quarter const &lhs, year_quarter const &rhs) noexcept = default;
142
143
144 [[nodiscard]] friend std::string to_string(year_quarter const &rhs) noexcept
145 {
146 return std::format("{}Q{}", rhs.y, rhs.q);
147 }
148
149 friend std::ostream &operator<<(std::ostream &lhs, year_quarter const &rhs) noexcept
150 {
151 return lhs << to_string(rhs);
152 }
153};
154
155} // namespace hi::inline v1
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
Definition date.hpp:20
Definition date.hpp:93
T to_string(T... args)