Ocean
Loading...
Searching...
No Matches
Timestamp.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_BASE_TIMESTAMP_H
9#define META_OCEAN_BASE_TIMESTAMP_H
10
11#include "ocean/base/Base.h"
12#include "ocean/base/Lock.h"
13
14#include <atomic>
15#include <deque>
16#include <cfloat>
17#include <limits>
18
19#ifndef OCEAN_BASE_TIMESTAMP_BOOTTIME_AVAILABLE
20 #if !defined(OCEAN_PLATFORM_BUILD_WINDOWS) && defined(CLOCK_BOOTTIME)
21 #define OCEAN_BASE_TIMESTAMP_BOOTTIME_AVAILABLE
22 #endif
23#endif // OCEAN_BASE_TIMESTAMP_BOOTTIME_AVAILABLE
24
25#ifndef OCEAN_BASE_TIMESTAMP_UPTIMERAW_AVAILABLE
26 #if defined(OCEAN_PLATFORM_BUILD_APPLE) && defined(CLOCK_UPTIME_RAW)
27 #define OCEAN_BASE_TIMESTAMP_UPTIMERAW_AVAILABLE
28 #endif
29#endif // OCEAN_BASE_TIMESTAMP_UPTIMERAW_AVAILABLE
30
31#ifndef OCEAN_BASE_TIMESTAMP_VIRTUAL_COUNTER_REGISTER_AVAILABLE
32 #if defined(OCEAN_PLATFORM_BUILD_ANDROID) && (defined(__arm__) || defined(__aarch64__))
33 #define OCEAN_BASE_TIMESTAMP_VIRTUAL_COUNTER_REGISTER_AVAILABLE
34 #endif
35#endif // OCEAN_BASE_TIMESTAMP_VIRTUAL_COUNTER_REGISTER_AVAILABLE
36
37#ifndef OCEAN_BASE_TIMESTAMP_CUSTOM_POSIX_AVAILABLE
38 #if !defined(OCEAN_PLATFORM_BUILD_WINDOWS)
39 #define OCEAN_BASE_TIMESTAMP_CUSTOM_POSIX_AVAILABLE
40 #endif
41#endif
42
43namespace Ocean
44{
45
46// Forward declaration.
47class Timestamp;
48
49/**
50 * Definition of a vector holding Timestamp objects.
51 * @see Timestamp
52 * @ingroup base
53 */
54using Timestamps = std::vector<Timestamp>;
55
56/**
57 * This class implements a timestamp.
58 * The timestamp is specified by the number of seconds since 01.01.1970 00:00:00 in UTC time.<br>
59 * Depending on the underlying hardware the accuracy (update rate) of the timestamps can vary.<br>
60 * The timestamp class wraps a floating value with 64 bit precision.
61 * @ingroup base
62 */
63class OCEAN_BASE_EXPORT Timestamp
64{
65 public:
66
67 /// Definition of the number of milliseconds in one second.
68 static constexpr int64_t millisecondsPerSecond_ = 1000;
69
70 /// Definition of the number of microseconds in one second.
71 static constexpr int64_t microsecondsPerSecond_ = millisecondsPerSecond_ * 1000;
72
73 /// Definition of the number of nanoseconds in one second.
74 static constexpr int64_t nanosecondsPerSecond_ = microsecondsPerSecond_ * 1000;
75
76 public:
77
78 /**
79 * Creates a new timestamp with invalid time.
80 */
81 Timestamp() = default;
82
83 /**
84 * Creates a new timestamp.
85 * @param toNow Determines whether the timestamp holds the seconds since 01.01.1970 00:00:00 in UTC time, otherwise the timestamp will be initialized as invalid
86 */
87 explicit Timestamp(const bool toNow);
88
89 /**
90 * Creates a new timestamp with a given value.
91 * @param timestamp Timestamp value
92 */
93 inline explicit Timestamp(const double timestamp);
94
95 /**
96 * Sets the timestamp to the current time.
97 * The timestamp holds the seconds since 01.01.1970 00:00:00 in UTC time.
98 * @return Reference to this object
99 */
101
102 /**
103 * Sets the timestamp to invalid.
104 * @return Reference to this object
105 */
106 inline Timestamp& toInvalid();
107
108 /**
109 * Returns this timestamp in nanoseconds.
110 * @return The timestamp in nanoseconds, with range (-infinity, infinity)
111 */
112 inline int64_t nanoseconds() const;
113
114 /**
115 * Returns whether a specified amount of time has passed since this timestamp.
116 * This function returns 'thisTimestamp + seconds <= currentTimestamp'.
117 * @param seconds The number of seconds defining the time to check, with range [0, infinity)
118 * @param currentTimestamp The current timestamp to use for comparison
119 * @return True, if the time has passed or if this timestamp is invalid
120 */
121 inline bool hasTimePassed(const double seconds, const Timestamp& currentTimestamp = Timestamp(true)) const;
122
123 /**
124 * Returns whether the timestamp holds a valid time.
125 * @return True, if so
126 */
127 inline bool isValid() const;
128
129 /**
130 * Returns whether the timestamp holds an invalid time.
131 * @return True, if so
132 */
133 inline bool isInvalid() const;
134
135 /**
136 * Assign a new value.
137 * @param timestamp Value to assign
138 * @return Reference to this timestamp
139 */
140 inline Timestamp& operator=(const double timestamp);
141
142 /**
143 * Adds two timestamps.
144 * @param right The right timestamp
145 * @return New timestamp
146 */
147 inline Timestamp operator+(const Timestamp& right) const;
148
149 /**
150 * Adds and assigns two timestamps.
151 * @param right The right timestamp
152 * @return Reference to this timestamp
153 */
154 inline Timestamp& operator+=(const Timestamp& right);
155
156 /**
157 * Adds seconds to this timestamps.
158 * @param seconds The number of seconds to add, with range (-infinity, infinity)
159 * @return New timestamp
160 */
161 inline Timestamp operator+(const double seconds) const;
162
163 /**
164 * Adds and assigns seconds to this timestamps.
165 * @param seconds The number of seconds to add, with range (-infinity, infinity)
166 * @return Reference to this timestamp
167 */
168 inline Timestamp& operator+=(const double seconds);
169
170 /**
171 * Subtracts two timestamps.
172 * @param right The right timestamp
173 * @return New timestamp
174 */
175 inline Timestamp operator-(const Timestamp& right) const;
176
177 /**
178 * Subtracts and assigns two timestamps.
179 * @param right The right timestamp
180 * @return Reference to this timestamp
181 */
182 inline Timestamp& operator-=(const Timestamp& right);
183
184 /**
185 * Subtracts seconds from this timestamp.
186 * @param seconds The number of seconds to subtract, with range (-infinity, infinity)
187 * @return New timestamp
188 */
189 inline Timestamp operator-(const double seconds) const;
190
191 /**
192 * Subtracts and assigns seconds from this timestamp.
193 * @param seconds The number of seconds to subtract, with range (-infinity, infinity)
194 * @return Reference to this timestamp
195 */
196 inline Timestamp& operator-=(const double seconds);
197
198 /**
199 * Returns whether the this timestamp is lesser than the right one.
200 * @param right The right timestamp
201 * @return True, if so
202 */
203 inline bool operator<(const Timestamp& right) const;
204
205 /**
206 * Returns whether the this timestamp is lesser or equal to the right one.
207 * @param right The right timestamp
208 * @return True, if so
209 */
210 inline bool operator<=(const Timestamp& right) const;
211
212 /**
213 * Returns whether the this timestamp is greater than the right one.
214 * @param right The right timestamp
215 * @return True, if so
216 */
217 inline bool operator>(const Timestamp& right) const;
218
219 /**
220 * Returns whether the this timestamp is greater or equal to the right one.
221 * @param right The right timestamp
222 * @return True, if so
223 */
224 inline bool operator>=(const Timestamp& right) const;
225
226 /**
227 * Returns whether two timestamps are identical.
228 * @param right The right timestamp
229 * @return True, if so
230 */
231 inline bool operator==(const Timestamp& right) const;
232
233 /**
234 * Returns whether two timestamps are not identical.
235 * @param right The right timestamp
236 * @return True, if so
237 */
238 inline bool operator!=(const Timestamp& right) const;
239
240 /**
241 * Cast operator for the timestamp value.
242 * @return Timestamp
243 */
244 explicit inline operator double() const;
245
246 /**
247 * Hash function.
248 * @param timestamp The timestamp for which the hash value will be determined
249 * @return The resulting hash value
250 */
251 inline size_t operator()(const Timestamp& timestamp) const;
252
253 /**
254 * Converts seconds to milliseconds.
255 * @param seconds The seconds to convert, with range (-infinity, infinity)
256 * @return The resulting milliseconds
257 */
258 static constexpr int64_t seconds2milliseconds(const double seconds);
259
260 /**
261 * Converts seconds to microseconds.
262 * @param seconds The seconds to convert, with range (-infinity, infinity)
263 * @return The resulting microseconds
264 */
265 static constexpr int64_t seconds2microseconds(const double seconds);
266
267 /**
268 * Converts seconds to nanoseconds.
269 * @param seconds The seconds to convert, with range (-infinity, infinity)
270 * @return The resulting nanoseconds
271 */
272 static constexpr int64_t seconds2nanoseconds(const double seconds);
273
274 /**
275 * Converts milliseconds to seconds.
276 * @param milliseconds The milliseconds to convert, with range (-infinity, infinity)
277 * @return The resulting seconds
278 */
279 static constexpr double milliseconds2seconds(const int64_t milliseconds);
280
281 /**
282 * Converts microseconds to seconds.
283 * @param microseconds The microseconds to convert, with range (-infinity, infinity)
284 * @return The resulting seconds
285 */
286 static constexpr double microseconds2seconds(const int64_t microseconds);
287
288 /**
289 * Converts nanoseconds to seconds.
290 * @param nanoseconds The nanoseconds to convert, with range (-infinity, infinity)
291 * @return The resulting seconds
292 */
293 static constexpr double nanoseconds2seconds(const int64_t nanoseconds);
294
295 protected:
296
297 /**
298 * Returns the of an invalid timestamp.
299 * @return Invalid timestamp value
300 */
301 static constexpr double invalidTimestampValue();
302
303 protected:
304
305 /// Timestamp value.
306 double value_ = invalidTimestampValue();
307};
308
309/**
310 * This class is a helper class allowing to converter timestamps defined in a specific time domain to unix timestamps.
311 */
312class OCEAN_BASE_EXPORT TimestampConverter
313{
314 public:
315
316 /**
317 * Definition of individual time domains.
318 */
319 enum TimeDomain : uint32_t
320 {
321 /// An invalid time domain.
322 TD_INVALID = 0u,
323 /// The monotonically increasing time domain defined in nanoseconds, not increasing during system sleep.
324 TD_MONOTONIC = 1u,
325
326#ifdef OCEAN_BASE_TIMESTAMP_BOOTTIME_AVAILABLE
327 /// The monotonically increasing time domain defined in nanoseconds, increasing during system sleep, not available on Windows.
328 TD_BOOTTIME = 2u,
329#endif
330
331#ifdef OCEAN_BASE_TIMESTAMP_UPTIMERAW_AVAILABLE
332 /// The monotonically increasing time domain defined in nanoseconds, the time the system has been awake since the last time it was restarted.
333 TD_UPTIME_RAW = 3u,
334#endif
335
336#ifdef OCEAN_BASE_TIMESTAMP_VIRTUAL_COUNTER_REGISTER_AVAILABLE
337 TD_VIRTUAL_COUNTER_REGISTER = 4u,
338#endif
339
340#ifdef OCEAN_BASE_TIMESTAMP_CUSTOM_POSIX_AVAILABLE
341 /// A custom POSIX clock id specified by the user.
342 TD_CUSTOM_POSIX = 5u
343#endif
344 };
345
346 /**
347 * Definition of an invalid value.
348 */
349 static constexpr int64_t invalidValue_ = std::numeric_limits<int64_t>::lowest();
350
351 protected:
352
353 /**
354 * This class encapsulates the logic for calculating the offset between a domain time and unix time.
355 * The calculator gathers timestamp pairs (domain and unix) and computes an averaged offset to reduce measurement noise.
356 * Two modes are supported:
357 * - Fixed mode: Accumulates measurements until the necessary count is reached, then the offset becomes final.
358 * - Sliding window mode: Continuously updates the offset using the most recent N measurements.
359 */
361 {
362 protected:
363
364 /**
365 * Definition of a double-ended queue holding offsets between the domain time and the unix time.
366 */
367 using OffsetQueue = std::deque<int64_t>;
368
369 public:
370
371 /**
372 * Default constructor creating an invalid calculator.
373 */
374 OffsetCalculator() = default;
375
376 /**
377 * Creates a new offset calculator.
378 * @param necessaryMeasurements The number of measurements necessary to determine the offset, with range [1, infinity)
379 * @param useSlidingWindow True, to use a sliding window for continuous offset updates; False, to fix the offset after necessaryMeasurements
380 */
381 OffsetCalculator(const size_t necessaryMeasurements, const bool useSlidingWindow);
382
383 /**
384 * Calculates the domain-to-unix offset based on a new pair of timestamps.
385 * This function accumulates measurements and returns the current averaged offset.
386 * In fixed mode, once the necessary number of measurements is reached, isFinal is set to true.
387 * In sliding window mode, isFinal is never set to true (the offset is continuously updated).
388 * @param currentDomainTimestampNs The current domain timestamp, in nanoseconds
389 * @param currentUnixTimestampNs The current unix timestamp, in nanoseconds
390 * @param isFinal Output parameter set to true when the offset is finalized (only in fixed mode)
391 * @return The averaged domain-to-unix offset, in nanoseconds
392 */
393 int64_t domainToUnixOffsetNs(const int64_t currentDomainTimestampNs, const int64_t currentUnixTimestampNs, bool& isFinal);
394
395 /**
396 * Returns the number of measurements accumulated so far.
397 * In sliding window mode, this is capped at necessaryMeasurements.
398 * @return The number of measurements
399 */
400 inline size_t measurements() const;
401
402 /**
403 * Returns whether this calculator is valid.
404 * @return True, if the calculator was initialized with valid parameters
405 */
406 inline bool isValid() const;
407
408 protected:
409
410 /// The initial domain timestamp, in nanoseconds.
411 int64_t initialDomainNs_ = invalidValue_;
412
413 /// The initial unix timestamp, in nanoseconds.
414 int64_t initialUnixNs_ = invalidValue_;
415
416 /// The measured sum of the domain to unix offsets, in nanoseconds.
417 int64_t sumDomainToUnixOffsetNs_ = 0;
418
419 /// The number of measurements.
420 size_t measurements_ = 0;
421
422 /// The number of necessary measurements before the converter keeps the determined offset fixed.
423 size_t necessaryMeasurements_ = 0;
424
425 /// True, if a sliding window is used to determine the average offset; False, to determine the average offset once based on several measurements.
426 bool useSlidingWindow_ = false;
427
428 /// The queue holding the domain to unix offsets, in case a sliding window is used to determine the average offset, in nanoseconds.
430 };
431
432 public:
433
434 /**
435 * Creates an invalid converter object.
436 * @see isValid().
437 */
439
440 /**
441 * Default destructor.
442 */
444
445 /**
446 * Creates a new converter object for a specific time domain.
447 * @param timeDomain The time domain for which the converter will be created
448 * @param useSlidingWindow True, to continuously update the offset using a sliding window of the most recent measurements; False, to fix the offset after necessaryMeasurements
449 * @param necessaryMeasurements The number of measurements necessary to determine the offset between the domain time and the unix time, with range [1, infinity)
450 */
451 TimestampConverter(const TimeDomain timeDomain, const bool useSlidingWindow, const size_t necessaryMeasurements = 100);
452
453#ifdef OCEAN_BASE_TIMESTAMP_CUSTOM_POSIX_AVAILABLE
454
455 /**
456 * Creates a new converter object for a custom POSIX clock id.
457 * @param timeDomain The time domain for which the converter will be created, must be TD_CUSTOM_POSIX
458 * @param useSlidingWindow True, to continuously update the offset using a sliding window of the most recent measurements; False, to fix the offset after necessaryMeasurements
459 * @param customPosixClockId The custom POSIX clock id to use for time conversion
460 * @param necessaryMeasurements The number of measurements necessary to determine the offset between the domain time and the unix time, with range [1, infinity)
461 */
462 TimestampConverter(const TimeDomain timeDomain, const bool useSlidingWindow, const int customPosixClockId, const size_t necessaryMeasurements);
463
464#endif // OCEAN_BASE_TIMESTAMP_CUSTOM_POSIX_AVAILABLE
465
466 /**
467 * Move constructor.
468 * @param converter The converter to be moved
469 */
470 inline TimestampConverter(TimestampConverter&& converter) noexcept;
471
472 /**
473 * Converts a timestamp defined in the converter's time domain to a unix timestamp.
474 * @param domainTimestampNs The timestamp in the converter's time domain, in nanoseconds, with range (-infinity, infinity)
475 * @return The converted unix timestamp
476 */
477 Timestamp toUnix(const int64_t domainTimestampNs);
478
479 /**
480 * Converts a timestamp defined in the converter's time domain to a unix timestamp.
481 * @param domainTimestampSeconds The timestamp in the converter's time domain, in seconds, with range (-infinity, infinity)
482 * @return The converted unix timestamp
483 */
484 Timestamp toUnix(const double domainTimestampSeconds);
485
486 /**
487 * Returns whether a given domain timestamp is within a specified range of the current domain timestamp.
488 * @param domainTimestampNs The domain timestamp to check, in nanoseconds, with range (-infinity, infinity)
489 * @param maxDistance The maximal distance between the domain timestamp and the current domain timestamp, in seconds, with range [0, infinity)
490 * @param distance Optional resulting distance between the domain timestamp and the current domain timestamp, in seconds, with range (-infinity, infinity)
491 * @return True, if so
492 */
493 bool isWithinRange(const int64_t domainTimestampNs, const double maxDistance = 1.0, double* distance = nullptr);
494
495 /**
496 * Returns the current timestamp in the time domain of this converter.
497 * @return The current timestamp in the converter's time domain, in nanoseconds, invalidValue_ in case of an error
498 */
500
501 /**
502 * Returns the time domain of this converter.
503 * @return The converter's time domain
504 */
505 inline TimeDomain timeDomain() const;
506
507 /**
508 * Returns the offset between the domain time and the unix time, in nanoseconds.
509 * Unix time = domain time + domainToUnixOffset
510 * @return The offset between the domain time and the unix time, in nanoseconds, with range (-infinity, infinity)
511 */
513
514 /**
515 * Returns the number of measurements.
516 * @return The converter's number of measurements
517 */
518 inline size_t measurements() const;
519
520 /**
521 * Returns whether this converter has been initialized with a valid time domain.
522 * @return True, if so
523 */
524 inline bool isValid() const;
525
526 /**
527 * Returns whether this converter is valid.
528 * @return True, if so
529 */
530 explicit inline operator bool() const;
531
532 /**
533 * Move operator.
534 * @param converter The converter to be moved
535 * @return Reference to this object
536 */
538
539 /**
540 * Returns the current timestamp in a specified time domain.
541 * @param timeDomain The time domain for which the current timestamp will be returned
542 * @return The current timestamp in the specified time domain, in nanoseconds
543 */
544 static int64_t currentDomainTimestampNs(const TimeDomain timeDomain);
545
546 /**
547 * Converts a timestamp which is defined in seconds to a timestamp which is defined in nanoseconds.
548 * The timestamp is defined by (timeValue / timeDenominator) * 1s.<br>
549 * The resulting timestamp will be (newTimeValue / 1000000000) * 1s.
550 * @param timeValue The time value, in seconds, with range (-infinity, infinity)
551 * @param timeDenominator The denominator corresponding to the time value (sometimes call time scale), with range [1, infinity)
552 * @return The resulting timestamp in nanoseconds, with range (-infinity, infinity)
553 */
554 static int64_t timestampInNs(const int64_t timeValue, const int64_t timeDenominator);
555
556#ifndef OCEAN_PLATFORM_BUILD_WINDOWS
557
558 /**
559 * Return the current timestamp in a specified POSIX clock id.
560 * @param posixClockId The POSIX clock id for which the current timestamp will be returned
561 * @return The current timestamp in the specified POSIX clock id, in nanoseconds
562 */
563 static int64_t currentTimestampNs(const int posixClockId);
564
565 protected:
566
567 /**
568 * Disabled copy constructor.
569 */
571
572 /**
573 * Disabled copy operator.
574 * @return Reference to this object
575 */
577
578 /**
579 * Returns the POSIX clock id associated with a time domain.
580 * @param timeDomain The time domain for which the associated POSIX clock id will be returned
581 * @return The POSIX clock id associated with the specified time domain, -1 if no associated POSIX clock id exists
582 */
583 static int posixClockId(const TimeDomain timeDomain);
584
585#endif // OCEAN_PLATFORM_BUILD_WINDOWS
586
587 protected:
588
589 /// The time domain of this converter.
590 TimeDomain timeDomain_ = TD_INVALID;
591
592 /// The average offset between the domain time and the unix time, in nanoseconds.
593 std::atomic_int64_t domainToUnixOffsetNs_ = invalidValue_;
594
595 /// The calculator used to determine the offset between the domain time and the unix time.
597
598 /// Counter used to alternate the order of domain/unix timestamp sampling, reducing systematic measurement bias.
599 std::atomic<size_t> toggleCounter_ = 0;
600
601 /// The optional frequency of the domain time, in Hz (in case the domain time is not defined in nanoseconds).
602 uint64_t domainFrequency_ = 0ull;
603
604 /// The converter's lock.
605 mutable Lock lock_;
606
607#ifndef OCEAN_PLATFORM_BUILD_WINDOWS
608 /// The POSIX clock id associated with the time domain.
609 int domainPosixClockId_ = -1;
610#endif
611};
612
613inline Timestamp::Timestamp(const double timestamp) :
614 value_(timestamp)
615{
616 // nothing to do here
617}
618
620{
622
623 return *this;
624}
625
626inline int64_t Timestamp::nanoseconds() const
627{
628 ocean_assert(isValid());
629
631}
632
633inline bool Timestamp::hasTimePassed(const double seconds, const Timestamp& currentTimestamp) const
634{
635 ocean_assert(seconds >= 0.0);
636 ocean_assert(currentTimestamp.isValid());
637
638 if (!isValid())
639 {
640 return true;
641 }
642
643 return double(*this) + seconds <= double(currentTimestamp);
644}
645
646inline bool Timestamp::isValid() const
647{
648 return value_ != invalidTimestampValue();
649}
650
651inline bool Timestamp::isInvalid() const
652{
653 return value_ == invalidTimestampValue();
654}
655
656inline Timestamp& Timestamp::operator=(const double timestamp)
657{
658 value_ = timestamp;
659
660 return *this;
661}
662
663inline Timestamp Timestamp::operator+(const Timestamp& right) const
664{
665 return Timestamp(value_ + right.value_);
666}
667
669{
670 value_ += right.value_;
671
672 return *this;
673}
674
675inline Timestamp Timestamp::operator+(const double seconds) const
676{
677 return Timestamp(value_ + seconds);
678}
679
680inline Timestamp& Timestamp::operator+=(const double seconds)
681{
682 value_ += seconds;
683
684 return *this;
685}
686
687inline Timestamp Timestamp::operator-(const Timestamp& right) const
688{
689 return Timestamp(value_ - right.value_);
690}
691
693{
694 value_ -= right.value_;
695
696 return *this;
697}
698
699inline Timestamp Timestamp::operator-(const double seconds) const
700{
701 return Timestamp(value_ - seconds);
702}
703
704inline Timestamp& Timestamp::operator-=(const double seconds)
705{
706 value_ -= seconds;
707
708 return *this;
709}
710
711inline bool Timestamp::operator<(const Timestamp& right) const
712{
713 return value_ < right.value_;
714}
715
716inline bool Timestamp::operator<=(const Timestamp& right) const
717{
718 return value_ <= right.value_;
719}
720
721inline bool Timestamp::operator>(const Timestamp& right) const
722{
723 return value_ > right.value_;
724}
725
726inline bool Timestamp::operator>=(const Timestamp& right) const
727{
728 return value_ >= right.value_;
729}
730
731inline bool Timestamp::operator==(const Timestamp& right) const
732{
733 return value_ == right.value_;
734}
735
736inline bool Timestamp::operator!=(const Timestamp& right) const
737{
738 return value_ != right.value_;
739}
740
741inline Timestamp::operator double() const
742{
743 return value_;
744}
745
746inline size_t Timestamp::operator()(const Timestamp& timestamp) const
747{
748 return std::hash<double>{}(double(timestamp));
749}
750
751constexpr int64_t Timestamp::seconds2milliseconds(const double seconds)
752{
753 // 1000 milliseconds = 1 second
754
755 if (seconds >= 0.0)
756 {
757 return int64_t(seconds * double(millisecondsPerSecond_) + 0.5);
758 }
759 else
760 {
761 return int64_t(seconds * double(millisecondsPerSecond_) - 0.5);
762 }
763}
764
765constexpr int64_t Timestamp::seconds2microseconds(const double seconds)
766{
767 // 1000 milliseconds = 1 second
768 // 1000 microseconds = 1 milliseconds
769
770 if (seconds >= 0.0)
771 {
772 return int64_t(seconds * double(microsecondsPerSecond_) + 0.5);
773 }
774 else
775 {
776 return int64_t(seconds * double(microsecondsPerSecond_) - 0.5);
777 }
778}
779
780constexpr int64_t Timestamp::seconds2nanoseconds(const double seconds)
781{
782 // 1000 milliseconds = 1 second
783 // 1000 microseconds = 1 milliseconds
784 // 1000 nanoseconds = 1 microseconds
785
786 if (seconds >= 0.0)
787 {
788 return int64_t(seconds * double(nanosecondsPerSecond_) + 0.5);
789 }
790 else
791 {
792 return int64_t(seconds * double(nanosecondsPerSecond_) - 0.5);
793 }
794}
795
796constexpr double Timestamp::milliseconds2seconds(const int64_t milliseconds)
797{
798 return double(milliseconds) / double(millisecondsPerSecond_);
799}
800
801constexpr double Timestamp::microseconds2seconds(const int64_t microseconds)
802{
803 return double(microseconds) / double(microsecondsPerSecond_);
804}
805
806constexpr double Timestamp::nanoseconds2seconds(const int64_t nanoseconds)
807{
808 return double(nanoseconds) / double(nanosecondsPerSecond_);
809}
810
812{
813 return -DBL_MAX;
814}
815
817{
818 return measurements_;
819}
820
822{
823 return necessaryMeasurements_ != 0;
824}
825
827{
828 *this = std::move(converter);
829}
830
835
837{
838 const ScopedLock scopedLock(lock_);
839
841}
842
844{
846}
847
848inline TimestampConverter::operator bool() const
849{
850 return isValid();
851}
852
853}
854
855#endif // META_OCEAN_BASE_TIMESTAMP_H
This class implements a recursive lock object.
Definition Lock.h:31
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:147
This class encapsulates the logic for calculating the offset between a domain time and unix time.
Definition Timestamp.h:361
OffsetCalculator(const size_t necessaryMeasurements, const bool useSlidingWindow)
Creates a new offset calculator.
int64_t domainToUnixOffsetNs(const int64_t currentDomainTimestampNs, const int64_t currentUnixTimestampNs, bool &isFinal)
Calculates the domain-to-unix offset based on a new pair of timestamps.
std::deque< int64_t > OffsetQueue
Definition of a double-ended queue holding offsets between the domain time and the unix time.
Definition Timestamp.h:367
OffsetQueue domainToUnixOffsetQueueNs_
The queue holding the domain to unix offsets, in case a sliding window is used to determine the avera...
Definition Timestamp.h:429
size_t measurements_
The number of measurements.
Definition Timestamp.h:420
OffsetCalculator()=default
Default constructor creating an invalid calculator.
size_t measurements() const
Returns the number of measurements accumulated so far.
Definition Timestamp.h:816
bool isValid() const
Returns whether this calculator is valid.
Definition Timestamp.h:821
This class is a helper class allowing to converter timestamps defined in a specific time domain to un...
Definition Timestamp.h:313
~TimestampConverter()=default
Default destructor.
static int64_t currentDomainTimestampNs(const TimeDomain timeDomain)
Returns the current timestamp in a specified time domain.
TimestampConverter(const TimeDomain timeDomain, const bool useSlidingWindow, const int customPosixClockId, const size_t necessaryMeasurements)
Creates a new converter object for a custom POSIX clock id.
static int posixClockId(const TimeDomain timeDomain)
Returns the POSIX clock id associated with a time domain.
TimestampConverter(const TimeDomain timeDomain, const bool useSlidingWindow, const size_t necessaryMeasurements=100)
Creates a new converter object for a specific time domain.
int64_t currentDomainTimestampNs() const
Returns the current timestamp in the time domain of this converter.
OffsetCalculator offsetCalculator_
The calculator used to determine the offset between the domain time and the unix time.
Definition Timestamp.h:596
TimeDomain timeDomain_
The time domain of this converter.
Definition Timestamp.h:590
size_t measurements() const
Returns the number of measurements.
Definition Timestamp.h:836
TimestampConverter & operator=(const TimestampConverter &)=delete
Disabled copy operator.
Timestamp toUnix(const double domainTimestampSeconds)
Converts a timestamp defined in the converter's time domain to a unix timestamp.
TimestampConverter(const TimestampConverter &)=delete
Disabled copy constructor.
Timestamp toUnix(const int64_t domainTimestampNs)
Converts a timestamp defined in the converter's time domain to a unix timestamp.
TimestampConverter()=default
Creates an invalid converter object.
static int64_t timestampInNs(const int64_t timeValue, const int64_t timeDenominator)
Converts a timestamp which is defined in seconds to a timestamp which is defined in nanoseconds.
int64_t domainToUnixOffset()
Returns the offset between the domain time and the unix time, in nanoseconds.
bool isValid() const
Returns whether this converter has been initialized with a valid time domain.
Definition Timestamp.h:843
bool isWithinRange(const int64_t domainTimestampNs, const double maxDistance=1.0, double *distance=nullptr)
Returns whether a given domain timestamp is within a specified range of the current domain timestamp.
TimeDomain timeDomain() const
Returns the time domain of this converter.
Definition Timestamp.h:831
TimeDomain
Definition of individual time domains.
Definition Timestamp.h:320
@ TD_INVALID
An invalid time domain.
Definition Timestamp.h:322
TimestampConverter & operator=(TimestampConverter &&converter) noexcept
Move operator.
Lock lock_
The converter's lock.
Definition Timestamp.h:605
static int64_t currentTimestampNs(const int posixClockId)
Return the current timestamp in a specified POSIX clock id.
This class implements a timestamp.
Definition Timestamp.h:64
bool operator>=(const Timestamp &right) const
Returns whether the this timestamp is greater or equal to the right one.
Definition Timestamp.h:726
static constexpr int64_t seconds2milliseconds(const double seconds)
Converts seconds to milliseconds.
Definition Timestamp.h:751
bool isValid() const
Returns whether the timestamp holds a valid time.
Definition Timestamp.h:646
size_t operator()(const Timestamp &timestamp) const
Hash function.
Definition Timestamp.h:746
static constexpr int64_t millisecondsPerSecond_
Definition of the number of milliseconds in one second.
Definition Timestamp.h:68
static constexpr double nanoseconds2seconds(const int64_t nanoseconds)
Converts nanoseconds to seconds.
Definition Timestamp.h:806
bool operator!=(const Timestamp &right) const
Returns whether two timestamps are not identical.
Definition Timestamp.h:736
Timestamp(const bool toNow)
Creates a new timestamp.
static constexpr int64_t seconds2microseconds(const double seconds)
Converts seconds to microseconds.
Definition Timestamp.h:765
static constexpr double microseconds2seconds(const int64_t microseconds)
Converts microseconds to seconds.
Definition Timestamp.h:801
bool hasTimePassed(const double seconds, const Timestamp &currentTimestamp=Timestamp(true)) const
Returns whether a specified amount of time has passed since this timestamp.
Definition Timestamp.h:633
Timestamp & toInvalid()
Sets the timestamp to invalid.
Definition Timestamp.h:619
bool operator<=(const Timestamp &right) const
Returns whether the this timestamp is lesser or equal to the right one.
Definition Timestamp.h:716
bool operator==(const Timestamp &right) const
Returns whether two timestamps are identical.
Definition Timestamp.h:731
double value_
Timestamp value.
Definition Timestamp.h:306
static constexpr int64_t nanosecondsPerSecond_
Definition of the number of nanoseconds in one second.
Definition Timestamp.h:74
int64_t nanoseconds() const
Returns this timestamp in nanoseconds.
Definition Timestamp.h:626
bool operator>(const Timestamp &right) const
Returns whether the this timestamp is greater than the right one.
Definition Timestamp.h:721
bool operator<(const Timestamp &right) const
Returns whether the this timestamp is lesser than the right one.
Definition Timestamp.h:711
Timestamp operator-(const Timestamp &right) const
Subtracts two timestamps.
Definition Timestamp.h:687
Timestamp operator+(const Timestamp &right) const
Adds two timestamps.
Definition Timestamp.h:663
Timestamp & operator+=(const Timestamp &right)
Adds and assigns two timestamps.
Definition Timestamp.h:668
static constexpr int64_t seconds2nanoseconds(const double seconds)
Converts seconds to nanoseconds.
Definition Timestamp.h:780
bool isInvalid() const
Returns whether the timestamp holds an invalid time.
Definition Timestamp.h:651
Timestamp()=default
Creates a new timestamp with invalid time.
static constexpr double invalidTimestampValue()
Returns the of an invalid timestamp.
Definition Timestamp.h:811
Timestamp & toNow()
Sets the timestamp to the current time.
static constexpr int64_t microsecondsPerSecond_
Definition of the number of microseconds in one second.
Definition Timestamp.h:71
static constexpr double milliseconds2seconds(const int64_t milliseconds)
Converts milliseconds to seconds.
Definition Timestamp.h:796
Timestamp & operator=(const double timestamp)
Assign a new value.
Definition Timestamp.h:656
Timestamp & operator-=(const Timestamp &right)
Subtracts and assigns two timestamps.
Definition Timestamp.h:692
std::vector< Timestamp > Timestamps
Definition of a vector holding Timestamp objects.
Definition Timestamp.h:54
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
AutomaticDifferentiationT< T1, TNumeric1 > operator+(const T2 &left, const AutomaticDifferentiationT< T1, TNumeric1 > &right)
Definition AutomaticDifferentiation.h:418
AutomaticDifferentiationT< T1, TNumeric1 > operator-(const T2 &left, const AutomaticDifferentiationT< T1, TNumeric1 > &right)
Definition AutomaticDifferentiation.h:484