25#ifndef FEATURES_TIMESTAMP_H
26#define FEATURES_TIMESTAMP_H
43#include <mach/mach_time.h>
45#elif defined(_WIN32) || defined(_WIN64)
46#ifndef WIN32_LEAN_AND_MEAN
47#define WIN32_LEAN_AND_MEAN
112 template <
typename Rep,
typename Period>
113 constexpr explicit Duration(
const std::chrono::duration<Rep, Period>& duration) noexcept
114 : _duration(std::chrono::duration_cast<chrono_duration>(duration).
count()) {}
136 template <
typename TargetDuration>
137 [[nodiscard]]
constexpr TargetDuration
to() const noexcept {
138 return std::chrono::duration_cast<TargetDuration>(
to_chrono());
210 [[nodiscard]]
constexpr rep days() const noexcept {
211 return _duration / (86400 * 1000000000LL);
219 return static_cast<double>(_duration) / (86400.0 * 1000000000.0);
226 [[nodiscard]]
constexpr rep hours() const noexcept {
227 return _duration / (3600 * 1000000000LL);
235 return static_cast<double>(_duration) / (3600.0 * 1000000000.0);
243 return _duration / (60 * 1000000000LL);
251 return static_cast<double>(_duration) / (60.0 * 1000000000.0);
259 return _duration / 1000000000LL;
267 return static_cast<double>(_duration) / 1000000000.0;
275 return _duration / 1000000LL;
283 return static_cast<double>(_duration) / 1000000.0;
291 return _duration / 1000LL;
299 return static_cast<double>(_duration) / 1000.0;
315 return static_cast<double>(_duration);
322 [[nodiscard]]
constexpr rep count() const noexcept {
328 constexpr Duration operator-() const noexcept {
return Duration(-_duration); }
332 _duration += other._duration;
337 _duration -= other._duration;
341 constexpr Duration& operator*=(
rep multiplier)
noexcept {
342 _duration *= multiplier;
346 constexpr Duration& operator/=(
rep divisor)
noexcept {
347 _duration /= divisor;
352 _duration %= other._duration;
357 constexpr bool operator==(
const Duration& rhs)
const noexcept {
358 return count() == rhs.count();
361 constexpr bool operator!=(
const Duration& rhs)
const noexcept {
362 return count() != rhs.count();
365 constexpr bool operator<(
const Duration& rhs)
const noexcept {
366 return count() < rhs.count();
369 constexpr bool operator<=(
const Duration& rhs)
const noexcept {
370 return count() <= rhs.count();
373 constexpr bool operator>(
const Duration& rhs)
const noexcept {
374 return count() > rhs.count();
377 constexpr bool operator>=(
const Duration& rhs)
const noexcept {
378 return count() >= rhs.count();
394 return Duration(lhs.count() + rhs.count());
405 return Duration(lhs.count() - rhs.count());
449 return lhs.count() / rhs.count();
471 return Duration(lhs.count() % rhs.count());
482 constexpr Duration operator""_d(
unsigned long long days)
noexcept {
492 constexpr Duration operator""_h(
unsigned long long hours)
noexcept {
502 constexpr Duration operator""_min(
unsigned long long minutes)
noexcept {
512 constexpr Duration operator""_s(
unsigned long long seconds)
noexcept {
522 constexpr Duration operator""_ms(
unsigned long long milliseconds)
noexcept {
532 constexpr Duration operator""_us(
unsigned long long microseconds)
noexcept {
542 constexpr Duration operator""_ns(
unsigned long long nanoseconds)
noexcept {
562 std::chrono::duration<rep, std::nano>>;
585 template <
typename Clock,
typename ChronoDuration>
586 explicit TimePoint(
const std::chrono::time_point<Clock, ChronoDuration>& time_point) noexcept
588 time_point.time_since_epoch()).count()) {}
604 static const auto system_start = std::chrono::system_clock::now();
605 static const auto steady_start = std::chrono::steady_clock::now();
607 auto steady_now = std::chrono::steady_clock::now();
608 auto delta = steady_now - steady_start;
609 auto result = system_start + delta;
619 return std::chrono::time_point<std::chrono::system_clock>() +
629 template <
typename Clock,
typename ChronoDuration =
typename Clock::duration>
630 [[nodiscard]] std::chrono::time_point<Clock, ChronoDuration>
631 to() const noexcept {
632 using target_tp = std::chrono::time_point<Clock, ChronoDuration>;
633 return std::chrono::time_point_cast<ChronoDuration>(
634 target_tp(std::chrono::duration_cast<ChronoDuration>(
706 [[nodiscard]]
static std::optional<TimePoint>
from_iso8601(std::string_view iso8601)
noexcept {
709 std::string str_iso8601(iso8601);
710 std::istringstream iss(str_iso8601);
711 iss >> std::get_time(&tm,
"%Y-%m-%dT%H:%M:%SZ");
731 [[nodiscard]]
static std::optional<TimePoint>
parse(
732 std::string_view time_string, std::string_view
format)
noexcept {
735 std::string str_time_string(time_string);
736 std::istringstream iss(str_time_string);
737 iss >> std::get_time(&tm,
format.data());
757 [[nodiscard]]
constexpr rep days() const noexcept {
773 [[nodiscard]]
constexpr rep hours() const noexcept {
877 [[nodiscard]]
constexpr rep count() const noexcept {
887 const auto time_t_value =
static_cast<std::time_t
>(
seconds());
891 gmtime_s(&tm, &time_t_value);
893 tm = *std::gmtime(&time_t_value);
896 std::array<char, 128> buffer{};
897 const auto result = std::strftime(buffer.data(), buffer.size(),
format.data(), &tm);
903 return std::string(buffer.data(), result);
911 return format(
"%Y-%m-%dT%H:%M:%SZ");
921#elif defined(__i386__)
923 __asm__
volatile(
".byte 0x0f, 0x31" :
"=A"(x));
925#elif defined(__x86_64__)
927 __asm__ __volatile__(
"rdtsc" :
"=a"(lo),
"=d"(hi));
928 return ((uint64_t)lo) | (((uint64_t)hi) << 32ULL);
931 const auto now = std::chrono::high_resolution_clock::now();
932 return std::chrono::duration_cast<std::chrono::nanoseconds>(
933 now.time_since_epoch()).count();
961 static uint64_t
nano() noexcept {
1027 return lhs.count() == rhs.count();
1038 return lhs.count() != rhs.count();
1049 return lhs.count() < rhs.count();
1060 return lhs.count() <= rhs.count();
1071 return lhs.count() > rhs.count();
1082 return lhs.count() >= rhs.count();
1163 const auto time_t_value =
static_cast<std::time_t
>(
seconds());
1166#if defined(_MSC_VER)
1167 localtime_s(&tm, &time_t_value);
1169 tm = *std::localtime(&time_t_value);
1172 std::array<char, 128> buffer{};
1173 const auto result = std::strftime(buffer.data(), buffer.size(),
format.data(), &tm);
1179 return std::string(buffer.data(), result);
1236 static const auto tsc_frequency = calibrate_tsc_frequency();
1239 const auto seconds_elapsed =
static_cast<double>(tsc_elapsed) / tsc_frequency;
1240 const auto nanoseconds_elapsed =
static_cast<uint64_t
>(seconds_elapsed * 1e9);
1242 return TscTimePoint(system_time_at_init.count() + nanoseconds_elapsed);
1250 static double calibrate_tsc_frequency() noexcept {
1255 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1260 const auto time_diff_ns = end_time.count() - start_time.count();
1261 const auto tsc_diff = end_tsc - start_tsc;
1263 return static_cast<double>(tsc_diff) * 1e9 /
static_cast<double>(time_diff_ns);
1308 using TimerCallback = std::function<void(
Duration)>;
1316 , _callback(std::move(callback))
1339 _callback(_elapsed);
1373 TimerCallback _callback;
1392 : _reason(std::move(reason))
1393 , _timer([this](
Duration duration) {
1394 qb::io::cout() << _reason <<
": " << duration.microseconds() <<
"us" << std::endl;
1402 return _timer.elapsed();
1406 std::string _reason;
1433 auto nanoseconds = d.
nanoseconds() % 1000000000LL;
1435 if (nanoseconds == 0) {
1436 return os << seconds <<
"s";
1437 }
else if (nanoseconds % 1000000LL == 0) {
1438 return os << seconds <<
"s " << (nanoseconds / 1000000LL) <<
"ms";
1439 }
else if (nanoseconds % 1000LL == 0) {
1440 return os << seconds <<
"s " << (nanoseconds / 1000LL) <<
"us";
1442 return os << seconds <<
"s " << nanoseconds <<
"ns";
1458 struct hash<qb::Duration> {
1465 return std::hash<int64_t>{}(duration.count());
1479 struct hash<qb::TimePoint> {
1486 return std::hash<uint64_t>{}(time_point.count());
1492#if __cplusplus >= 202002L
1495 struct formatter<qb::TimePoint> {
1496 constexpr auto parse(format_parse_context& ctx) {
1500 auto format(
const qb::TimePoint& tp, format_context& ctx)
const {
1501 return format_to(ctx.out(),
"{}", tp.
to_iso8601());
1506 struct formatter<qb::Duration> {
1507 constexpr auto parse(format_parse_context& ctx) {
1511 auto format(
const qb::Duration& d, format_context& ctx)
const {
1513 auto nanoseconds = d.
nanoseconds() % 1000000000LL;
1515 if (nanoseconds == 0) {
1516 return format_to(ctx.out(),
"{}s", seconds);
1517 }
else if (nanoseconds % 1000000LL == 0) {
1518 return format_to(ctx.out(),
"{}s {}ms", seconds, nanoseconds / 1000000LL);
1519 }
else if (nanoseconds % 1000LL == 0) {
1520 return format_to(ctx.out(),
"{}s {}us", seconds, nanoseconds / 1000LL);
1522 return format_to(ctx.out(),
"{}s {}ns", seconds, nanoseconds);
Represents a duration with nanosecond precision.
Definition timestamp.h:85
constexpr double minutes_float() const noexcept
Gets the duration in minutes with fractional precision.
Definition timestamp.h:250
constexpr rep minutes() const noexcept
Gets the duration in minutes.
Definition timestamp.h:242
constexpr rep seconds() const noexcept
Gets the duration in seconds.
Definition timestamp.h:258
constexpr double nanoseconds_float() const noexcept
Gets the duration in nanoseconds with double precision.
Definition timestamp.h:314
constexpr rep days() const noexcept
Gets the duration in days.
Definition timestamp.h:210
static constexpr Duration from_nanoseconds(rep ns) noexcept
Factory method to create a Duration from nanoseconds.
Definition timestamp.h:200
constexpr double hours_float() const noexcept
Gets the duration in hours with fractional precision.
Definition timestamp.h:234
constexpr TargetDuration to() const noexcept
Converts to any std::chrono::duration.
Definition timestamp.h:137
static constexpr Duration from_microseconds(rep us) noexcept
Factory method to create a Duration from microseconds.
Definition timestamp.h:191
constexpr double days_float() const noexcept
Gets the duration in days with fractional precision.
Definition timestamp.h:218
constexpr double seconds_float() const noexcept
Gets the duration in seconds with fractional precision.
Definition timestamp.h:266
static constexpr Duration from_hours(rep hours) noexcept
Factory method to create a Duration from hours.
Definition timestamp.h:155
static constexpr Duration from_days(rep days) noexcept
Factory method to create a Duration from days.
Definition timestamp.h:146
int64_t rep
Type used for nanosecond representation.
Definition timestamp.h:88
constexpr rep milliseconds() const noexcept
Gets the duration in milliseconds.
Definition timestamp.h:274
constexpr Duration() noexcept=default
Default constructor, initializes to zero.
constexpr double milliseconds_float() const noexcept
Gets the duration in milliseconds with fractional precision.
Definition timestamp.h:282
static constexpr Duration zero() noexcept
Represents zero duration.
Definition timestamp.h:94
static constexpr Duration from_milliseconds(rep ms) noexcept
Factory method to create a Duration from milliseconds.
Definition timestamp.h:182
static constexpr Duration from_seconds(rep seconds) noexcept
Factory method to create a Duration from seconds.
Definition timestamp.h:173
constexpr rep nanoseconds() const noexcept
Gets the duration in nanoseconds.
Definition timestamp.h:306
constexpr rep count() const noexcept
Gets the total duration in nanoseconds.
Definition timestamp.h:322
std::chrono::duration< rep, std::nano > chrono_duration
Underlying chrono duration type (nanoseconds)
Definition timestamp.h:91
constexpr Duration(const std::chrono::duration< Rep, Period > &duration) noexcept
Constructs a duration from std::chrono::duration.
Definition timestamp.h:113
constexpr rep microseconds() const noexcept
Gets the duration in microseconds.
Definition timestamp.h:290
static constexpr Duration from_minutes(rep minutes) noexcept
Factory method to create a Duration from minutes.
Definition timestamp.h:164
constexpr double microseconds_float() const noexcept
Gets the duration in microseconds with fractional precision.
Definition timestamp.h:298
constexpr rep hours() const noexcept
Gets the duration in hours.
Definition timestamp.h:226
constexpr chrono_duration to_chrono() const noexcept
Converts to std::chrono::duration.
Definition timestamp.h:127
Represents a high-resolution time point.
Definition timestamp.h:1190
static HighResTimePoint now() noexcept
Gets current high-resolution time.
Definition timestamp.h:1203
constexpr TimePoint() noexcept=default
Default constructor, initializes to epoch.
HighResTimePoint()
Default constructor, initializes to current high-resolution time.
Definition timestamp.h:1197
Represents a local time point with nanosecond precision.
Definition timestamp.h:1136
constexpr TimePoint() noexcept=default
Default constructor, initializes to epoch.
LocalTimePoint()
Default constructor, initializes to current local time.
Definition timestamp.h:1143
static LocalTimePoint now() noexcept
Gets current local time.
Definition timestamp.h:1149
std::string format_local(std::string_view format) const
Formats the time point as a local time string.
Definition timestamp.h:1162
LogTimer(std::string reason)
Constructs a timer with a descriptive reason.
Definition timestamp.h:1391
Duration elapsed() const
Gets elapsed time without stopping timer.
Definition timestamp.h:1401
Utility for measuring code block execution time.
Definition timestamp.h:1306
Duration elapsed() const
Gets elapsed time without stopping timer.
Definition timestamp.h:1357
Duration stop()
Stops the timer and invokes callback if active.
Definition timestamp.h:1330
ScopedTimer(TimerCallback callback)
Constructs a timer with a callback.
Definition timestamp.h:1314
~ScopedTimer()
Destructor that invokes callback with elapsed time.
Definition timestamp.h:1322
void restart()
Restarts the timer.
Definition timestamp.h:1348
Represents a point in time with nanosecond precision.
Definition timestamp.h:555
constexpr double minutes_float() const noexcept
Gets the time in minutes since epoch with fractional precision.
Definition timestamp.h:797
TimePoint(const std::chrono::time_point< Clock, ChronoDuration > &time_point) noexcept
Constructs a time point from std::chrono::time_point.
Definition timestamp.h:586
constexpr double hours_float() const noexcept
Gets the time in hours since epoch with fractional precision.
Definition timestamp.h:781
std::string format(std::string_view format) const
Formats the time point as a string.
Definition timestamp.h:886
constexpr double microseconds_float() const noexcept
Gets the time in microseconds since epoch with fractional precision.
Definition timestamp.h:845
constexpr rep nanoseconds() const noexcept
Gets the time in nanoseconds since epoch.
Definition timestamp.h:853
constexpr rep minutes() const noexcept
Gets the time in minutes since epoch.
Definition timestamp.h:789
constexpr double days_float() const noexcept
Gets the time in days since epoch with fractional precision.
Definition timestamp.h:765
rep _time_since_epoch
Time in nanoseconds since epoch.
Definition timestamp.h:966
static std::optional< TimePoint > from_iso8601(std::string_view iso8601) noexcept
Creates a TimePoint from ISO8601 string.
Definition timestamp.h:706
Duration time_since_epoch() const noexcept
Gets the duration since epoch.
Definition timestamp.h:869
constexpr rep seconds() const noexcept
Gets the time in seconds since epoch.
Definition timestamp.h:805
static constexpr TimePoint from_milliseconds(int64_t ms) noexcept
Factory method to create a TimePoint from milliseconds since epoch.
Definition timestamp.h:679
constexpr TimePoint() noexcept=default
Default constructor, initializes to epoch.
constexpr rep hours() const noexcept
Gets the time in hours since epoch.
Definition timestamp.h:773
static TimePoint now() noexcept
Gets current system time.
Definition timestamp.h:601
chrono_time_point to_chrono() const noexcept
Converts to std::chrono::time_point.
Definition timestamp.h:618
TimePoint & operator-=(const Duration &duration) noexcept
Subtracts a duration from this time point.
Definition timestamp.h:952
TimePoint & operator+=(const Duration &duration) noexcept
Adds a duration to this time point.
Definition timestamp.h:942
static constexpr TimePoint from_days(int64_t days) noexcept
Factory method to create a TimePoint from days since epoch.
Definition timestamp.h:643
static constexpr TimePoint from_minutes(int64_t minutes) noexcept
Factory method to create a TimePoint from minutes since epoch.
Definition timestamp.h:661
constexpr rep days() const noexcept
Gets the time in days since epoch.
Definition timestamp.h:757
static constexpr TimePoint from_nanoseconds(int64_t ns) noexcept
Factory method to create a TimePoint from nanoseconds since epoch.
Definition timestamp.h:697
static constexpr TimePoint from_seconds(int64_t seconds) noexcept
Factory method to create a TimePoint from seconds since epoch.
Definition timestamp.h:670
constexpr double nanoseconds_float() const noexcept
Gets the time in nanoseconds since epoch with double precision.
Definition timestamp.h:861
constexpr rep count() const noexcept
Gets the total time in nanoseconds since epoch.
Definition timestamp.h:877
uint64_t rep
Type used for nanosecond representation.
Definition timestamp.h:558
std::string to_iso8601() const
Converts to ISO8601 string.
Definition timestamp.h:910
static constexpr TimePoint epoch() noexcept
Represents the epoch (1970-01-01 00:00:00 UTC)
Definition timestamp.h:565
static uint64_t nano() noexcept
Gets the current time in nanoseconds since epoch.
Definition timestamp.h:961
constexpr double milliseconds_float() const noexcept
Gets the time in milliseconds since epoch with fractional precision.
Definition timestamp.h:829
constexpr rep milliseconds() const noexcept
Gets the time in milliseconds since epoch.
Definition timestamp.h:821
std::chrono::time_point< Clock, ChronoDuration > to() const noexcept
Converts to any std::chrono::time_point.
Definition timestamp.h:631
static constexpr TimePoint from_microseconds(int64_t us) noexcept
Factory method to create a TimePoint from microseconds since epoch.
Definition timestamp.h:688
static uint64_t read_tsc() noexcept
Reads CPU timestamp counter.
Definition timestamp.h:918
std::chrono::time_point< std::chrono::system_clock, std::chrono::duration< rep, std::nano > > chrono_time_point
Underlying std::chrono time point type.
Definition timestamp.h:561
static constexpr TimePoint from_hours(int64_t hours) noexcept
Factory method to create a TimePoint from hours since epoch.
Definition timestamp.h:652
static std::optional< TimePoint > parse(std::string_view time_string, std::string_view format) noexcept
Factory method to parse a string into a TimePoint.
Definition timestamp.h:731
constexpr rep microseconds() const noexcept
Gets the time in microseconds since epoch.
Definition timestamp.h:837
constexpr double seconds_float() const noexcept
Gets the time in seconds since epoch with fractional precision.
Definition timestamp.h:813
Represents a time point based on CPU's timestamp counter.
Definition timestamp.h:1220
TscTimePoint()
Default constructor, initializes to current TSC time.
Definition timestamp.h:1227
static TscTimePoint now() noexcept
Gets current TSC time calibrated to system time.
Definition timestamp.h:1233
constexpr TimePoint() noexcept=default
Default constructor, initializes to epoch.
Represents a UTC time point with nanosecond precision.
Definition timestamp.h:1108
static UtcTimePoint now() noexcept
Gets current UTC time.
Definition timestamp.h:1121
constexpr TimePoint() noexcept=default
Default constructor, initializes to epoch.
UtcTimePoint()
Default constructor, initializes to current UTC time.
Definition timestamp.h:1115
Thread-safe console output class.
Definition io.h:100
constexpr Duration operator*(const Duration &lhs, Duration::rep rhs) noexcept
Multiplies a duration by a scalar value.
Definition timestamp.h:415
constexpr bool operator<(const TimePoint &lhs, const TimePoint &rhs) noexcept
Less than comparison for time points.
Definition timestamp.h:1048
constexpr bool operator<=(const TimePoint &lhs, const TimePoint &rhs) noexcept
Less than or equal comparison for time points.
Definition timestamp.h:1059
TscTimePoint RdtsTimestamp
Backward compatibility alias for TscTimePoint.
Definition timestamp.h:1297
constexpr Duration operator-(const Duration &lhs, const Duration &rhs) noexcept
Subtracts second duration from first.
Definition timestamp.h:404
constexpr bool operator>=(const TimePoint &lhs, const TimePoint &rhs) noexcept
Greater than or equal comparison for time points.
Definition timestamp.h:1081
TimePoint Timestamp
Backward compatibility alias for TimePoint.
Definition timestamp.h:1100
UtcTimePoint UtcTimestamp
Backward compatibility alias for UtcTimePoint.
Definition timestamp.h:1273
constexpr bool operator>(const TimePoint &lhs, const TimePoint &rhs) noexcept
Greater than comparison for time points.
Definition timestamp.h:1070
HighResTimePoint NanoTimestamp
Backward compatibility alias for HighResTimePoint.
Definition timestamp.h:1289
constexpr Duration operator/(const Duration &lhs, Duration::rep rhs) noexcept
Divides a duration by a scalar value.
Definition timestamp.h:437
Duration Timespan
Backward compatibility alias for Duration.
Definition timestamp.h:1092
LocalTimePoint LocalTimestamp
Backward compatibility alias for LocalTimePoint.
Definition timestamp.h:1281
std::ostream & operator<<(std::ostream &os, const qb::TimePoint &tp)
Stream insertion operator for TimePoint.
Definition timestamp.h:1420
constexpr Duration operator%(const Duration &lhs, Duration::rep rhs) noexcept
Calculates the remainder of dividing a duration by a scalar.
Definition timestamp.h:459
Core I/O and logging utilities for the qb framework.
string< std::max(_Size1, _Size2)> operator+(const string< _Size1 > &lhs, const string< _Size2 > &rhs) noexcept
Concatenation operator.
Definition string.h:1078
size_t operator()(const qb::Duration &duration) const noexcept
Hash function operator for Duration.
Definition timestamp.h:1464
size_t operator()(const qb::TimePoint &time_point) const noexcept
Hash function operator for TimePoint.
Definition timestamp.h:1485