11#include <promeki/config.h>
12#if PROMEKI_ENABLE_NETWORK
18PROMEKI_NAMESPACE_BEGIN
56 static constexpr uint64_t UnixEpochOffsetSeconds = 2208988800ULL;
62 NtpTime(uint32_t sec, uint32_t frac) : _seconds(sec), _fraction(frac) {}
65 static NtpTime now() {
return fromSystemClock(std::chrono::system_clock::now()); }
73 static NtpTime fromSystemClock(std::chrono::system_clock::time_point tp) {
77 const auto nsSinceUnix =
78 std::chrono::duration_cast<std::chrono::nanoseconds>(tp.time_since_epoch()).count();
81 if (nsSinceUnix < 0)
return NtpTime(0, 0);
82 const uint64_t totalNs =
static_cast<uint64_t
>(nsSinceUnix) +
83 (UnixEpochOffsetSeconds * 1'000'000'000ULL);
84 const uint64_t secs = totalNs / 1'000'000'000ULL;
85 const uint64_t remNs = totalNs % 1'000'000'000ULL;
89 const uint64_t frac = (remNs << 32) / 1'000'000'000ULL;
90 return NtpTime(
static_cast<uint32_t
>(secs & 0xFFFFFFFFu),
91 static_cast<uint32_t
>(frac & 0xFFFFFFFFu));
95 uint32_t seconds()
const {
return _seconds; }
98 uint32_t fraction()
const {
return _fraction; }
101 uint64_t toUint64()
const {
102 return (
static_cast<uint64_t
>(_seconds) << 32) |
static_cast<uint64_t
>(_fraction);
109 uint32_t toCompact32()
const {
return ((_seconds & 0xFFFFu) << 16) | (_fraction >> 16); }
111 bool isValid()
const {
return _seconds != 0 || _fraction != 0; }
113 bool operator==(
const NtpTime &o)
const {
return _seconds == o._seconds && _fraction == o._fraction; }
114 bool operator!=(
const NtpTime &o)
const {
return !(*
this == o); }
138 NtpTime operator+(
const Duration &d)
const {
139 const int64_t ns = d.nanoseconds();
140 const uint64_t packed = (
static_cast<uint64_t
>(_seconds) << 32) |
141 static_cast<uint64_t
>(_fraction);
156 const int64_t wholeSec = ns / 1'000'000'000;
157 const int64_t subNs = ns % 1'000'000'000;
158 const int64_t subFrac = (subNs << 32) / 1'000'000'000;
159 const uint64_t deltaPacked =
160 (
static_cast<uint64_t
>(wholeSec) << 32) +
static_cast<uint64_t
>(subFrac);
161 const uint64_t result = packed + deltaPacked;
162 return NtpTime(
static_cast<uint32_t
>(result >> 32) & 0xFFFFFFFFu,
163 static_cast<uint32_t
>(result & 0xFFFFFFFFu));
167 NtpTime operator-(
const Duration &d)
const {
return *
this + (-d); }
170 uint32_t _seconds = 0;
171 uint32_t _fraction = 0;