roo_time
API Documentation for roo_time
Loading...
Searching...
No Matches
roo_time.h
Go to the documentation of this file.
1#pragma once
2
3/// Umbrella header for the roo_time module.
4///
5/// Provides duration, uptime, and wall-time abstractions.
6
7#include <inttypes.h>
8#if defined(ESP_PLATFORM) || defined(__linux__)
9#define CTIME_HDR_DEFINED
10#include <sys/time.h>
11
12#include <ctime>
13#endif
14
15/// Convenience classes for handling delays and elapsed time measurement.
16///
17/// Helps avoid common mistakes such as mixing time units or confusing
18/// timestamps with durations.
19namespace roo_time {
20
21/// Represents an amount of time (e.g. 5s, 10min).
22///
23/// Stored with microsecond precision and 64-bit range. Pass by value.
24/// For rounding semantics, see README section "Rounding semantics".
25class Duration {
26 public:
27 /// Calendar-like decomposition of a duration value.
28 struct Components {
29 bool negative : 1;
30 uint64_t days : 26;
31 uint8_t hours : 5;
32 uint8_t minutes : 6;
33 uint8_t seconds : 6;
34 uint32_t micros : 20;
35 };
36
37 /// Constructs zero duration.
38 constexpr Duration() : micros_(0) {}
39
40 /// Returns the maximum representable duration.
41 static const Duration Max() { return Duration(0x7FFFFFFFFFFFFFFF); }
42
43 /// Returns duration in microseconds.
44 [[nodiscard]] constexpr int64_t inMicros() const { return micros_; }
45
46 /// Returns duration in milliseconds, rounded toward zero.
47 [[nodiscard]] constexpr int64_t inMillis() const {
48 return inMillisRoundedDown();
49 }
50
51 /// Returns duration in seconds, rounded toward zero.
52 [[nodiscard]] constexpr int64_t inSeconds() const {
53 return inSecondsRoundedDown();
54 }
55
56 /// Returns duration in minutes, rounded toward zero.
57 [[nodiscard]] constexpr int64_t inMinutes() const {
58 return inMinutesRoundedDown();
59 }
60
61 /// Returns duration in hours, rounded toward zero.
62 [[nodiscard]] constexpr int64_t inHours() const { return inHoursRoundedDown(); }
63
64 /// Returns duration in milliseconds, rounded toward zero.
65 [[nodiscard]] constexpr int64_t inMillisRoundedDown() const {
66 return micros_ / 1000LL;
67 }
68
69 /// Returns duration in seconds, rounded toward zero.
70 [[nodiscard]] constexpr int64_t inSecondsRoundedDown() const {
71 return micros_ / 1000000LL;
72 }
73
74 /// Returns duration in minutes, rounded toward zero.
75 [[nodiscard]] constexpr int64_t inMinutesRoundedDown() const {
76 return micros_ / 60000000LL;
77 }
78
79 /// Returns duration in hours, rounded toward zero.
80 [[nodiscard]] constexpr int64_t inHoursRoundedDown() const {
81 return micros_ / 3600000000LL;
82 }
83
84 /// Returns duration in milliseconds, rounded away from zero.
85 [[nodiscard]] constexpr int64_t inMillisRoundedUp() const {
86 int64_t q = micros_ / 1000LL;
87 int64_t r = micros_ % 1000LL;
88 if (r == 0) return q;
89 return micros_ > 0 ? q + 1 : q - 1;
90 }
91
92 /// Returns duration in seconds, rounded away from zero.
93 [[nodiscard]] constexpr int64_t inSecondsRoundedUp() const {
94 int64_t q = micros_ / 1000000LL;
95 int64_t r = micros_ % 1000000LL;
96 if (r == 0) return q;
97 return micros_ > 0 ? q + 1 : q - 1;
98 }
99
100 /// Returns duration in minutes, rounded away from zero.
101 [[nodiscard]] constexpr int64_t inMinutesRoundedUp() const {
102 int64_t q = micros_ / 60000000LL;
103 int64_t r = micros_ % 60000000LL;
104 if (r == 0) return q;
105 return micros_ > 0 ? q + 1 : q - 1;
106 }
107
108 /// Returns duration in hours, rounded away from zero.
109 [[nodiscard]] constexpr int64_t inHoursRoundedUp() const {
110 int64_t q = micros_ / 3600000000LL;
111 int64_t r = micros_ % 3600000000LL;
112 if (r == 0) return q;
113 return micros_ > 0 ? q + 1 : q - 1;
114 }
115
116 /// Returns duration in milliseconds, rounded to nearest (ties away from
117 /// zero).
118 [[nodiscard]] constexpr int64_t inMillisRoundedNearest() const {
119 int64_t q = micros_ / 1000LL;
120 int64_t r = micros_ % 1000LL;
121 int64_t ar = r < 0 ? -r : r;
122 if (ar * 2 < 1000LL) return q;
123 return micros_ > 0 ? q + 1 : q - 1;
124 }
125
126 /// Returns duration in seconds, rounded to nearest (ties away from zero).
127 [[nodiscard]] constexpr int64_t inSecondsRoundedNearest() const {
128 int64_t q = micros_ / 1000000LL;
129 int64_t r = micros_ % 1000000LL;
130 int64_t ar = r < 0 ? -r : r;
131 if (ar * 2 < 1000000LL) return q;
132 return micros_ > 0 ? q + 1 : q - 1;
133 }
134
135 /// Returns duration in minutes, rounded to nearest (ties away from zero).
136 [[nodiscard]] constexpr int64_t inMinutesRoundedNearest() const {
137 int64_t q = micros_ / 60000000LL;
138 int64_t r = micros_ % 60000000LL;
139 int64_t ar = r < 0 ? -r : r;
140 if (ar * 2 < 60000000LL) return q;
141 return micros_ > 0 ? q + 1 : q - 1;
142 }
143
144 /// Returns duration in hours, rounded to nearest (ties away from zero).
145 [[nodiscard]] constexpr int64_t inHoursRoundedNearest() const {
146 int64_t q = micros_ / 3600000000LL;
147 int64_t r = micros_ % 3600000000LL;
148 int64_t ar = r < 0 ? -r : r;
149 if (ar * 2 < 3600000000LL) return q;
150 return micros_ > 0 ? q + 1 : q - 1;
151 }
152
153 /// Returns duration in milliseconds as floating-point value.
154 [[nodiscard]] constexpr float inMillisFloat() const { return micros_ / 1000.0; }
155
156 /// Returns duration in seconds as floating-point value.
157 [[nodiscard]] constexpr float inSecondsFloat() const {
158 return micros_ / 1000000.0;
159 }
160
161 /// Returns duration in minutes as floating-point value.
162 [[nodiscard]] constexpr float inMinutesFloat() const {
163 return micros_ / 60000000.0;
164 }
165
166 /// Returns duration in hours as floating-point value.
167 [[nodiscard]] constexpr float inHoursFloat() const {
168 return micros_ / 3600000000.0;
169 }
170
171 /// Adds another duration to this one.
172 Duration& operator+=(const Duration& other) {
173 micros_ += other.inMicros();
174 return *this;
175 }
176
177 /// Subtracts another duration from this one.
178 Duration& operator-=(const Duration& other) {
179 micros_ -= other.inMicros();
180 return *this;
181 }
182
183 /// Breaks duration into components (days, hours, minutes, ...).
184 Components toComponents();
185
186 /// Reconstructs duration from components.
187 static Duration FromComponents(const Components& components);
188
189 private:
190 friend constexpr Duration Micros(long long micros);
191
192 friend constexpr Duration Millis(long long millis);
193 friend constexpr Duration Seconds(long long seconds);
194 friend constexpr Duration Minutes(long long minutes);
195 friend constexpr Duration Hours(long long hours);
196
197 friend constexpr Duration Millis(float millis);
198 friend constexpr Duration Seconds(float seconds);
199 friend constexpr Duration Minutes(float minutes);
200 friend constexpr Duration Hours(float hours);
201
202 friend constexpr Duration Millis(double millis);
203 friend constexpr Duration Seconds(double seconds);
204 friend constexpr Duration Minutes(double minutes);
205 friend constexpr Duration Hours(double hours);
206
207 constexpr Duration(int64_t micros) : micros_(micros) {}
208
209 int64_t micros_;
210};
211
212/// Backwards compatibility alias. Prefer `Duration` in new code.
214
215/// Constructs a duration from microseconds.
216inline constexpr Duration Micros(long long micros) { return Duration(micros); }
217
218/// Constructs a duration from milliseconds.
219///
220/// Overloads accept integer and floating-point input types.
221inline constexpr Duration Millis(long long millis) {
222 return Micros(millis * 1000);
223}
224
225inline constexpr Duration Millis(unsigned long long millis) {
226 return Millis((long long)millis);
227}
228
229inline constexpr Duration Millis(long millis) {
230 return Millis((long long)millis);
231}
232
233inline constexpr Duration Millis(unsigned long millis) {
234 return Millis((long long)millis);
235}
236
237inline constexpr Duration Millis(int millis) {
238 return Millis((long long)millis);
239}
240
241inline constexpr Duration Millis(unsigned int millis) {
242 return Millis((long long)millis);
243}
244
245inline constexpr Duration Millis(short millis) {
246 return Millis((long long)millis);
247}
248
249inline constexpr Duration Millis(unsigned short millis) {
250 return Millis((long long)millis);
251}
252
253inline constexpr Duration Millis(float millis) {
254 return Duration((long long)(millis * 1000));
255}
256
257inline constexpr Duration Millis(double millis) {
258 return Duration((long long)(millis * 1000));
259}
260
261/// Constructs a duration from seconds.
262///
263/// Overloads accept integer and floating-point input types.
264inline constexpr Duration Seconds(long long seconds) {
265 return Micros(seconds * 1000 * 1000);
266}
267
268inline constexpr Duration Seconds(unsigned long long seconds) {
269 return Seconds((long long)seconds);
270}
271
272inline constexpr Duration Seconds(long seconds) {
273 return Seconds((long long)seconds);
274}
275
276inline constexpr Duration Seconds(unsigned long seconds) {
277 return Seconds((long long)seconds);
278}
279
280inline constexpr Duration Seconds(int seconds) {
281 return Seconds((long long)seconds);
282}
283
284inline constexpr Duration Seconds(unsigned int seconds) {
285 return Seconds((long long)seconds);
286}
287
288inline constexpr Duration Seconds(short seconds) {
289 return Seconds((long long)seconds);
290}
291
292inline constexpr Duration Seconds(unsigned short seconds) {
293 return Seconds((long long)seconds);
294}
295
296inline constexpr Duration Seconds(float seconds) {
297 return Duration((int64_t)(seconds * 1000 * 1000));
298}
299
300inline constexpr Duration Seconds(double seconds) {
301 return Duration((int64_t)(seconds * 1000 * 1000));
302}
303
304/// Constructs a duration from minutes.
305///
306/// Overloads accept integer and floating-point input types.
307inline constexpr Duration Minutes(long long minutes) {
308 return Duration(minutes * 1000 * 1000 * 60);
309}
310
311inline constexpr Duration Minutes(unsigned long long minutes) {
312 return Minutes((long long)minutes);
313}
314
315inline constexpr Duration Minutes(long minutes) {
316 return Minutes((long long)minutes);
317}
318
319inline constexpr Duration Minutes(unsigned long minutes) {
320 return Minutes((long long)minutes);
321}
322
323inline constexpr Duration Minutes(int minutes) {
324 return Minutes((long long)minutes);
325}
326
327inline constexpr Duration Minutes(unsigned int minutes) {
328 return Minutes((long long)minutes);
329}
330
331inline constexpr Duration Minutes(short minutes) {
332 return Minutes((long long)minutes);
333}
334
335inline constexpr Duration Minutes(unsigned short minutes) {
336 return Minutes((long long)minutes);
337}
338
339inline constexpr Duration Minutes(float minutes) {
340 return Duration((int64_t)(minutes * 1000 * 1000 * 60));
341}
342
343inline constexpr Duration Minutes(double minutes) {
344 return Duration((int64_t)(minutes * 1000 * 1000 * 60));
345}
346
347/// Constructs a duration from hours.
348///
349/// Overloads accept integer and floating-point input types.
350inline constexpr Duration Hours(long long hours) {
351 return Duration(hours * 1000 * 1000 * 60 * 60);
352}
353
354inline constexpr Duration Hours(unsigned long long minutes) {
355 return Hours((long long)minutes);
356}
357
358inline constexpr Duration Hours(long minutes) {
359 return Hours((long long)minutes);
360}
361
362inline constexpr Duration Hours(unsigned long minutes) {
363 return Hours((long long)minutes);
364}
365
366inline constexpr Duration Hours(int minutes) {
367 return Hours((long long)minutes);
368}
369
370inline constexpr Duration Hours(unsigned int minutes) {
371 return Hours((long long)minutes);
372}
373
374inline constexpr Duration Hours(short minutes) {
375 return Hours((long long)minutes);
376}
377
378inline constexpr Duration Hours(unsigned short minutes) {
379 return Hours((long long)minutes);
380}
381
382inline constexpr Duration Hours(float hours) {
383 return Duration((int64_t)(hours * 1000 * 1000 * 60 * 60));
384}
385
386inline constexpr Duration Hours(double hours) {
387 return Duration((int64_t)(hours * 1000 * 1000 * 60 * 60));
388}
389
390/// Returns true if both durations are equal.
391inline bool operator==(const Duration& a, const Duration& b) {
392 return a.inMicros() == b.inMicros();
393}
394
395/// Returns true if durations differ.
396inline bool operator!=(const Duration& a, const Duration& b) {
397 return a.inMicros() != b.inMicros();
398}
399
400/// Returns true if `a` is shorter than `b`.
401inline bool operator<(const Duration& a, const Duration& b) {
402 return a.inMicros() < b.inMicros();
403}
404
405/// Returns true if `a` is longer than `b`.
406inline bool operator>(const Duration& a, const Duration& b) {
407 return a.inMicros() > b.inMicros();
408}
409
410/// Returns true if `a` is not longer than `b`.
411inline bool operator<=(const Duration& a, const Duration& b) {
412 return a.inMicros() <= b.inMicros();
413}
414
415/// Returns true if `a` is not shorter than `b`.
416inline bool operator>=(const Duration& a, const Duration& b) {
417 return a.inMicros() >= b.inMicros();
418}
419
420/// Returns the sum of two durations.
421inline Duration operator+(const Duration& a, const Duration& b) {
422 return Micros(a.inMicros() + b.inMicros());
423}
424
425/// Returns the difference between two durations.
426inline Duration operator-(const Duration& a, const Duration& b) {
427 return Micros(a.inMicros() - b.inMicros());
428}
429
430/// Multiplies duration by an integer factor.
431inline Duration operator*(const Duration& a, int b) {
432 return Micros(a.inMicros() * b);
433}
434
435/// Multiplies duration by an integer factor.
436inline Duration operator*(int a, const Duration& b) {
437 return Micros(a * b.inMicros());
438}
439
440/// Represents an instant relative to process/boot start time.
441///
442/// Stored with microsecond precision and 64-bit range. May not include sleep
443/// time on some platforms.
444class Uptime {
445 public:
446 /// Returns current monotonic process uptime.
447 static const Uptime Now();
448
449 /// Returns uptime value at process start.
450 static const Uptime Start() { return Uptime(0); }
451
452 /// Returns the maximum representable uptime value.
453 static const Uptime Max() { return Uptime(0x7FFFFFFFFFFFFFFF); }
454
455 /// Constructs zero uptime value.
456 Uptime() : micros_(0) {}
457
458 /// Copy constructor.
459 Uptime(const Uptime& other) : micros_(other.micros_) {}
460
461 /// Copy constructor for volatile sources.
462 Uptime(const volatile Uptime& other) : micros_(other.micros_) {}
463
464 /// Assignment operator.
465 Uptime& operator=(const Uptime& other) {
466 micros_ = other.micros_;
467 return *this;
468 }
469
470 /// Assignment operator for volatile sources.
471 Uptime& operator=(const volatile Uptime& other) {
472 micros_ = other.micros_;
473 return *this;
474 }
475
476 /// Returns uptime in microseconds.
477 [[nodiscard]] int64_t inMicros() const { return micros_; }
478
479 /// Returns uptime in milliseconds.
480 [[nodiscard]] int64_t inMillis() const { return micros_ / 1000LL; }
481
482 /// Returns uptime in seconds.
483 [[nodiscard]] int64_t inSeconds() const { return micros_ / 1000000LL; }
484
485 /// Returns uptime in minutes.
486 [[nodiscard]] int64_t inMinutes() const { return micros_ / 60000000LL; }
487
488 /// Returns uptime in hours.
489 [[nodiscard]] int64_t inHours() const { return micros_ / 3600000000LL; }
490
491 // Duration HowLongAgo() const {
492 // return Duration(Now().ToMicros() - this->ToMicros);
493 // }
494
495 /// Adds duration to this uptime.
497 micros_ += i.inMicros();
498 return *this;
499 }
500
501 /// Subtracts duration from this uptime.
503 micros_ -= i.inMicros();
504 return *this;
505 }
506
507 private:
508 friend Uptime operator+(const Uptime& u, const Duration& i);
509 friend Uptime operator-(const Uptime& u, const Duration& i);
510 friend Uptime operator+(const Duration& i, const Uptime& u);
511
512 Uptime(int64_t micros) : micros_(micros) {}
513
514 int64_t micros_;
515};
516
517/// Returns true if uptimes are equal.
518inline bool operator==(const Uptime& a, const Uptime& b) {
519 return a.inMicros() == b.inMicros();
520}
521
522/// Returns true if uptimes differ.
523inline bool operator!=(const Uptime& a, const Uptime& b) {
524 return a.inMicros() != b.inMicros();
525}
526
527/// Returns true if `a` is earlier than `b`.
528inline bool operator<(const Uptime& a, const Uptime& b) {
529 return a.inMicros() < b.inMicros();
530}
531
532/// Returns true if `a` is later than `b`.
533inline bool operator>(const Uptime& a, const Uptime& b) {
534 return a.inMicros() > b.inMicros();
535}
536
537/// Returns true if `a` is not later than `b`.
538inline bool operator<=(const Uptime& a, const Uptime& b) {
539 return a.inMicros() <= b.inMicros();
540}
541
542/// Returns true if `a` is not earlier than `b`.
543inline bool operator>=(const Uptime& a, const Uptime& b) {
544 return a.inMicros() >= b.inMicros();
545}
546
547/// Returns elapsed duration between two uptime instants.
548inline Duration operator-(const Uptime& a, const Uptime& b) {
549 return Micros(a.inMicros() - b.inMicros());
550}
551
552/// Returns uptime shifted by duration.
553inline Uptime operator+(const Uptime& u, const Duration& i) {
554 return Uptime(u.inMicros() + i.inMicros());
555}
556
557/// Returns uptime shifted backwards by duration.
558inline Uptime operator-(const Uptime& u, const Duration& i) {
559 return Uptime(u.inMicros() - i.inMicros());
560}
561
562/// Returns uptime shifted by duration.
563inline Uptime operator+(const Duration& i, const Uptime& u) {
564 return Uptime(u.inMicros() + i.inMicros());
565}
566
567/// Delays execution for `duration`.
568///
569/// Negative durations are treated as no-op.
570void Delay(Duration duration);
571
572/// Delays execution until `deadline`.
573///
574/// If deadline is in the past, returns immediately.
575void DelayUntil(Uptime deadline);
576
577/// Represents absolute wall time since Unix epoch.
578///
579/// Stored with microsecond precision and 64-bit range. Does not account for
580/// leap seconds.
581class WallTime {
582 public:
583 /// Constructs epoch wall time.
585
586 /// Constructs wall time from offset since Unix epoch.
587 explicit WallTime(Duration since_epoch) : since_epoch_(since_epoch) {}
588
589 /// Returns elapsed duration since Unix epoch.
590 [[nodiscard]] Duration sinceEpoch() const { return since_epoch_; }
591
592 /// Adds duration to this wall time.
594 since_epoch_ += i;
595 return *this;
596 }
597
598 /// Subtracts duration from this wall time.
600 since_epoch_ -= i;
601 return *this;
602 }
603
604 private:
605 friend WallTime operator+(const WallTime&, const Duration&);
606 friend WallTime operator-(const WallTime&, const Duration&);
607 friend WallTime operator+(const Duration&, const WallTime&);
608
609 Duration since_epoch_;
610};
611
612/// Returns true if both wall times are equal.
613inline bool operator==(const WallTime& a, const WallTime& b) {
614 return a.sinceEpoch() == b.sinceEpoch();
615}
616
617/// Returns true if wall times differ.
618inline bool operator!=(const WallTime& a, const WallTime& b) {
619 return a.sinceEpoch() != b.sinceEpoch();
620}
621
622/// Returns true if `a` is earlier than `b`.
623inline bool operator<(const WallTime& a, const WallTime& b) {
624 return a.sinceEpoch() < b.sinceEpoch();
625}
626
627/// Returns true if `a` is later than `b`.
628inline bool operator>(const WallTime& a, const WallTime& b) {
629 return a.sinceEpoch() > b.sinceEpoch();
630}
631
632/// Returns true if `a` is not later than `b`.
633inline bool operator<=(const WallTime& a, const WallTime& b) {
634 return a.sinceEpoch() <= b.sinceEpoch();
635}
636
637/// Returns true if `a` is not earlier than `b`.
638inline bool operator>=(const WallTime& a, const WallTime& b) {
639 return a.sinceEpoch() >= b.sinceEpoch();
640}
641
642/// Returns elapsed duration between two wall times.
643inline Duration operator-(const WallTime& a, const WallTime& b) {
644 return a.sinceEpoch() - b.sinceEpoch();
645}
646
647/// Returns wall time shifted by duration.
648inline WallTime operator+(const WallTime& t, const Duration& i) {
649 return WallTime(t.sinceEpoch() + i);
650}
651
652/// Returns wall time shifted backwards by duration.
653inline WallTime operator-(const WallTime& t, const Duration& i) {
654 return WallTime(t.sinceEpoch() - i);
655}
656
657/// Returns wall time shifted by duration.
658inline WallTime operator+(const Duration& i, const WallTime& t) {
659 return WallTime(t.sinceEpoch() + i);
660}
661
662/// Abstract interface for obtaining current wall time.
664 public:
665 /// Virtual destructor.
666 virtual ~WallTimeClock() = default;
667
668 /// Returns current wall time.
669 virtual WallTime now() const = 0;
670};
671
672#ifdef CTIME_HDR_DEFINED
673/// Wall-time clock backed by `gettimeofday`.
674class SystemClock : public WallTimeClock {
675 public:
676 /// Returns current system wall time.
677 WallTime now() const override {
678 struct timeval tv;
679 if (gettimeofday(&tv, nullptr)) return WallTime();
680 return WallTime(Micros(tv.tv_sec * 1000000LL + tv.tv_usec));
681 }
682};
683#endif
684
685class TimeZone {
686 public:
687 /// Constructs UTC timezone.
688 TimeZone() : offset_minutes_(0) {}
689
690 /// Creates time zone with specified UTC offset.
691 constexpr explicit TimeZone(Duration offset)
692 : offset_minutes_(offset.inMinutes()) {}
693
694 /// Returns UTC offset of this time zone.
695 [[nodiscard]] constexpr Duration offset() const {
696 return Minutes(offset_minutes_);
697 }
698
699 private:
700 int16_t offset_minutes_;
701};
702
703namespace timezone {
704constexpr TimeZone UTC = TimeZone(Micros(0));
705}
706
716
731
732/// Represents wall time decomposed into date/time in a specific time zone.
733///
734/// Does not account for leap seconds.
735class DateTime {
736 public:
737 /// Constructs `DateTime` representing current time in UTC.
738 DateTime() : DateTime(WallTime(), timezone::UTC) {}
739
740 /// Constructs `DateTime` at midnight of a date in the specified time zone.
741 ///
742 /// @param year Four-digit year.
743 /// @param month Month in [1, 12].
744 /// @param day Day in [1, max_day_of_month].
745 DateTime(uint16_t year, uint8_t month, uint8_t day, TimeZone tz);
746
747 /// Constructs date/time in the specified time zone.
748 ///
749 /// @param year Four-digit year.
750 /// @param month Month in [1, 12].
751 /// @param day Day in [1, max_day_of_month].
752 /// @param hour Hour in [0, 23].
753 /// @param minute Minute in [0, 59].
754 /// @param second Second in [0, 59].
755 /// @param micros Microsecond fraction in [0, 999999].
756 /// @param tz Time zone to interpret the components in.
757 DateTime(uint16_t year, uint8_t month, uint8_t day, uint8_t hour,
758 uint8_t minute, uint8_t second, uint32_t micros, TimeZone tz);
759
760 /// Constructs `DateTime` for `wallTime` in time zone `tz`.
762
763 /// Returns `WallTime` corresponding to this `DateTime`.
764 [[nodiscard]] WallTime wallTime() const { return walltime_; }
765
766 /// Returns time zone of this `DateTime`.
767 [[nodiscard]] TimeZone timeZone() const { return tz_; }
768
769 /// Returns four-digit year.
770 [[nodiscard]] int16_t year() const { return year_; }
771
772 /// Returns month in [1, 12].
773 [[nodiscard]] Month month() const { return (Month)month_; }
774
775 /// Returns day of month in valid range.
776 [[nodiscard]] uint8_t day() const { return day_; }
777
778 /// Returns hour in [0, 23].
779 [[nodiscard]] uint8_t hour() const { return hour_; }
780
781 /// Returns minute in [0, 59].
782 [[nodiscard]] uint8_t minute() const { return minute_; }
783
784 /// Returns second in [0, 59].
785 [[nodiscard]] uint8_t second() const { return second_; }
786
787 /// Returns microsecond fraction in [0, 999999].
788 [[nodiscard]] uint32_t micros() const { return micros_; }
789
790 /// Returns day of week in this time zone.
791 [[nodiscard]] DayOfWeek dayOfWeek() const { return day_of_week_; }
792
793 /// Returns day of year in [1, 366].
794 [[nodiscard]] uint16_t dayOfYear() const { return day_of_year_; }
795
796#ifdef CTIME_HDR_DEFINED
797 /// Constructs `DateTime` from C `tm` structure.
798 DateTime(struct tm t, TimeZone tz = timezone::UTC)
799 : DateTime(t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min,
800 t.tm_sec, 0, tz) {}
801
802 /// Returns this value as a C `tm` structure.
803 struct tm tmStruct() const {
804 return tm{.tm_sec = second_,
805 .tm_min = minute_,
806 .tm_hour = hour_,
807 .tm_mday = day_,
808 .tm_mon = month_ - 1,
809 .tm_year = year_ - 1900,
810 .tm_wday = day_of_week_,
811 .tm_yday = day_of_year_,
812 .tm_isdst = -1};
813 }
814#endif
815
816 private:
817 WallTime walltime_;
818 TimeZone tz_;
819 int16_t year_;
820 uint8_t month_;
821 uint8_t day_;
822 uint8_t hour_;
823 uint8_t minute_;
824 uint8_t second_;
825 DayOfWeek day_of_week_;
826 uint16_t day_of_year_;
827 uint32_t micros_;
828};
829
830/// Returns true if both date-times represent the same instant and offset.
831inline bool operator==(const DateTime& a, const DateTime& b) {
832 return a.wallTime() == b.wallTime() &&
833 a.timeZone().offset() == b.timeZone().offset();
834}
835
836/// Returns true if date-times differ in instant or time-zone offset.
837inline bool operator!=(const DateTime& a, const DateTime& b) {
838 return a.wallTime() != b.wallTime() ||
839 a.timeZone().offset() != b.timeZone().offset();
840}
841
842} // namespace roo_time
843
844#if defined(__linux__)
845
846/// Convenience printers to aid testing.
847#include <iomanip>
848#include <ostream>
849
850/// Streams textual `Duration` representation for tests.
851inline std::ostream& operator<<(std::ostream& os,
852 const roo_time::Duration& duration) {
853 os << duration.inMicros() << " us";
854 return os;
855}
856
857/// Streams textual `Uptime` representation for tests.
858inline std::ostream& operator<<(std::ostream& os, const roo_time::Uptime& t) {
859 os << (t - roo_time::Uptime::Start()) << " uptime";
860 return os;
861}
862
863/// Streams textual `WallTime` representation for tests.
864inline std::ostream& operator<<(std::ostream& os, const roo_time::WallTime& t) {
865 os << t.sinceEpoch() << " since Epoch";
866 return os;
867}
868
869/// Streams textual `DateTime` representation for tests.
870inline std::ostream& operator<<(std::ostream& os,
871 const roo_time::DateTime& dt) {
872 os << std::setfill('0') << std::setw(4) << (int)dt.year() << "-";
873 os << std::setfill('0') << std::setw(2) << (int)dt.month() << "-";
874 os << std::setfill('0') << std::setw(2) << (int)dt.day() << " ";
875 os << std::setfill('0') << std::setw(2) << (int)dt.hour() << ":";
876 os << std::setfill('0') << std::setw(2) << (int)dt.minute() << ":";
877 os << std::setfill('0') << std::setw(2) << (int)dt.second() << ".";
878 os << std::setfill('0') << std::setw(6) << (int64_t)dt.micros();
879 if (dt.timeZone().offset().inMicros() > 0) {
880 os << "+";
881 }
882 os << dt.timeZone().offset().inMinutes() << "min";
883 return os;
884}
885
886#endif
Represents wall time decomposed into date/time in a specific time zone.
Definition roo_time.h:735
int16_t year() const
Returns four-digit year.
Definition roo_time.h:770
Month month() const
Returns month in [1, 12].
Definition roo_time.h:773
uint8_t second() const
Returns second in [0, 59].
Definition roo_time.h:785
uint16_t dayOfYear() const
Returns day of year in [1, 366].
Definition roo_time.h:794
DayOfWeek dayOfWeek() const
Returns day of week in this time zone.
Definition roo_time.h:791
uint32_t micros() const
Returns microsecond fraction in [0, 999999].
Definition roo_time.h:788
uint8_t minute() const
Returns minute in [0, 59].
Definition roo_time.h:782
uint8_t hour() const
Returns hour in [0, 23].
Definition roo_time.h:779
DateTime()
Constructs DateTime representing current time in UTC.
Definition roo_time.h:738
WallTime wallTime() const
Returns WallTime corresponding to this DateTime.
Definition roo_time.h:764
uint8_t day() const
Returns day of month in valid range.
Definition roo_time.h:776
TimeZone timeZone() const
Returns time zone of this DateTime.
Definition roo_time.h:767
Represents an amount of time (e.g. 5s, 10min).
Definition roo_time.h:25
Duration & operator+=(const Duration &other)
Adds another duration to this one.
Definition roo_time.h:172
constexpr int64_t inMillis() const
Returns duration in milliseconds, rounded toward zero.
Definition roo_time.h:47
constexpr int64_t inHours() const
Returns duration in hours, rounded toward zero.
Definition roo_time.h:62
constexpr int64_t inMinutesRoundedNearest() const
Returns duration in minutes, rounded to nearest (ties away from zero).
Definition roo_time.h:136
constexpr float inMillisFloat() const
Returns duration in milliseconds as floating-point value.
Definition roo_time.h:154
constexpr int64_t inMillisRoundedDown() const
Returns duration in milliseconds, rounded toward zero.
Definition roo_time.h:65
constexpr int64_t inSecondsRoundedDown() const
Returns duration in seconds, rounded toward zero.
Definition roo_time.h:70
constexpr Duration()
Constructs zero duration.
Definition roo_time.h:38
Duration & operator-=(const Duration &other)
Subtracts another duration from this one.
Definition roo_time.h:178
constexpr float inMinutesFloat() const
Returns duration in minutes as floating-point value.
Definition roo_time.h:162
constexpr int64_t inHoursRoundedUp() const
Returns duration in hours, rounded away from zero.
Definition roo_time.h:109
constexpr int64_t inSecondsRoundedNearest() const
Returns duration in seconds, rounded to nearest (ties away from zero).
Definition roo_time.h:127
constexpr int64_t inMinutesRoundedDown() const
Returns duration in minutes, rounded toward zero.
Definition roo_time.h:75
friend constexpr Duration Hours(long long hours)
Constructs a duration from hours.
Definition roo_time.h:350
constexpr int64_t inMillisRoundedNearest() const
Returns duration in milliseconds, rounded to nearest (ties away from zero).
Definition roo_time.h:118
friend constexpr Duration Seconds(long long seconds)
Constructs a duration from seconds.
Definition roo_time.h:264
static Duration FromComponents(const Components &components)
Reconstructs duration from components.
Definition roo_time.cpp:28
Components toComponents()
Breaks duration into components (days, hours, minutes, ...).
Definition roo_time.cpp:10
constexpr int64_t inHoursRoundedDown() const
Returns duration in hours, rounded toward zero.
Definition roo_time.h:80
constexpr int64_t inMillisRoundedUp() const
Returns duration in milliseconds, rounded away from zero.
Definition roo_time.h:85
constexpr int64_t inMinutesRoundedUp() const
Returns duration in minutes, rounded away from zero.
Definition roo_time.h:101
friend constexpr Duration Micros(long long micros)
Constructs a duration from microseconds.
Definition roo_time.h:216
constexpr int64_t inMinutes() const
Returns duration in minutes, rounded toward zero.
Definition roo_time.h:57
constexpr float inSecondsFloat() const
Returns duration in seconds as floating-point value.
Definition roo_time.h:157
constexpr int64_t inSeconds() const
Returns duration in seconds, rounded toward zero.
Definition roo_time.h:52
constexpr int64_t inSecondsRoundedUp() const
Returns duration in seconds, rounded away from zero.
Definition roo_time.h:93
constexpr int64_t inMicros() const
Returns duration in microseconds.
Definition roo_time.h:44
static const Duration Max()
Returns the maximum representable duration.
Definition roo_time.h:41
constexpr int64_t inHoursRoundedNearest() const
Returns duration in hours, rounded to nearest (ties away from zero).
Definition roo_time.h:145
constexpr float inHoursFloat() const
Returns duration in hours as floating-point value.
Definition roo_time.h:167
friend constexpr Duration Minutes(long long minutes)
Constructs a duration from minutes.
Definition roo_time.h:307
friend constexpr Duration Millis(long long millis)
Constructs a duration from milliseconds.
Definition roo_time.h:221
TimeZone()
Constructs UTC timezone.
Definition roo_time.h:688
constexpr Duration offset() const
Returns UTC offset of this time zone.
Definition roo_time.h:695
constexpr TimeZone(Duration offset)
Creates time zone with specified UTC offset.
Definition roo_time.h:691
Represents an instant relative to process/boot start time.
Definition roo_time.h:444
Uptime()
Constructs zero uptime value.
Definition roo_time.h:456
Uptime & operator-=(const Duration &i)
Subtracts duration from this uptime.
Definition roo_time.h:502
static const Uptime Now()
Returns current monotonic process uptime.
int64_t inHours() const
Returns uptime in hours.
Definition roo_time.h:489
int64_t inMicros() const
Returns uptime in microseconds.
Definition roo_time.h:477
int64_t inSeconds() const
Returns uptime in seconds.
Definition roo_time.h:483
Uptime(const Uptime &other)
Copy constructor.
Definition roo_time.h:459
static const Uptime Max()
Returns the maximum representable uptime value.
Definition roo_time.h:453
Uptime & operator=(const volatile Uptime &other)
Assignment operator for volatile sources.
Definition roo_time.h:471
int64_t inMinutes() const
Returns uptime in minutes.
Definition roo_time.h:486
friend Uptime operator-(const Uptime &u, const Duration &i)
Returns uptime shifted backwards by duration.
Definition roo_time.h:558
int64_t inMillis() const
Returns uptime in milliseconds.
Definition roo_time.h:480
Uptime & operator=(const Uptime &other)
Assignment operator.
Definition roo_time.h:465
friend Uptime operator+(const Uptime &u, const Duration &i)
Returns uptime shifted by duration.
Definition roo_time.h:553
Uptime(const volatile Uptime &other)
Copy constructor for volatile sources.
Definition roo_time.h:462
Uptime & operator+=(const Duration &i)
Adds duration to this uptime.
Definition roo_time.h:496
static const Uptime Start()
Returns uptime value at process start.
Definition roo_time.h:450
Abstract interface for obtaining current wall time.
Definition roo_time.h:663
virtual ~WallTimeClock()=default
Virtual destructor.
virtual WallTime now() const =0
Returns current wall time.
Represents absolute wall time since Unix epoch.
Definition roo_time.h:581
WallTime()
Constructs epoch wall time.
Definition roo_time.h:584
Duration sinceEpoch() const
Returns elapsed duration since Unix epoch.
Definition roo_time.h:590
WallTime & operator-=(const Duration &i)
Subtracts duration from this wall time.
Definition roo_time.h:599
friend WallTime operator-(const WallTime &, const Duration &)
Returns wall time shifted backwards by duration.
Definition roo_time.h:653
WallTime(Duration since_epoch)
Constructs wall time from offset since Unix epoch.
Definition roo_time.h:587
WallTime & operator+=(const Duration &i)
Adds duration to this wall time.
Definition roo_time.h:593
friend WallTime operator+(const WallTime &, const Duration &)
Returns wall time shifted by duration.
Definition roo_time.h:648
Umbrella header for the roo_time module.
Definition roo_time.cpp:3
bool operator==(const Duration &a, const Duration &b)
Returns true if both durations are equal.
Definition roo_time.h:391
Duration operator-(const Duration &a, const Duration &b)
Returns the difference between two durations.
Definition roo_time.h:426
@ kWednesday
Definition roo_time.h:711
@ kThursday
Definition roo_time.h:712
@ kSaturday
Definition roo_time.h:714
bool operator!=(const Duration &a, const Duration &b)
Returns true if durations differ.
Definition roo_time.h:396
bool operator<=(const Duration &a, const Duration &b)
Returns true if a is not longer than b.
Definition roo_time.h:411
constexpr Duration Micros(long long micros)
Constructs a duration from microseconds.
Definition roo_time.h:216
Duration operator*(const Duration &a, int b)
Multiplies duration by an integer factor.
Definition roo_time.h:431
constexpr Duration Seconds(long long seconds)
Constructs a duration from seconds.
Definition roo_time.h:264
void DelayUntil(Uptime deadline)
Delays execution until deadline.
constexpr Duration Minutes(long long minutes)
Constructs a duration from minutes.
Definition roo_time.h:307
constexpr Duration Millis(long long millis)
Constructs a duration from milliseconds.
Definition roo_time.h:221
bool operator>=(const Duration &a, const Duration &b)
Returns true if a is not shorter than b.
Definition roo_time.h:416
bool operator>(const Duration &a, const Duration &b)
Returns true if a is longer than b.
Definition roo_time.h:406
void Delay(Duration duration)
Delays execution for duration.
constexpr Duration Hours(long long hours)
Constructs a duration from hours.
Definition roo_time.h:350
Duration operator+(const Duration &a, const Duration &b)
Returns the sum of two durations.
Definition roo_time.h:421
bool operator<(const Duration &a, const Duration &b)
Returns true if a is shorter than b.
Definition roo_time.h:401
@ kFebruary
Definition roo_time.h:719
@ kNovember
Definition roo_time.h:728
@ kDecember
Definition roo_time.h:729
@ kSeptember
Definition roo_time.h:726
Calendar-like decomposition of a duration value.
Definition roo_time.h:28