E-MailRelay
gdatetime.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gdatetime.h
19///
20
21#ifndef G_DATE_TIME_H
22#define G_DATE_TIME_H
23
24#include "gdef.h"
25#include "gexception.h"
26#include <chrono>
27#include <vector>
28#include <string>
29#include <iostream>
30
31namespace G
32{
33 class DateTime ;
34 class SystemTime ;
35 class TimerTime ;
36 class TimeInterval ;
37 class BrokenDownTime ;
38 class DateTimeTest ;
39}
40
41//| \class G::BrokenDownTime
42/// An encapsulation of 'struct std::tm'.
43///
45{
46public:
47 explicit BrokenDownTime( const struct std::tm & ) ;
48 ///< Constructor.
49
50 BrokenDownTime( int year , int month , int day , int hh , int mm , int ss ) ;
51 ///< Constructor.
52
53 static BrokenDownTime null() ;
54 ///< Factory function for an unusable object with bogus
55 ///< component values.
56
57 static BrokenDownTime midday( int year , int month , int day ) ;
58 ///< Factory function for midday on the given date.
59
60 static BrokenDownTime midnight( int year , int month , int day ) ;
61 ///< Factory function for midnight starting the given date.
62
64 ///< Factory function for the locale-dependent local broken-down
65 ///< time of the given epoch time. See also SystemTime::local().
66
67 static BrokenDownTime utc( SystemTime ) ;
68 ///< Factory function for the utc broken-down time of the given
69 ///< epoch time. See also SystemTime::utc().
70
71 bool format( char * out , std::size_t out_size , const char * fmt ) const ;
72 ///< Puts the formatted date, including a terminating null character,
73 ///< into the given output buffer. Returns false if the output buffer
74 ///< is too small. Only simple non-locale-dependent format specifiers
75 ///< are allowed, and these allowed specifiers explicitly exclude
76 ///< '%z' and '%Z'.
77
78 void format( std::vector<char> & out , const char * fmt ) const ;
79 ///< Overload for an output vector. Throws if the vector is
80 ///< too small for the result (with its null terminator).
81
82 std::string str( const char * fmt ) const ;
83 ///< Returns the formatted date, with the same restrictions
84 ///< as format().
85
86 std::string str() const ;
87 ///< Returns str() using a "%F %T" format.
88
89 int year() const ;
90 ///< Returns the four-digit year value.
91
92 int month() const ;
93 ///< Returns the 1..12 month value.
94
95 int day() const ;
96 ///< Returns the 1..31 month-day value.
97
98 int hour() const ;
99 ///< Returns the 0..23 hour value.
100
101 int min() const ;
102 ///< Returns the 0..59 minute value.
103
104 int sec() const ;
105 ///< Returns the 0..59 or 0..60 seconds value.
106
107 int wday() const ;
108 ///< Returns week day where sunday=0 and saturday=6.
109
110 std::time_t epochTimeFromUtc() const ;
111 ///< Converts this utc broken-down time into epoch time.
112
113 std::time_t epochTimeFromLocal() const ;
114 ///< Uses std::mktime() to convert this locale-dependent
115 ///< local broken-down time into epoch time.
116
117 bool sameMinute( const BrokenDownTime & ) const noexcept ;
118 ///< Returns true if this and the other broken-down
119 ///< times are the same, at minute resolution with
120 ///< no rounding.
121
122 bool operator==( const BrokenDownTime & ) const noexcept ;
123 ///< Equality test.
124
125 bool operator!=( const BrokenDownTime & ) const noexcept ;
126 ///< Inequality test.
127
128private:
130
131private:
132 friend class G::DateTimeTest ;
133 struct std::tm m_tm {} ;
134} ;
135
136//| \class G::SystemTime
137/// Represents a unix-epoch time with microsecond resolution.
138///
140{
141public:
142 static SystemTime now() ;
143 ///< Factory function for the current time.
144
145 static SystemTime zero() ;
146 ///< Factory function for the start of the epoch.
147
148 explicit SystemTime( std::time_t , unsigned long us = 0UL ) noexcept ;
149 ///< Constructor. The first parameter should be some
150 ///< large positive number. The second parameter can be
151 ///< more than 10^6.
152
153 bool isZero() const ;
154 ///< Returns true if zero().
155
156 bool sameSecond( const SystemTime & other ) const noexcept ;
157 ///< Returns true if this time and the other time are the same,
158 ///< at second resolution.
159
160 BrokenDownTime local() const ;
161 ///< Returns the locale-dependent local broken-down time.
162
163 BrokenDownTime utc() const ;
164 ///< Returns the utc broken-down time.
165
166 unsigned int ms() const ;
167 ///< Returns the millisecond fraction.
168
169 unsigned int us() const ;
170 ///< Returns the microsecond fraction.
171
172 std::time_t s() const noexcept ;
173 ///< Returns the number of seconds since the start of the epoch.
174
175 bool operator<( const SystemTime & ) const ;
176 ///< Comparison operator.
177
178 bool operator<=( const SystemTime & ) const ;
179 ///< Comparison operator.
180
181 bool operator==( const SystemTime & ) const ;
182 ///< Comparison operator.
183
184 bool operator!=( const SystemTime & ) const ;
185 ///< Comparison operator.
186
187 bool operator>( const SystemTime & ) const ;
188 ///< Comparison operator.
189
190 bool operator>=( const SystemTime & ) const ;
191 ///< Comparison operator.
192
193 void operator+=( TimeInterval ) ;
194 ///< Adds the given interval. Throws on overflow.
195
197 ///< Returns this time with given interval added.
198 ///< Throws on overflow.
199
200 TimeInterval operator-( const SystemTime & start ) const ;
201 ///< Returns the given start time's interval() compared
202 ///< to this end time. Returns TimeInterval::zero() on
203 ///< underflow or TimeInterval::limit() on overflow of
204 ///< TimeInterval::s_type.
205
206 TimeInterval interval( const SystemTime & end ) const ;
207 ///< Returns the interval between this time and the given
208 ///< end time. Returns TimeInterval::zero() on underflow or
209 ///< TimeInterval::limit() on overflow of TimeInterval::s_type.
210
211 void streamOut( std::ostream & ) const ;
212 ///< Streams out the time comprised of the s() value, a decimal
213 ///< point, and then the six-digit us() value.
214
215private:
216 friend class G::DateTimeTest ;
217 using time_point_type = std::chrono::time_point<std::chrono::system_clock> ;
218 using duration_type = time_point_type::duration ;
219 explicit SystemTime( time_point_type ) ;
220 SystemTime & add( unsigned long us ) ;
221
222private:
223 time_point_type m_tp ;
224} ;
225
226//| \class G::TimerTime
227/// A monotonically increasing subsecond-resolution timestamp, notionally
228/// unrelated to time_t.
229///
231{
232public:
233 using time_point_type = std::chrono::time_point<std::chrono::steady_clock> ;
234
235 static TimerTime now() ;
236 ///< Factory function for the current steady-clock time.
237
238 static TimerTime zero() ;
239 ///< Factory function for the start of the epoch, guaranteed
240 ///< to be less than any now().
241
242 bool isZero() const noexcept ;
243 ///< Returns true if zero().
244
245 bool sameSecond( const TimerTime & other ) const ;
246 ///< Returns true if this time and the other time are the same,
247 ///< at second resolution.
248
249 static constexpr bool less_noexcept = noexcept(time_point_type() < time_point_type()) ; // NOLINT bogus cert-err58-cpp
250
251 static bool less( const TimerTime & , const TimerTime & ) noexcept(less_noexcept) ;
252 ///< Comparison operator.
253
254 bool operator<=( const TimerTime & ) const ;
255 ///< Comparison operator.
256
257 bool operator==( const TimerTime & ) const ;
258 ///< Comparison operator.
259
260 bool operator!=( const TimerTime & ) const ;
261 ///< Comparison operator.
262
263 bool operator>( const TimerTime & ) const ;
264 ///< Comparison operator.
265
266 bool operator>=( const TimerTime & ) const ;
267 ///< Comparison operator.
268
269 TimerTime operator+( const TimeInterval & ) const ;
270 ///< Returns this time with given interval added.
271
272 void operator+=( TimeInterval ) ;
273 ///< Adds an interval.
274
275 TimeInterval operator-( const TimerTime & start ) const ;
276 ///< Returns the given start time's interval() compared
277 ///< to this end time. Returns TimeInterval::zero() on
278 ///< underflow or TimeInterval::limit() if the
279 ///< TimeInterval::s_type value overflows.
280
281 TimeInterval interval( const TimerTime & end ) const ;
282 ///< Returns the interval between this time and the given
283 ///< end time. Returns TimeInterval::zero() on underflow or
284 ///< TimeInterval::limit() if the TimeInterval::s_type
285 ///< value overflows.
286
287private:
288 friend class G::DateTimeTest ;
289 using duration_type = time_point_type::duration ;
290 explicit TimerTime( time_point_type ) ;
291 static TimerTime test( int , int ) ;
292 unsigned long s() const ; // DateTimeTest
293 unsigned long us() const ; // DateTimeTest
294 std::string str() const ; // DateTimeTest
295
296private:
297 time_point_type m_tp ;
298} ;
299
300//| \class G::TimeInterval
301/// An interval between two G::SystemTime values or two G::TimerTime
302/// values.
303///
305{
306public:
307 using s_type = unsigned int ;
308 using us_type = unsigned int ;
309
310 explicit TimeInterval( unsigned int s , unsigned int us = 0U ) ;
311 ///< Constructor.
312
313 TimeInterval( const SystemTime & start , const SystemTime & end ) ;
314 ///< Constructor. Constructs a zero interval if 'end' is before
315 ///< 'start', and the limit() interval if 'end' is too far
316 ///< ahead of 'start' for the underlying type.
317
318 TimeInterval( const TimerTime & start , const TimerTime & end ) ;
319 ///< Constructor. Overload for TimerTime.
320
321 static TimeInterval zero() ;
322 ///< Factory function for the zero interval.
323
324 static TimeInterval limit() ;
325 ///< Factory function for the maximum valid interval.
326
327 unsigned int s() const ;
328 ///< Returns the number of seconds.
329
330 unsigned int us() const ;
331 ///< Returns the fractional microseconds part.
332
333 void streamOut( std::ostream & ) const ;
334 ///< Streams out the interval.
335
336 bool operator<( const TimeInterval & ) const ;
337 ///< Comparison operator.
338
339 bool operator<=( const TimeInterval & ) const ;
340 ///< Comparison operator.
341
342 bool operator==( const TimeInterval & ) const ;
343 ///< Comparison operator.
344
345 bool operator!=( const TimeInterval & ) const ;
346 ///< Comparison operator.
347
348 bool operator>( const TimeInterval & ) const ;
349 ///< Comparison operator.
350
351 bool operator>=( const TimeInterval & ) const ;
352 ///< Comparison operator.
353
354 TimeInterval operator+( const TimeInterval & ) const ;
355 ///< Returns the combined interval. Throws on overflow.
356
357 TimeInterval operator-( const TimeInterval & ) const ;
358 ///< Returns the interval difference. Throws on underflow.
359
360 void operator+=( TimeInterval ) ;
361 ///< Adds the given interval. Throws on overflow.
362
363 void operator-=( TimeInterval ) ;
364 ///< Subtracts the given interval. Throws on underflow.
365
366private:
367 void normalise() ;
368 static void increase( unsigned int & s , unsigned int ds = 1U ) ;
369 static void decrease( unsigned int & s , unsigned int ds = 1U ) ;
370
371private:
372 unsigned int m_s ;
373 unsigned int m_us ;
374} ;
375
376//| \class G::DateTime
377/// A static class that knows about timezone offsets.
378///
380{
381public:
382 G_EXCEPTION_CLASS( Error , tx("date/time error") )
383 using Offset = std::pair<bool,unsigned int> ;
384
385 static Offset offset( SystemTime ) ;
386 ///< Returns the offset in seconds between UTC and localtime
387 ///< as at the given system time. The returned pair has 'first'
388 ///< set to true if localtime is ahead of (ie. east of) UTC.
389
390 static std::string offsetString( Offset offset ) ;
391 ///< Converts the given utc/localtime offset into a five-character
392 ///< "+/-hhmm" string.
393 ///< See also RFC-2822.
394
395 static std::string offsetString( int hh ) ;
396 ///< Overload for a signed integer timezone.
397
398public:
399 DateTime() = delete ;
400} ;
401
402namespace G
403{
404 std::ostream & operator<<( std::ostream & , const SystemTime & ) ;
405 std::ostream & operator<<( std::ostream & , const TimeInterval & ) ;
406 inline bool operator<( const TimerTime & a , const TimerTime & b ) noexcept(TimerTime::less_noexcept)
407 {
408 return TimerTime::less( a , b ) ;
409 }
410}
411
412inline bool G::TimerTime::less( const TimerTime & a , const TimerTime & b ) noexcept(less_noexcept)
413{
414 return a.m_tp < b.m_tp ;
415}
416
417inline bool G::BrokenDownTime::operator==( const BrokenDownTime & other ) const noexcept
418{
419 return sameMinute(other) && m_tm.tm_sec == other.m_tm.tm_sec ;
420}
421
422inline bool G::BrokenDownTime::operator!=( const BrokenDownTime & other ) const noexcept
423{
424 return !sameMinute(other) || m_tm.tm_sec != other.m_tm.tm_sec ;
425}
426
427#endif
An encapsulation of 'struct std::tm'.
Definition: gdatetime.h:45
int wday() const
Returns week day where sunday=0 and saturday=6.
Definition: gdatetime.cpp:301
bool operator!=(const BrokenDownTime &) const noexcept
Inequality test.
Definition: gdatetime.h:422
int day() const
Returns the 1..31 month-day value.
Definition: gdatetime.cpp:296
static BrokenDownTime null()
Factory function for an unusable object with bogus component values.
Definition: gdatetime.cpp:200
std::time_t epochTimeFromLocal() const
Uses std::mktime() to convert this locale-dependent local broken-down time into epoch time.
Definition: gdatetime.cpp:169
std::string str() const
Returns str() using a "%F %T" format.
Definition: gdatetime.cpp:253
int sec() const
Returns the 0..59 or 0..60 seconds value.
Definition: gdatetime.cpp:281
static BrokenDownTime utc(SystemTime)
Factory function for the utc broken-down time of the given epoch time.
Definition: gdatetime.cpp:213
bool operator==(const BrokenDownTime &) const noexcept
Equality test.
Definition: gdatetime.h:417
static BrokenDownTime midday(int year, int month, int day)
Factory function for midday on the given date.
Definition: gdatetime.cpp:220
static BrokenDownTime midnight(int year, int month, int day)
Factory function for midnight starting the given date.
Definition: gdatetime.cpp:226
int month() const
Returns the 1..12 month value.
Definition: gdatetime.cpp:291
static BrokenDownTime local(SystemTime)
Factory function for the locale-dependent local broken-down time of the given epoch time.
Definition: gdatetime.cpp:206
int hour() const
Returns the 0..23 hour value.
Definition: gdatetime.cpp:271
int year() const
Returns the four-digit year value.
Definition: gdatetime.cpp:286
bool format(char *out, std::size_t out_size, const char *fmt) const
Puts the formatted date, including a terminating null character, into the given output buffer.
Definition: gdatetime.cpp:232
bool sameMinute(const BrokenDownTime &) const noexcept
Returns true if this and the other broken-down times are the same, at minute resolution with no round...
Definition: gdatetime.cpp:309
std::time_t epochTimeFromUtc() const
Converts this utc broken-down time into epoch time.
Definition: gdatetime.cpp:175
int min() const
Returns the 0..59 minute value.
Definition: gdatetime.cpp:276
A static class that knows about timezone offsets.
Definition: gdatetime.h:380
static Offset offset(SystemTime)
Returns the offset in seconds between UTC and localtime as at the given system time.
Definition: gdatetime.cpp:772
static std::string offsetString(Offset offset)
Converts the given utc/localtime offset into a five-character "+/-hhmm" string.
Definition: gdatetime.cpp:792
Represents a unix-epoch time with microsecond resolution.
Definition: gdatetime.h:140
TimeInterval operator-(const SystemTime &start) const
Returns the given start time's interval() compared to this end time.
Definition: gdatetime.cpp:333
static SystemTime now()
Factory function for the current time.
Definition: gdatetime.cpp:328
std::time_t s() const noexcept
Returns the number of seconds since the start of the epoch.
Definition: gdatetime.cpp:380
SystemTime operator+(TimeInterval) const
Returns this time with given interval added.
Definition: gdatetime.cpp:440
unsigned int ms() const
Returns the millisecond fraction.
Definition: gdatetime.cpp:367
unsigned int us() const
Returns the microsecond fraction.
Definition: gdatetime.cpp:374
bool operator!=(const SystemTime &) const
Comparison operator.
Definition: gdatetime.cpp:420
BrokenDownTime local() const
Returns the locale-dependent local broken-down time.
Definition: gdatetime.cpp:356
bool operator>(const SystemTime &) const
Comparison operator.
Definition: gdatetime.cpp:426
void streamOut(std::ostream &) const
Streams out the time comprised of the s() value, a decimal point, and then the six-digit us() value.
Definition: gdatetime.cpp:455
TimeInterval interval(const SystemTime &end) const
Returns the interval between this time and the given end time.
Definition: gdatetime.cpp:338
bool sameSecond(const SystemTime &other) const noexcept
Returns true if this time and the other time are the same, at second resolution.
Definition: gdatetime.cpp:351
bool operator<=(const SystemTime &) const
Comparison operator.
Definition: gdatetime.cpp:409
bool isZero() const
Returns true if zero().
Definition: gdatetime.cpp:397
bool operator>=(const SystemTime &) const
Comparison operator.
Definition: gdatetime.cpp:433
static SystemTime zero()
Factory function for the start of the epoch.
Definition: gdatetime.cpp:388
SystemTime(std::time_t, unsigned long us=0UL) noexcept
Constructor.
Definition: gdatetime.cpp:322
BrokenDownTime utc() const
Returns the utc broken-down time.
Definition: gdatetime.cpp:361
void operator+=(TimeInterval)
Adds the given interval. Throws on overflow.
Definition: gdatetime.cpp:448
bool operator<(const SystemTime &) const
Comparison operator.
Definition: gdatetime.cpp:403
bool operator==(const SystemTime &) const
Comparison operator.
Definition: gdatetime.cpp:415
An interval between two G::SystemTime values or two G::TimerTime values.
Definition: gdatetime.h:305
TimeInterval(unsigned int s, unsigned int us=0U)
Constructor.
Definition: gdatetime.cpp:594
TimeInterval operator+(const TimeInterval &) const
Returns the combined interval. Throws on overflow.
Definition: gdatetime.cpp:696
static TimeInterval zero()
Factory function for the zero interval.
Definition: gdatetime.cpp:644
void operator-=(TimeInterval)
Subtracts the given interval. Throws on underflow.
Definition: gdatetime.cpp:741
bool operator==(const TimeInterval &) const
Comparison operator.
Definition: gdatetime.cpp:659
static TimeInterval limit()
Factory function for the maximum valid interval.
Definition: gdatetime.cpp:638
unsigned int s() const
Returns the number of seconds.
Definition: gdatetime.cpp:649
unsigned int us() const
Returns the fractional microseconds part.
Definition: gdatetime.cpp:654
void operator+=(TimeInterval)
Adds the given interval. Throws on overflow.
Definition: gdatetime.cpp:722
bool operator>(const TimeInterval &) const
Comparison operator.
Definition: gdatetime.cpp:683
TimeInterval operator-(const TimeInterval &) const
Returns the interval difference. Throws on underflow.
Definition: gdatetime.cpp:705
bool operator<(const TimeInterval &) const
Comparison operator.
Definition: gdatetime.cpp:671
bool operator!=(const TimeInterval &) const
Comparison operator.
Definition: gdatetime.cpp:665
void streamOut(std::ostream &) const
Streams out the interval.
Definition: gdatetime.cpp:753
bool operator>=(const TimeInterval &) const
Comparison operator.
Definition: gdatetime.cpp:689
bool operator<=(const TimeInterval &) const
Comparison operator.
Definition: gdatetime.cpp:677
A monotonically increasing subsecond-resolution timestamp, notionally unrelated to time_t.
Definition: gdatetime.h:231
bool isZero() const noexcept
Returns true if zero().
Definition: gdatetime.cpp:491
static TimerTime now()
Factory function for the current steady-clock time.
Definition: gdatetime.cpp:479
TimerTime operator+(const TimeInterval &) const
Returns this time with given interval added.
Definition: gdatetime.cpp:525
bool operator>(const TimerTime &) const
Comparison operator.
Definition: gdatetime.cpp:579
TimeInterval interval(const TimerTime &end) const
Returns the interval between this time and the given end time.
Definition: gdatetime.cpp:546
bool operator==(const TimerTime &) const
Comparison operator.
Definition: gdatetime.cpp:566
bool operator!=(const TimerTime &) const
Comparison operator.
Definition: gdatetime.cpp:572
static bool less(const TimerTime &, const TimerTime &) noexcept(less_noexcept)
Comparison operator.
Definition: gdatetime.h:412
TimeInterval operator-(const TimerTime &start) const
Returns the given start time's interval() compared to this end time.
Definition: gdatetime.cpp:540
bool sameSecond(const TimerTime &other) const
Returns true if this time and the other time are the same, at second resolution.
Definition: gdatetime.cpp:552
void operator+=(TimeInterval)
Adds an interval.
Definition: gdatetime.cpp:532
static TimerTime zero()
Factory function for the start of the epoch, guaranteed to be less than any now().
Definition: gdatetime.cpp:486
bool operator<=(const TimerTime &) const
Comparison operator.
Definition: gdatetime.cpp:561
bool operator>=(const TimerTime &) const
Comparison operator.
Definition: gdatetime.cpp:586
Low-level classes.
Definition: garg.h:36
constexpr const char * tx(const char *p) noexcept
A briefer alternative to G::gettext_noop().
Definition: ggettext.h:84