Program Listing for File time.h
↰ Return to documentation for file (include_public/anj/time.h)
ANJ_TIME_DURATION_AS_STRING(timeout, ANJ_TIME_UNIT_MS));
/*
* Copyright 2023-2026 AVSystem <avsystem@avsystem.com>
* AVSystem Anjay Lite LwM2M SDK
* All rights reserved.
*
* Licensed under AVSystem Anjay Lite LwM2M Client SDK - Non-Commercial License.
* See the attached LICENSE file for details.
*/
#include <anj/init.h>
#ifndef ANJ_TIME_H
# define ANJ_TIME_H
# include <inttypes.h>
# include <math.h>
# include <stdbool.h>
# include <stddef.h>
# include <stdint.h>
# ifdef __cplusplus
extern "C" {
# endif
typedef enum {
ANJ_TIME_UNIT_DAY,
ANJ_TIME_UNIT_HOUR,
ANJ_TIME_UNIT_MIN,
ANJ_TIME_UNIT_S,
ANJ_TIME_UNIT_MS,
ANJ_TIME_UNIT_US,
} anj_time_unit_t;
# define ANJ_TIME_US_MAX INT64_MAX
# define ANJ_TIME_DURATION_AS_STRING_MAX_LEN (sizeof("-9223372036854775808"))
typedef struct {
int64_t us;
} anj_time_duration_t;
typedef struct {
anj_time_duration_t since_monotonic_epoch;
} anj_time_monotonic_t;
typedef struct {
anj_time_duration_t since_real_epoch;
} anj_time_real_t;
extern const anj_time_duration_t ANJ_TIME_DURATION_ZERO;
extern const anj_time_real_t ANJ_TIME_REAL_ZERO;
extern const anj_time_monotonic_t ANJ_TIME_MONOTONIC_ZERO;
extern const anj_time_duration_t ANJ_TIME_DURATION_INVALID;
extern const anj_time_real_t ANJ_TIME_REAL_INVALID;
extern const anj_time_monotonic_t ANJ_TIME_MONOTONIC_INVALID;
anj_time_duration_t anj_time_duration_new(int64_t scalar, anj_time_unit_t unit);
anj_time_duration_t anj_time_duration_fnew(double scalar, anj_time_unit_t unit);
int64_t anj_time_duration_to_scalar(anj_time_duration_t duration,
anj_time_unit_t unit);
double anj_time_duration_to_fscalar(anj_time_duration_t duration,
anj_time_unit_t unit);
static inline bool anj_time_duration_is_valid(anj_time_duration_t duration) {
if (duration.us == ANJ_TIME_US_MAX) {
return false;
}
return true;
}
static inline anj_time_duration_t
anj_time_duration_add(const anj_time_duration_t lhs,
const anj_time_duration_t rhs) {
if (!anj_time_duration_is_valid(lhs) || !anj_time_duration_is_valid(rhs)) {
return ANJ_TIME_DURATION_INVALID;
}
const anj_time_duration_t result = { lhs.us + rhs.us };
return result;
}
static inline anj_time_duration_t
anj_time_duration_sub(const anj_time_duration_t lhs,
const anj_time_duration_t rhs) {
if (!anj_time_duration_is_valid(lhs) || !anj_time_duration_is_valid(rhs)) {
return ANJ_TIME_DURATION_INVALID;
}
const anj_time_duration_t result = { lhs.us - rhs.us };
return result;
}
static inline anj_time_duration_t
anj_time_duration_mul(const anj_time_duration_t duration,
const int32_t factor) {
if (!anj_time_duration_is_valid(duration) || factor == INT32_MAX) {
return ANJ_TIME_DURATION_INVALID;
}
const anj_time_duration_t result = { duration.us * factor };
return result;
}
static inline anj_time_duration_t
anj_time_duration_fmul(const anj_time_duration_t duration,
const double factor) {
if (!anj_time_duration_is_valid(duration) || isinf(factor)
|| isnan(factor)) {
return ANJ_TIME_DURATION_INVALID;
}
const anj_time_duration_t result = { (int64_t) ((double) duration.us
* factor) };
return result;
}
static inline anj_time_duration_t
anj_time_duration_div(const anj_time_duration_t duration,
const int32_t divisor) {
if (!anj_time_duration_is_valid(duration) || divisor == 0) {
return ANJ_TIME_DURATION_INVALID;
}
const anj_time_duration_t result = { duration.us / divisor };
return result;
}
static inline bool anj_time_duration_eq(const anj_time_duration_t lhs,
const anj_time_duration_t rhs) {
if (!anj_time_duration_is_valid(lhs) || !anj_time_duration_is_valid(rhs)) {
return false;
}
return lhs.us == rhs.us;
}
static inline bool anj_time_duration_lt(const anj_time_duration_t lhs,
const anj_time_duration_t rhs) {
if (!anj_time_duration_is_valid(lhs) || !anj_time_duration_is_valid(rhs)) {
return false;
}
return lhs.us < rhs.us;
}
static inline bool anj_time_duration_gt(const anj_time_duration_t lhs,
const anj_time_duration_t rhs) {
if (!anj_time_duration_is_valid(lhs) || !anj_time_duration_is_valid(rhs)) {
return false;
}
return lhs.us > rhs.us;
}
static inline bool anj_time_duration_leq(const anj_time_duration_t lhs,
const anj_time_duration_t rhs) {
if (!anj_time_duration_is_valid(lhs) || !anj_time_duration_is_valid(rhs)) {
return false;
}
return lhs.us <= rhs.us;
}
static inline bool anj_time_duration_geq(const anj_time_duration_t lhs,
const anj_time_duration_t rhs) {
if (!anj_time_duration_is_valid(lhs) || !anj_time_duration_is_valid(rhs)) {
return false;
}
return lhs.us >= rhs.us;
}
const char *_anj_time_duration_as_string_impl(
const anj_time_duration_t duration,
const anj_time_unit_t unit,
char (*buffer)[ANJ_TIME_DURATION_AS_STRING_MAX_LEN]);
# define ANJ_TIME_DURATION_AS_STRING(duration, unit) \
(_anj_time_duration_as_string_impl( \
duration, \
unit, \
&(char[ANJ_TIME_DURATION_AS_STRING_MAX_LEN]){ "" }))
static inline anj_time_monotonic_t
anj_time_monotonic_from_duration(const anj_time_duration_t duration) {
const anj_time_monotonic_t result = { duration };
return result;
}
static inline anj_time_duration_t
anj_time_monotonic_to_duration(const anj_time_monotonic_t time) {
return time.since_monotonic_epoch;
}
static inline anj_time_monotonic_t
anj_time_monotonic_new(const int64_t scalar, const anj_time_unit_t unit) {
return anj_time_monotonic_from_duration(
anj_time_duration_new(scalar, unit));
}
static inline anj_time_monotonic_t
anj_time_monotonic_fnew(const double scalar, const anj_time_unit_t unit) {
return anj_time_monotonic_from_duration(
anj_time_duration_fnew(scalar, unit));
}
static inline bool
anj_time_monotonic_is_valid(const anj_time_monotonic_t time) {
return anj_time_duration_is_valid(anj_time_monotonic_to_duration(time));
}
static inline int64_t
anj_time_monotonic_to_scalar(const anj_time_monotonic_t time,
const anj_time_unit_t unit) {
return anj_time_duration_to_scalar(anj_time_monotonic_to_duration(time),
unit);
}
static inline double
anj_time_monotonic_to_fscalar(const anj_time_monotonic_t time,
const anj_time_unit_t unit) {
return anj_time_duration_to_fscalar(anj_time_monotonic_to_duration(time),
unit);
}
static inline anj_time_monotonic_t
anj_time_monotonic_add(const anj_time_monotonic_t start,
const anj_time_duration_t duration) {
return anj_time_monotonic_from_duration(anj_time_duration_add(
anj_time_monotonic_to_duration(start), duration));
}
static inline anj_time_monotonic_t
anj_time_monotonic_sub(const anj_time_monotonic_t start,
const anj_time_duration_t duration) {
return anj_time_monotonic_from_duration(anj_time_duration_sub(
anj_time_monotonic_to_duration(start), duration));
}
static inline anj_time_duration_t
anj_time_monotonic_diff(const anj_time_monotonic_t end,
const anj_time_monotonic_t start) {
return anj_time_duration_sub(anj_time_monotonic_to_duration(end),
anj_time_monotonic_to_duration(start));
}
static inline bool anj_time_monotonic_lt(const anj_time_monotonic_t lhs,
const anj_time_monotonic_t rhs) {
return anj_time_duration_lt(anj_time_monotonic_to_duration(lhs),
anj_time_monotonic_to_duration(rhs));
}
static inline bool anj_time_monotonic_gt(const anj_time_monotonic_t lhs,
const anj_time_monotonic_t rhs) {
return anj_time_duration_gt(anj_time_monotonic_to_duration(lhs),
anj_time_monotonic_to_duration(rhs));
}
static inline bool anj_time_monotonic_eq(const anj_time_monotonic_t lhs,
const anj_time_monotonic_t rhs) {
return anj_time_duration_eq(anj_time_monotonic_to_duration(lhs),
anj_time_monotonic_to_duration(rhs));
}
static inline bool anj_time_monotonic_leq(const anj_time_monotonic_t lhs,
const anj_time_monotonic_t rhs) {
return anj_time_duration_leq(anj_time_monotonic_to_duration(lhs),
anj_time_monotonic_to_duration(rhs));
}
static inline bool anj_time_monotonic_geq(const anj_time_monotonic_t lhs,
const anj_time_monotonic_t rhs) {
return anj_time_duration_geq(anj_time_monotonic_to_duration(lhs),
anj_time_monotonic_to_duration(rhs));
}
# define ANJ_TIME_MONOTONIC_AS_STRING(time, unit) \
(_anj_time_duration_as_string_impl( \
time.since_monotonic_epoch, \
unit, \
&(char[ANJ_TIME_DURATION_AS_STRING_MAX_LEN]){ "" }))
static inline anj_time_real_t
anj_time_real_from_duration(const anj_time_duration_t duration) {
const anj_time_real_t result = { duration };
return result;
}
static inline anj_time_duration_t
anj_time_real_to_duration(const anj_time_real_t time) {
return time.since_real_epoch;
}
static inline anj_time_real_t anj_time_real_new(const int64_t scalar,
const anj_time_unit_t unit) {
return anj_time_real_from_duration(anj_time_duration_new(scalar, unit));
}
static inline anj_time_real_t anj_time_real_fnew(const double scalar,
const anj_time_unit_t unit) {
return anj_time_real_from_duration(anj_time_duration_fnew(scalar, unit));
}
static inline int64_t anj_time_real_to_scalar(const anj_time_real_t time,
const anj_time_unit_t unit) {
return anj_time_duration_to_scalar(anj_time_real_to_duration(time), unit);
}
static inline double anj_time_real_to_fscalar(const anj_time_real_t time,
const anj_time_unit_t unit) {
return anj_time_duration_to_fscalar(anj_time_real_to_duration(time), unit);
}
static inline bool anj_time_real_is_valid(const anj_time_real_t time) {
return anj_time_duration_is_valid(anj_time_real_to_duration(time));
}
static inline anj_time_real_t
anj_time_real_add(const anj_time_real_t start,
const anj_time_duration_t duration) {
return anj_time_real_from_duration(
anj_time_duration_add(anj_time_real_to_duration(start), duration));
}
static inline anj_time_real_t
anj_time_real_sub(const anj_time_real_t start,
const anj_time_duration_t duration) {
return anj_time_real_from_duration(
anj_time_duration_sub(anj_time_real_to_duration(start), duration));
}
static inline anj_time_duration_t
anj_time_real_diff(const anj_time_real_t end, const anj_time_real_t start) {
return anj_time_duration_sub(anj_time_real_to_duration(end),
anj_time_real_to_duration(start));
}
static inline bool anj_time_real_lt(const anj_time_real_t lhs,
const anj_time_real_t rhs) {
return anj_time_duration_lt(anj_time_real_to_duration(lhs),
anj_time_real_to_duration(rhs));
}
static inline bool anj_time_real_gt(const anj_time_real_t lhs,
const anj_time_real_t rhs) {
return anj_time_duration_gt(anj_time_real_to_duration(lhs),
anj_time_real_to_duration(rhs));
}
static inline bool anj_time_real_eq(const anj_time_real_t lhs,
const anj_time_real_t rhs) {
return anj_time_duration_eq(anj_time_real_to_duration(lhs),
anj_time_real_to_duration(rhs));
}
static inline bool anj_time_real_leq(const anj_time_real_t lhs,
const anj_time_real_t rhs) {
return anj_time_duration_leq(anj_time_real_to_duration(lhs),
anj_time_real_to_duration(rhs));
}
static inline bool anj_time_real_geq(const anj_time_real_t lhs,
const anj_time_real_t rhs) {
return anj_time_duration_geq(anj_time_real_to_duration(lhs),
anj_time_real_to_duration(rhs));
}
# define ANJ_TIME_REAL_AS_STRING(time, unit) \
(_anj_time_duration_as_string_impl( \
time.since_real_epoch, \
unit, \
&(char[ANJ_TIME_DURATION_AS_STRING_MAX_LEN]){ "" }))
# ifdef __cplusplus
}
# endif
#endif // ANJ_TIME_H