Time representation and functions

group jsdrv_time

JSDRV time representation.

The C standard library includes time.h which is very inconvenient for embedded systems. This module defines a much simpler 64-bit fixed point integer for representing time. The value is 34Q30 with the upper 34 bits to represent whole seconds and the lower 30 bits to represent fractional seconds. A value of 2**30 (1 << 30) represents 1 second. This representation gives a resolution of 2 ** -30 (approximately 1 nanosecond) and a range of +/- 2 ** 33 (approximately 272 years). The value is signed to allow for simple arithmetic on the time either as a fixed value or as deltas.

Certain elements may elect to use floating point time given in seconds. The macros JSDRV_TIME_TO_F64() and JSDRV_F64_TO_TIME() facilitate converting between the domains. Note that double precision floating point is not able to maintain the same resolution over the time range as the 64-bit representation. JSDRV_TIME_TO_F32() and JSDRV_F32_TO_TIME() allow conversion to single precision floating point which has significantly reduce resolution compared to the 34Q30 value.

Float64 only has 53 bits of precision, which can only represent up to 104 days with nanosecond precision. While this duration and precision is often adequate for relative time, it is insufficient to store absolute time from the epoch. In contrast, the int64 34Q30 time with nanosecond resolution can store ±272 years relative to its epoch.

For applications that need floating-point time, store a separate offset in seconds relative to the starting time. This improves precision between intervals. For example:

 x = np.linspace(0, time_end - time_start, length, dtype=np.float64)

Defines

JSDRV_TIME_Q

The number of fractional bits in the 64-bit time representation.

JSDRV_TIME_MAX

The maximum (positive) time representation.

JSDRV_TIME_MIN

The minimum (negative) time representation.

JSDRV_TIME_EPOCH_UNIX_OFFSET_SECONDS

The offset from the standard UNIX (POSIX) epoch.

This offset allows translation between JSDRV time and the standard UNIX (POSIX) epoch of Jan 1, 1970.

The value was computed using python3:

import dateutil.parser
dateutil.parser.parse('2018-01-01T00:00:00Z').timestamp()
JSDRV chooses a different epoch to advance “zero” by 48 years!

JSDRV_TIME_SECOND

The fixed-point representation for 1 second.

JSDRV_FRACT_MASK

The mask for the fractional bits.

JSDRV_TIME_MILLISECOND

The approximate fixed-point representation for 1 millisecond.

JSDRV_TIME_MICROSECOND

The approximate fixed-point representation for 1 microsecond.

CAUTION: this value is 0.024% accurate (240 ppm)

JSDRV_TIME_NANOSECOND

The approximate fixed-point representation for 1 nanosecond.

WARNING: this value is only 6.7% accurate!

JSDRV_TIME_MINUTE

The fixed-point representation for 1 minute.

JSDRV_TIME_HOUR

The fixed-point representation for 1 hour.

JSDRV_TIME_DAY

The fixed-point representation for 1 day.

JSDRV_TIME_WEEK

The fixed-point representation for 1 week.

JSDRV_TIME_MONTH

The average fixed-point representation for 1 month (365 day year).

JSDRV_TIME_YEAR

The approximate fixed-point representation for 1 year (365 days).

JSDRV_TIME_TO_F64(x)

Convert the 64-bit fixed point time to a double.

Parameters:
  • x – The 64-bit signed fixed point time.

Returns:

The time as a double p. Note that IEEE 747 doubles only have 52 bits of precision, so the result will be truncated for very small deltas.

JSDRV_TIME_TO_F32(x)

Convert the 64-bit fixed point time to single precision float.

Parameters:
  • x – The 64-bit signed fixed point time.

Returns:

The time as a float p in seconds. Note that IEEE 747 singles only have 23 bits of precision, so the result will likely be truncated.

JSDRV_TIME_TO_SECONDS(x)

Convert to 32-bit unsigned seconds.

Parameters:
  • x – The 64-bit signed fixed point time.

Returns:

The 64-bit unsigned time in seconds, rounded to nearest.

JSDRV_TIME_TO_MILLISECONDS(x)

Convert to milliseconds.

Parameters:
  • x – The 64-bit signed fixed point time.

Returns:

The 64-bit signed time in milliseconds, rounded to nearest.

JSDRV_TIME_TO_MICROSECONDS(x)

Convert to microseconds.

Parameters:
  • x – The 64-bit signed fixed point time.

Returns:

The 64-bit signed time in microseconds, rounded to nearest.

JSDRV_TIME_TO_NANOSECONDS(x)

Convert to nanoseconds.

Parameters:
  • x – The 64-bit signed fixed point time.

Returns:

The 64-bit signed time in nanoseconds, rounded to nearest.

JSDRV_SECONDS_TO_TIME(x)

Convert to 64-bit signed fixed point time.

Parameters:
  • x – he 32-bit unsigned time in seconds.

Returns:

The 64-bit signed fixed point time.

JSDRV_MILLISECONDS_TO_TIME(x)

Convert to 64-bit signed fixed point time.

Parameters:
  • x – The 32-bit unsigned time in milliseconds.

Returns:

The 64-bit signed fixed point time.

JSDRV_MICROSECONDS_TO_TIME(x)

Convert to 64-bit signed fixed point time.

Parameters:
  • x – The 32-bit unsigned time in microseconds.

Returns:

The 64-bit signed fixed point time.

JSDRV_NANOSECONDS_TO_TIME(x)

Convert to 64-bit signed fixed point time.

Parameters:
  • x – The 32-bit unsigned time in microseconds.

Returns:

The 64-bit signed fixed point time.

JSDRV_TIME_STRING_LENGTH

The length of the ISO 8601 string produced by jsdrv_time_to_str().

Functions

int64_t JSDRV_F64_TO_TIME(double x)

Convert the double precision time to 64-bit fixed point time.

Parameters:

x – The double-precision floating point time in seconds.

Returns:

The time as a 34Q30.

int64_t JSDRV_F32_TO_TIME(float x)

Convert the single precision float time to 64-bit fixed point time.

Parameters:

x – The single-precision floating point time in seconds.

Returns:

The time as a 34Q30.

int64_t JSDRV_TIME_TO_COUNTER(int64_t x, uint64_t z)

Convert to counter ticks, rounded to nearest.

Parameters:
  • x – The 64-bit signed fixed point time.

  • z – The counter frequency in Hz.

Returns:

The 64-bit time in counter ticks.

int64_t JSDRV_TIME_TO_COUNTER_RZERO(int64_t x, uint64_t z)

Convert to counter ticks, rounded towards zero.

Parameters:
  • x – The 64-bit signed fixed point time.

  • z – The counter frequency in Hz.

Returns:

The 64-bit time in counter ticks.

int64_t JSDRV_TIME_TO_COUNTER_RINF(int64_t x, uint64_t z)

Convert to counter ticks, rounded towards infinity.

Parameters:
  • x – The 64-bit signed fixed point time.

  • z – The counter frequency in Hz.

Returns:

The 64-bit time in counter ticks.

int64_t JSDRV_COUNTER_TO_TIME(uint64_t x, uint64_t z)

Convert a counter to 64-bit signed fixed point time.

Parameters:
  • x – The counter value in ticks.

  • z – The counter frequency in Hz.

Returns:

The 64-bit signed fixed point time.

int64_t JSDRV_TIME_ABS(int64_t t)

Compute the absolute value of a time.

Parameters:

t – The time.

Returns:

The absolute value of t.

int64_t jsdrv_time_min(int64_t a, int64_t b)

Return the minimum time.

Parameters:
  • a – The first time value.

  • b – The second time value.

Returns:

The smaller value of a and b.

int64_t jsdrv_time_max(int64_t a, int64_t b)

Return the maximum time.

Parameters:
  • a – The first time value.

  • b – The second time value.

Returns:

The larger value of a and b.

int32_t jsdrv_time_to_str(int64_t t, char *str, size_t size)

Converts jsdrv time to an ISO 8601 string.

Parameters:
  • t – The jsdrv time.

  • str – The string buffer.

  • size – The size of str in bytes, which should be at least JSDRV_TIME_STRING_LENGTH bytes to fit the full ISO 8601 string with the null terminator.

Returns:

The number of characters written to buf, not including the null terminator. If this value is less than (JSDRV_TIME_STRING_LENGTH - 1), then the full string was truncated.

int64_t jsdrv_time_from_counter(const struct jsdrv_time_map_s *self, uint64_t counter)

Convert time from a counter value to JSDRV time.

Parameters:
  • self – The time mapping instance.

  • counter – The counter value u64.

Returns:

The JSDRV time i64.

uint64_t jsdrv_time_to_counter(const struct jsdrv_time_map_s *self, int64_t time64)

Convert time from JSDRV time to a counter value.

Parameters:
  • self – The time mapping instance.

  • time64 – The JSDRV time i64.

Returns:

The counter value u64.

struct jsdrv_time_map_s
#include <time.h>

Define a mapping between JSDRV time and a counter.

This mapping is often used to convert between an increment sample identifier value and JSDRV time.

The counter_rate is specified as a double which contains a 52-bit mantissa with fractional accuracy of 2e-16.

Public Members

int64_t offset_time

The offset specified as JSDRV time i64.

uint64_t offset_counter

The offset specified as counter values u64.

double counter_rate

The counter increment rate (Hz).