cxWidgets 1.0
cxDate.h
Go to the documentation of this file.
1// Copyright (c) 2026 E. Oulashin
2#ifndef __CXDATE_H__
3#define __CXDATE_H__
4
5// Copyright (c) 2007 Eric Oulashin
6//
7// cxDate.h - C++17-improved date class for the cxWidgets library.
8// This is a modernized version of the original 'date' class (date.h/date.cpp),
9// renamed to cxDate to follow cxWidgets naming conventions, and updated to use
10// C++17 standard features throughout.
11//
12// Changes from the original 'date' class:
13// - Class renamed from 'date' to 'cxDate'
14// - [[nodiscard]] attributes added to accessor/query methods
15// - noexcept specifications added to non-throwing methods
16// - std::string_view used for read-only string parameters
17// - std::optional<cxDate> returned by tryParse() for safe parsing
18// - std::chrono used in today() for current date retrieval
19// - std::stoi() replaces atoi() for safer string-to-int conversion
20// - std::to_string() replaces the custom anythingToString<T>() template
21// - inline constexpr replaces #define for numeric constants
22// - static cxDate today() added as a clear, expressive convenience method
23// - Default member initializers used in the class definition
24// - = default used for copy constructor, copy assignment, and destructor
25// - std::clamp used for range-clamping in validateDateElements()
26
27#include <string>
28#include <string_view>
29#include <iostream>
30#include <optional>
31
32namespace cx {
33
34// Date format enumeration (kept compatible with original date.h)
51
62
63// C++17: inline constexpr replaces #define for compile-time constants
64inline constexpr int CXDATE_DEFAULT_YEAR = 2000;
65inline constexpr int CXDATE_YEAR_2DIGIT_LAST_CENT = 49;
66inline constexpr int CXDATE_MONTHS_IN_YEAR = 12;
67inline constexpr int CXDATE_START_MONTH = 1;
68inline constexpr int CXDATE_END_MONTH = 12;
69inline constexpr int CXDATE_START_DAY = 1;
70inline constexpr int CXDATE_YEAR_MIN = 1800;
71inline constexpr int CXDATE_YEAR_MAX = 2500;
72
83class cxDate
84{
85public:
86 // -----------------------------------------------------------------------
87 // Constructors / Destructor
88 // -----------------------------------------------------------------------
89
91 explicit cxDate(eDateFormats pDateFormat = YYYY_MM_DD, char pSepChar = '-');
92
94 cxDate(int pYear, int pMonth, int pDay,
95 eDateFormats pDateFormat = YYYY_MM_DD,
96 char pSepChar = '-') noexcept;
97
99 cxDate(std::string_view pDateStr,
100 eDateFormats pDateFormat = YYYY_MM_DD,
101 char pSepChar = '-');
102
104 cxDate(std::string_view pDateStr, char pSepChar);
105
107 cxDate(long pJulianDate,
108 eDateFormats pDateFormat = YYYY_MM_DD,
109 char pSepChar = '-') noexcept;
110
111 virtual ~cxDate() = default;
112 cxDate(const cxDate&) = default;
113 cxDate& operator=(const cxDate&) = default;
114
115 // -----------------------------------------------------------------------
116 // Accessors (all [[nodiscard]] and noexcept)
117 // -----------------------------------------------------------------------
118
120 [[nodiscard]] int getYear() const noexcept
121 {
122 return mYear;
123 }
125 [[nodiscard]] int getMonth() const noexcept
126 {
127 return mMonth;
128 }
130 [[nodiscard]] int getDay() const noexcept
131 {
132 return mDay;
133 }
135 [[nodiscard]] eDateFormats getDateFormat() const noexcept
136 {
137 return mDateFormat;
138 }
140 [[nodiscard]] char getSepChar() const noexcept
141 {
142 return mSepChar;
143 }
145 [[nodiscard]] bool getDisplayLong() const noexcept
146 {
147 return mDisplayLong;
148 }
149
150 // -----------------------------------------------------------------------
151 // Mutators
152 // -----------------------------------------------------------------------
153
155 void setYear(int pYear) noexcept;
157 void setMonth(int pMonth) noexcept;
159 void setDay(int pDay) noexcept;
161 void setDateFormat(eDateFormats pDateFormat) noexcept;
163 void setSepChar(char pSepChar) noexcept
164 {
165 mSepChar = pSepChar;
166 }
168 void setDisplayLong(bool pDisplay) noexcept
169 {
170 mDisplayLong = pDisplay;
171 }
172
177 [[nodiscard]] bool setDate(int pYear, int pMonth, int pDay) noexcept;
178
179 // -----------------------------------------------------------------------
180 // Date arithmetic
181 // -----------------------------------------------------------------------
182
184 void addYears(int pNumYears) noexcept;
186 void subtractYears(int pNumYears) noexcept;
188 void addMonths(int pNumMonths) noexcept;
190 void subtractMonths(int pNumMonths) noexcept;
192 void addDays(int pNumDays) noexcept;
194 void subtractDays(int pNumDays) noexcept;
195
196 // -----------------------------------------------------------------------
197 // Operators
198 // -----------------------------------------------------------------------
199
201 void operator+=(int pNumDays) noexcept;
203 void operator-=(int pNumDays) noexcept;
204
206 [[nodiscard]] bool operator==(const cxDate& pThat) const noexcept;
208 [[nodiscard]] bool operator!=(const cxDate& pThat) const noexcept;
210 [[nodiscard]] bool operator> (const cxDate& pThat) const noexcept;
212 [[nodiscard]] bool operator>=(const cxDate& pThat) const noexcept;
214 [[nodiscard]] bool operator< (const cxDate& pThat) const noexcept;
216 [[nodiscard]] bool operator<=(const cxDate& pThat) const noexcept;
217
218 cxDate operator++(int) noexcept; // post-increment (advance one day)
219 cxDate& operator++() noexcept; // pre-increment (advance one day)
220 cxDate operator--(int) noexcept; // post-decrement (go back one day)
221 cxDate& operator--() noexcept; // pre-decrement (go back one day)
222
224 [[nodiscard]] cxDate operator+(int pNumDays) const noexcept;
226 [[nodiscard]] cxDate operator-(int pNumDays) const noexcept;
228 [[nodiscard]] int operator-(const cxDate& pThat) const noexcept;
229
231 friend std::ostream& operator<<(std::ostream& pOS, const cxDate& pDate);
233 friend std::istream& operator>>(std::istream& pIS, cxDate& pDate);
234
235 // -----------------------------------------------------------------------
236 // String conversion
237 // -----------------------------------------------------------------------
238
240 [[nodiscard]] std::string toString() const;
245 bool fromString(std::string_view pDateStr);
246
247 // -----------------------------------------------------------------------
248 // Utility
249 // -----------------------------------------------------------------------
250
252 [[nodiscard]] int numMonthDays() const noexcept;
254 [[nodiscard]] bool isLeapYear() const noexcept;
256 [[nodiscard]] eWeekDays dayOfWeek() const noexcept;
258 [[nodiscard]] std::string dayOfWeekStr() const;
259
260 // -----------------------------------------------------------------------
261 // Static methods
262 // -----------------------------------------------------------------------
263
268 [[nodiscard]] static int numMonthDays(int pMonth, int pYear) noexcept;
270 [[nodiscard]] static bool isLeapYear(int pYear) noexcept;
272 [[nodiscard]] static eWeekDays dayOfWeek(int pYear, int pMonth, int pDay) noexcept;
274 [[nodiscard]] static std::string dayOfWeekStr(eWeekDays pWeekDay);
276 [[nodiscard]] static std::string dayOfWeekStr(int pYear, int pMonth, int pDay);
281 [[nodiscard]] static std::string monthName(int pMonth, bool pAbbreviated = false);
282
284 [[nodiscard]] static std::string getToday(bool pLong = false);
286 [[nodiscard]] static int getCurrentYear() noexcept;
287
292 [[nodiscard]] static cxDate today() noexcept;
293
299 [[nodiscard]] static std::optional<cxDate> tryParse(
300 std::string_view pDateStr,
301 eDateFormats pDateFormat = YYYY_MM_DD,
302 char pSepChar = '-');
303
304 // -----------------------------------------------------------------------
305 // Julian date conversions
306 // -----------------------------------------------------------------------
307
309 [[nodiscard]] long toJulian() const noexcept;
311 static long toJulian(int pYear, int pMonth, int pDay) noexcept;
313 void fromJulian(long pJulianDate) noexcept;
315 static void fromJulian(long pJulianDate, int& pYear, int& pMonth, int& pDay) noexcept;
316
317 // -----------------------------------------------------------------------
318 // Date format detection
319 // -----------------------------------------------------------------------
320
322 [[nodiscard]] static eDateFormats getDateFormat(std::string_view pDateStr);
324 [[nodiscard]] static std::string getDateFormatStr(eDateFormats pDateFormat);
325
326 // -----------------------------------------------------------------------
327 // Calendar output
328 // -----------------------------------------------------------------------
329
334 static void monthCalendar(int pYear, int pMonth,
335 std::ostream& pOutStream = std::cout,
336 int pTrailingEndlines = 2);
341 static void yearCalendar(int pYear,
342 std::ostream& pOutStream = std::cout,
343 int pTrailingEndlines = 2);
344
345private:
346 int mYear = CXDATE_DEFAULT_YEAR;
347 int mMonth = 1;
348 int mDay = 1;
349 eDateFormats mDateFormat = YYYY_MM_DD;
350 char mSepChar = '-';
351 bool mDisplayLong = false;
352
353 // Validates and clamps month/day to legal ranges.
354 // Returns true if all values were already valid.
355 static bool validateDateElements(int pYear, int& pMonth, int& pDay) noexcept;
356
357 [[nodiscard]] static std::string getMonthName(int pMonth);
358 [[nodiscard]] static bool allDigits(std::string_view pStr) noexcept;
359};
360
361} // namespace cx
362
363#endif // __CXDATE_H__
Enables easy management of dates. C++17-enhanced version of the original 'date' class.
Definition cxDate.h:84
void operator-=(int pNumDays) noexcept
Definition cxDate.cpp:221
bool fromString(std::string_view pDateStr)
Definition cxDate.cpp:390
int numMonthDays() const noexcept
Definition cxDate.cpp:516
long toJulian() const noexcept
Definition cxDate.cpp:667
void fromJulian(long pJulianDate) noexcept
Definition cxDate.cpp:683
virtual ~cxDate()=default
void subtractMonths(int pNumMonths) noexcept
Definition cxDate.cpp:172
cxDate & operator=(const cxDate &)=default
eWeekDays dayOfWeek() const noexcept
Definition cxDate.cpp:526
void setMonth(int pMonth) noexcept
Definition cxDate.cpp:108
char getSepChar() const noexcept
Definition cxDate.h:140
void setSepChar(char pSepChar) noexcept
Definition cxDate.h:163
static void monthCalendar(int pYear, int pMonth, std::ostream &pOutStream=std::cout, int pTrailingEndlines=2)
Definition cxDate.cpp:786
int getDay() const noexcept
Definition cxDate.h:130
bool operator>(const cxDate &pThat) const noexcept
Definition cxDate.cpp:234
bool operator<=(const cxDate &pThat) const noexcept
Definition cxDate.cpp:248
bool operator!=(const cxDate &pThat) const noexcept
Definition cxDate.cpp:230
int getMonth() const noexcept
Definition cxDate.h:125
void addYears(int pNumYears) noexcept
Definition cxDate.cpp:145
static std::string getToday(bool pLong=false)
Definition cxDate.cpp:607
bool isLeapYear() const noexcept
Definition cxDate.cpp:521
bool operator==(const cxDate &pThat) const noexcept
Definition cxDate.cpp:226
bool operator>=(const cxDate &pThat) const noexcept
Definition cxDate.cpp:240
cxDate & operator++() noexcept
Definition cxDate.cpp:259
std::string dayOfWeekStr() const
Definition cxDate.cpp:531
static std::optional< cxDate > tryParse(std::string_view pDateStr, eDateFormats pDateFormat=YYYY_MM_DD, char pSepChar='-')
Definition cxDate.cpp:651
void setYear(int pYear) noexcept
Definition cxDate.cpp:102
static cxDate today() noexcept
Definition cxDate.cpp:646
void subtractDays(int pNumDays) noexcept
Definition cxDate.cpp:208
void addMonths(int pNumMonths) noexcept
Definition cxDate.cpp:156
bool setDate(int pYear, int pMonth, int pDay) noexcept
Definition cxDate.cpp:128
void setDisplayLong(bool pDisplay) noexcept
Definition cxDate.h:168
bool getDisplayLong() const noexcept
Definition cxDate.h:145
void subtractYears(int pNumYears) noexcept
Definition cxDate.cpp:151
static std::string getDateFormatStr(eDateFormats pDateFormat)
Definition cxDate.cpp:762
cxDate(const cxDate &)=default
void setDateFormat(eDateFormats pDateFormat) noexcept
Definition cxDate.cpp:120
static int getCurrentYear() noexcept
Definition cxDate.cpp:633
eDateFormats getDateFormat() const noexcept
Definition cxDate.h:135
static std::string monthName(int pMonth, bool pAbbreviated=false)
Definition cxDate.cpp:593
void addDays(int pNumDays) noexcept
Definition cxDate.cpp:177
std::string toString() const
Definition cxDate.cpp:383
bool operator<(const cxDate &pThat) const noexcept
Definition cxDate.cpp:244
static void yearCalendar(int pYear, std::ostream &pOutStream=std::cout, int pTrailingEndlines=2)
Definition cxDate.cpp:823
void operator+=(int pNumDays) noexcept
Definition cxDate.cpp:217
int getYear() const noexcept
Definition cxDate.h:120
void setDay(int pDay) noexcept
Definition cxDate.cpp:114
cxBorderChars.h - Defines border characters to be used in drawing a box (i.e., in cxWindow and all it...
Definition cxApp.cpp:5
constexpr int CXDATE_START_MONTH
Definition cxDate.h:67
constexpr int CXDATE_YEAR_MAX
Definition cxDate.h:71
eDateFormats
Definition cxDate.h:36
@ DDMMYY
Definition cxDate.h:48
@ MMDDYYYY
Definition cxDate.h:44
@ MM_DD_YYYY
Definition cxDate.h:38
@ YYYY_MM_DD
Definition cxDate.h:37
@ DD_MM_YY
Definition cxDate.h:42
@ UNKNOWN
Definition cxDate.h:49
@ DDMMYYYY
Definition cxDate.h:45
@ DD_MM_YYYY
Definition cxDate.h:39
@ MM_DD_YY
Definition cxDate.h:41
@ MMDDYY
Definition cxDate.h:47
@ YYYYMMDD
Definition cxDate.h:43
@ YYMMDD
Definition cxDate.h:46
@ YY_MM_DD
Definition cxDate.h:40
constexpr int CXDATE_YEAR_2DIGIT_LAST_CENT
Definition cxDate.h:65
constexpr int CXDATE_END_MONTH
Definition cxDate.h:68
eWeekDays
Definition cxDate.h:53
@ eSATURDAY
Definition cxDate.h:60
@ eTUESDAY
Definition cxDate.h:56
@ eMONDAY
Definition cxDate.h:55
@ eSUNDAY
Definition cxDate.h:54
@ eFRIDAY
Definition cxDate.h:59
@ eTHURSDAY
Definition cxDate.h:58
@ eWEDNESDAY
Definition cxDate.h:57
constexpr int CXDATE_DEFAULT_YEAR
Definition cxDate.h:64
constexpr int CXDATE_START_DAY
Definition cxDate.h:69
constexpr int CXDATE_MONTHS_IN_YEAR
Definition cxDate.h:66
constexpr int CXDATE_YEAR_MIN
Definition cxDate.h:70