21 Time::Time(u64 seconds, u32 nanoseconds, u16 subnanoseconds)
22 : m_secs((s64)seconds)
28 void Time::normalize() {
33 while (m_subns >= SUBNS_PER_SEC) {
35 m_subns -= SUBNS_PER_SEC;
40 template<s64 UNITS_PER_SEC>
41 inline s64 delta_convert(s64 sec, s64 subns) {
42 constexpr s64 MAX_SAFE = INT64_MAX / UNITS_PER_SEC - 1;
44 if (sec < -MAX_SAFE) {
46 }
else if (sec > MAX_SAFE) {
48 }
else if (SUBNS_PER_UNIT > 1) {
49 return UNITS_PER_SEC * sec + div_round(subns, SUBNS_PER_UNIT);
51 return UNITS_PER_SEC * sec + subns;
56 {
return delta_convert<SUBNS_PER_SEC>(m_secs, m_subns); }
58 {
return delta_convert<NSEC_PER_SEC>(m_secs, m_subns); }
60 {
return delta_convert<USEC_PER_SEC>(m_secs, m_subns); }
62 {
return delta_convert<MSEC_PER_SEC>(m_secs, m_subns); }
66 s64 sec_msb = (s64)src->read_u16();
67 s64 sec_lsb = (s64)src->read_u32();
68 s64 nsec = (s64)src->read_u32();
69 m_secs = (sec_msb << 32) + sec_lsb;
71 normalize();
return true;
78 dst->write_u16((u16)(m_secs >> 32));
79 dst->write_u32((u32)(m_secs >> 0));
93 constexpr s64 GPS_EPOCH = satcat5::datetime::ONE_DAY * 3657LL
94 + satcat5::datetime::ONE_SECOND * 19LL;
100 return tai_msec - GPS_EPOCH;
105 s64 tai_msec = gps_msec + GPS_EPOCH;
107 u64 ptp_secs = (u64)satcat5::util::divide(tai_msec,
MSEC_PER_SEC);
108 u32 ptp_msec = (u32)satcat5::util::modulo(tai_msec,
MSEC_PER_SEC);
109 return Time(ptp_secs, ptp_msec * 1000000u);
114 temp.m_secs = (s64)abs_s64(m_secs);
117 temp.m_subns = m_subns;
118 }
else if (m_subns > 0) {
130 return (m_secs == other.m_secs) && (m_subns == other.m_subns);
134 if (m_secs < other.m_secs)
return true;
135 if (m_secs > other.m_secs)
return false;
136 return m_subns < other.m_subns;
140 if (m_secs > other.m_secs)
return true;
141 if (m_secs < other.m_secs)
return false;
142 return m_subns > other.m_subns;
146 m_secs += other.m_secs;
147 m_subns += other.m_subns;
152 m_secs -= other.m_secs;
153 m_subns -= other.m_subns;
158 s64 tmp = m_subns * scale;
166 m_secs = m_secs / scale;
167 m_subns = (m_subns + tmp) / scale;
172 m_secs = other.m_secs;
173 m_subns = other.m_subns;
Abstract API for reading byte-streams and packets.
virtual unsigned get_read_ready() const =0
How many bytes can be read without blocking?
Abstract API for writing byte-streams and packets.
Internal buffer used by the Log class.
void wr_d64(u64 val, unsigned zpad=0)
Write an unsigned integer (u64) in decimal format.
void wr_s64(s64 val, unsigned zpad=0)
Write a signed integer (s64) in decimal format.
void wr_str(const char *str)
Write a null-terminated UTF-8 string.
High-precision timestamp for use with PTP / IEEE1588.
s64 delta_subns() const
Convert time-differences to the designated unit.
satcat5::ptp::Time operator=(const satcat5::ptp::Time &other)
Standard arithmetic operations.
s64 delta_nsec() const
Convert time-differences to the designated unit.
void operator*=(unsigned scale)
Scalar multiply and divide are used for weighted averaging.
bool read_from(satcat5::io::Readable *src)
Read the standard 10-byte timestamp from a PTP message (e.g., originTimestamp: u48 seconds + u32 nano...
u32 field_nsec() const
Read the "nanoseconds" field, rounding down.
s64 field_secs() const
Read the "seconds" field without intermediate rounding.
satcat5::ptp::Time operator+(const satcat5::ptp::Time &other) const
Standard arithmetic operations.
satcat5::ptp::Time abs() const
Standard arithmetic operations.
void log_to(satcat5::log::LogBuffer &wr) const
User-readable format for logging.
bool operator>(const satcat5::ptp::Time &other) const
Standard comparison operators.
u32 round_nsec() const
Return "nanoseconds" field after rounding to the nearest nanosecond.
satcat5::ptp::Time operator/(unsigned scale) const
Scalar multiply and divide are used for weighted averaging.
void operator/=(unsigned scale)
Scalar multiply and divide are used for weighted averaging.
satcat5::ptp::Time operator-() const
Standard arithmetic operations.
s64 delta_usec() const
Convert time-differences to the designated unit.
s64 to_datetime() const
Convert to SatCat5 date/time.
void operator+=(const satcat5::ptp::Time &other)
Standard arithmetic operations.
void write_to(satcat5::io::Writeable *dst) const
Read or write the 10-byte timestamp from a PTP message.
satcat5::ptp::Time operator*(unsigned scale) const
Scalar multiply and divide are used for weighted averaging.
void operator-=(const satcat5::ptp::Time &other)
Standard arithmetic operations.
s64 delta_msec() const
Convert time-differences to the designated unit.
bool operator==(const satcat5::ptp::Time &other) const
Standard comparison operators.
bool operator<(const satcat5::ptp::Time &other) const
Standard comparison operators.
Real-time clock conversion functions.
I/O interface core definitions.
Diagnostic logging to UART and/or Ethernet ports.
High-precision "Time" object for use with PTP / IEEE1588.
constexpr s64 SUBNS_PER_MSEC
Define commonly used scaling factors.
constexpr s64 SUBNS_PER_SEC
Define commonly used scaling factors.
constexpr s64 USEC_PER_SEC
Define commonly used scaling factors.
satcat5::ptp::Time from_datetime(s64 gps_msec)
Convert from SatCat5 date/time to a ptp::Time object.
constexpr s64 NSEC_PER_SEC
Define commonly used scaling factors.
constexpr s64 SUBNS_PER_NSEC
Define commonly used scaling factors.
constexpr s64 MSEC_PER_SEC
Define commonly used scaling factors.
constexpr u64 abs_s64(s64 a)
Absolute value.
constexpr T div_round(T a, T b)
Integer division functions with various rounding options: