27 RCSIDH(time_h,
"$Id: 8b88a88bde62d1f04e9478da459d19c419a206b7 $")
38 #if !defined(HAVE_CLOCK_GETTIME)
39 #error clock_gettime is required
106 #include <freeradius-devel/missing.h>
107 #include <freeradius-devel/util/debug.h>
108 #include <freeradius-devel/util/sbuff.h>
109 #include <freeradius-devel/util/math.h>
121 return ((a == op) == b);
130 #define fr_time_overflow_ispos(_a, _op, _b) \
133 fr_time_t *: (fr_time_unwrap(*((fr_time_t *)&(_a))) >= 0), \
134 fr_time_delta_t *: (fr_time_delta_unwrap(*((fr_time_delta_t *)&(_a))) >= 0), \
135 fr_unix_time_t *: true), \
138 fr_time_t *: (fr_time_unwrap(*((fr_time_t *)&(_b))) >= 0), \
139 fr_time_delta_t *: (fr_time_delta_unwrap(*((fr_time_delta_t *)&(_b))) >= 0), \
140 fr_unix_time_t *: true)\
143 #define fr_time_max() (fr_time_t){ .value = INT64_MAX }
144 #define fr_time_min() (fr_time_t){ .value = INT64_MIN }
145 #define fr_time_wrap(_time) (fr_time_t){ .value = (_time) }
147 #define fr_time_overflow_add(_a, _b) (fr_time_overflow_ispos(_a, true, _b) ? fr_time_max() : fr_time_min())
148 #define fr_time_overflow_sub(_a, _b) (fr_time_overflow_ispos(_a, false, _b) ? fr_time_max() : fr_time_min())
150 #define fr_time_delta_max() (fr_time_delta_t){ .value = INT64_MAX }
151 #define fr_time_delta_min() (fr_time_delta_t){ .value = INT64_MIN }
152 #define fr_time_delta_wrap(_time) (fr_time_delta_t){ .value = (_time) }
155 #define fr_time_delta_overflow_add(_a, _b) (fr_time_overflow_ispos(_a, true, _b) ? fr_time_delta_max() : fr_time_delta_min())
156 #define fr_time_delta_overflow_sub(_a, _b) (fr_time_overflow_ispos(_a, false, _b) ? fr_time_delta_max() : fr_time_delta_min())
158 #define fr_unix_time_max() (fr_unix_time_t){ .value = UINT64_MAX }
159 #define fr_unix_time_min() (fr_unix_time_t){ .value = 0 }
160 #define fr_unix_time_wrap(_time) (fr_unix_time_t){ .value = (_time) }
162 #define fr_unix_time_overflow_add(_a, _b) (fr_time_overflow_ispos(_a, true, _b) ? fr_unix_time_max() : fr_unix_time_min())
163 #define fr_unix_time_overflow_sub(_a, _b) (fr_time_overflow_ispos(_a, false, _b) ? fr_unix_time_max() : fr_unix_time_min())
196 #define fr_time_add(_a, _b) \
198 fr_time_t : _Generic(_b, \
199 fr_time_delta_t : fr_time_add_time_delta \
201 fr_time_delta_t : _Generic(_b, \
202 fr_time_t : fr_time_add_delta_time, \
203 fr_time_delta_t : fr_time_delta_add \
229 #define fr_time_sub(_a, _b) \
231 fr_time_t : _Generic(_b, \
232 fr_time_t : fr_time_sub_time_time, \
233 fr_time_delta_t : fr_time_sub_time_delta \
237 #define fr_time_gt(_a, _b) (fr_time_unwrap(_a) > fr_time_unwrap(_b))
238 #define fr_time_gteq(_a, _b) (fr_time_unwrap(_a) >= fr_time_unwrap(_b))
239 #define fr_time_lt(_a, _b) (fr_time_unwrap(_a) < fr_time_unwrap(_b))
240 #define fr_time_lteq(_a, _b) (fr_time_unwrap(_a) <= fr_time_unwrap(_b))
241 #define fr_time_eq(_a, _b) (fr_time_unwrap(_a) == fr_time_unwrap(_b))
242 #define fr_time_neq(_a, _b) (fr_time_unwrap(_a) != fr_time_unwrap(_b))
244 #define fr_time_ispos(_a) (fr_time_unwrap(_a) > 0)
245 #define fr_time_isneg(_a) (fr_time_unwrap(_a) < 0)
282 #define fr_time_delta_cond(_a, _op, _b) (fr_time_delta_unwrap(_a) _op fr_time_delta_unwrap(_b))
283 #define fr_time_delta_gt(_a, _b) (fr_time_delta_unwrap(_a) > fr_time_delta_unwrap(_b))
284 #define fr_time_delta_gteq(_a, _b) (fr_time_delta_unwrap(_a) >= fr_time_delta_unwrap(_b))
285 #define fr_time_delta_lt(_a, _b) (fr_time_delta_unwrap(_a) < fr_time_delta_unwrap(_b))
286 #define fr_time_delta_lteq(_a, _b) (fr_time_delta_unwrap(_a) <= fr_time_delta_unwrap(_b))
287 #define fr_time_delta_eq(_a, _b) (fr_time_delta_unwrap(_a) == fr_time_delta_unwrap(_b))
288 #define fr_time_delta_neq(_a, _b) (fr_time_delta_unwrap(_a) != fr_time_delta_unwrap(_b))
290 #define fr_time_delta_ispos(_a) (fr_time_delta_unwrap(_a) > 0)
291 #define fr_time_delta_isneg(_a) (fr_time_delta_unwrap(_a) < 0)
324 #define fr_unix_time_add(_a, _b) \
326 fr_unix_time_t : _Generic(_b, \
327 fr_time_delta_t : fr_unix_time_add_time_delta \
329 fr_time_delta_t : _Generic(_b, \
330 fr_unix_time_t : fr_unix_time_add_delta_time, \
331 fr_time_delta_t : fr_time_delta_add \
357 #define fr_unix_time_sub(_a, _b) \
359 fr_unix_time_t : _Generic(_b, \
360 fr_unix_time_t : fr_unix_time_sub_time_time, \
361 fr_time_delta_t : fr_unix_time_sub_time_delta \
365 #define fr_unix_time_gt(_a, _b) (fr_unix_time_unwrap(_a) > fr_unix_time_unwrap(_b))
366 #define fr_unix_time_gteq(_a, _b) (fr_unix_time_unwrap(_a) >= fr_unix_time_unwrap(_b))
367 #define fr_unix_time_lt(_a, _b) (fr_unix_time_unwrap(_a) < fr_unix_time_unwrap(_b))
368 #define fr_unix_time_lteq(_a, _b) (fr_unix_time_unwrap(_a) <= fr_unix_time_unwrap(_b))
369 #define fr_unix_time_eq(_a, _b) (fr_unix_time_unwrap(_a) == fr_unix_time_unwrap(_b))
370 #define fr_unix_time_neq(_a, _b) (fr_unix_time_unwrap(_a) != fr_unix_time_unwrap(_b))
372 #define fr_unix_time_ispos(_a) (fr_unix_time_unwrap(_a) > 0)
379 #define NSEC (1000000000)
380 #define USEC (1000000)
393 #define FR_TIME_DUR_YEAR ((int64_t)NSEC * 31556952)
394 #define FR_TIME_DUR_MONTH (FR_TIME_DUR_YEAR/12)
416 if (overflow) *overflow =
true;
419 if (overflow) *overflow =
false;
468 if (!
fr_add(&
out, integer, fraction))
goto overflow;
481 if (!
fr_add(&
out, integer, ts->tv_nsec))
goto overflow;
552 if (overflow) *overflow =
true;
556 if (overflow) *overflow =
true;
559 if (overflow) *overflow =
false;
609 if (!
fr_add(&
out, integer, fraction))
goto overflow;
622 if (!
fr_add(&
out, integer, ts->tv_nsec))
goto overflow;
656 #define fr_time_delta_to_timeval(_delta) \
658 .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \
659 .tv_usec = (fr_time_delta_unwrap(_delta) % NSEC) / (NSEC / USEC) \
666 #define fr_time_delta_to_timespec(_delta)\
668 .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \
669 .tv_nsec = (fr_time_delta_unwrap(_delta) % NSEC) \
742 #define fr_time_to_timeval(_when) fr_time_delta_to_timeval(fr_time_delta_wrap(fr_time_offset_to_realtime() + fr_time_unwrap(_when)))
748 #define fr_time_to_timespec(_when) fr_time_delta_to_timespec(fr_time_delta_wrap(fr_time_offset_to_realtime() + fr_time_unwrap(_when)))
765 if (overflow) *overflow =
true;
770 if (overflow) *overflow =
true;
774 if (overflow) *overflow =
false;
949 #ifndef CLOCK_MONOTONIC_RAW
950 #define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
988 CC_HINT(
format(strftime, 3, 0));
991 CC_HINT(
format(strftime, 3, 0));
static int const char * fmt
#define typeof_field(_type, _field)
Typeof field.
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
#define fr_sub(_out, _a, _b)
Subtracts two integers.
#define fr_add(_out, _a, _b)
Adds two integers.
#define fr_multiply(_out, _a, _b)
Multiplies two integers together.
static size_t array[MY_ARRAY_SIZE]
Set of terminal elements.
#define atomic_load_explicit(object, order)
An element in an arbitrarily ordered array of name to num mappings.
static fr_time_t fr_time_from_csec(int64_t when)
Convert csec (wallclock time) to a fr_time_t (internal time)
fr_slen_t fr_time_delta_from_substr(fr_time_delta_t *out, fr_sbuff_t *in, fr_time_res_t hint, bool no_trailing, fr_sbuff_term_t const *tt))
Create fr_time_delta_t from a string.
static fr_unix_time_t fr_unix_time_sub_time_delta(fr_unix_time_t a, fr_time_delta_t b)
static fr_unix_time_t fr_unix_time_from_msec(int64_t msec)
static fr_time_t fr_time_from_timeval(struct timeval const *when_tv)
Convert a timeval (wallclock time) to a fr_time_t (internal time)
void fr_time_elapsed_update(fr_time_elapsed_t *elapsed, fr_time_t start, fr_time_t end)
static fr_time_delta_t fr_time_delta_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
fr_unix_time_t fr_unix_time_from_tm(struct tm *tm)
static fr_time_t fr_time_from_nsec(int64_t when)
Convert a nsec (wallclock time) to a fr_time_t (internal time)
#define fr_time_delta_min()
static fr_time_delta_t fr_time_delta_from_msec(int64_t msec)
static int64_t fr_time_delta_to_integer(fr_time_delta_t delta, fr_time_res_t res)
static fr_time_t fr_time_from_msec(int64_t when)
Convert msec (wallclock time) to a fr_time_t (internal time)
static int64_t fr_time_to_sec(fr_time_t when)
Convert an fr_time_t (internal time) to number of sec since the unix epoch (wallclock time)
static fr_time_delta_t fr_time_delta_add(fr_time_delta_t a, fr_time_delta_t b)
static fr_unix_time_t fr_unix_time_add_delta_time(fr_time_delta_t a, fr_unix_time_t b)
static fr_unix_time_t fr_unix_time_from_nsec(int64_t nsec)
static fr_time_t fr_time_add_time_delta(fr_time_t a, fr_time_delta_t b)
int fr_time_sync(void)
Get a new fr_time_monotonic_to_realtime value.
static int64_t fr_time_delta_unwrap(fr_time_delta_t time)
static int64_t fr_time_to_msec(fr_time_t when)
Convert an fr_time_t (internal time) to number of msec since the unix epoch (wallclock time)
static int8_t fr_time_delta_cmp(fr_time_delta_t a, fr_time_delta_t b)
Compare two fr_time_delta_t values.
fr_table_num_ordered_t const fr_time_precision_table[]
static int64_t fr_unix_time_to_min(fr_unix_time_t delta)
static fr_time_t fr_time_from_integer(bool *overflow, int64_t when, fr_time_res_t res)
Convert wallclock time to a fr_time_t (internal time)
#define fr_time_delta_overflow_add(_a, _b)
static int64_t fr_time_unwrap(fr_time_t time)
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
static int64_t fr_unix_time_to_csec(fr_unix_time_t delta)
#define fr_unix_time_overflow_sub(_a, _b)
static int64_t fr_unix_time_to_sec(fr_unix_time_t delta)
#define fr_time_delta_wrap(_time)
int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta)
Return time delta from the time zone.
#define fr_time_wrap(_time)
fr_slen_t fr_time_delta_from_str(fr_time_delta_t *out, char const *in, size_t inlen, fr_time_res_t hint)
Create fr_time_delta_t from a string.
static fr_time_t fr_time_add_delta_time(fr_time_delta_t a, fr_time_t b)
bool fr_time_is_dst(void)
Whether or not we're daylight savings.
static fr_time_delta_t fr_time_delta_mul(fr_time_delta_t a, int64_t b)
#define fr_unix_time_min()
static fr_unix_time_t fr_unix_time_from_timeval(struct timeval const *tv)
static int64_t fr_time_delta_to_csec(fr_time_delta_t delta)
#define fr_time_overflow_add(_a, _b)
static fr_unix_time_t fr_unix_time_from_timespec(struct timespec const *ts)
#define fr_unix_time_wrap(_time)
static int64_t fr_time_to_usec(fr_time_t when)
Convert an fr_time_t (internal time) to number of usec since the unix epoch (wallclock time)
static int64_t fr_time_delta_to_sec(fr_time_delta_t delta)
_Atomic int64_t fr_time_monotonic_to_realtime
difference between the two clocks
int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_res_t hint)
Convert string in various formats to a fr_unix_time_t.
static fr_time_t fr_time_from_usec(int64_t when)
Convert usec (wallclock time) to a fr_time_t (internal time)
#define fr_time_delta_overflow_sub(_a, _b)
int64_t fr_time_scale(int64_t t, fr_time_res_t hint)
Scale an input time to NSEC, clamping it at max / min.
int64_t value
Signed because we need times before the server started for things like certificate validity checks an...
static fr_time_delta_t fr_time_sub_time_time(fr_time_t a, fr_time_t b)
fr_time_res_t
The base resolution for print parse operations.
static int64_t fr_time_delta_to_usec(fr_time_delta_t delta)
static fr_time_t fr_time_from_timespec(struct timespec const *when_ts)
Convert a timespec (wallclock time) to a fr_time_t (internal time)
static fr_unix_time_t fr_unix_time_from_csec(int64_t csec)
static fr_unix_time_t fr_unix_time_from_sec(int64_t sec)
size_t fr_time_strftime_utc(fr_sbuff_t *out, fr_time_t time, char const *fmt))
Copy a time string (UTC) to an sbuff.
#define fr_unix_time_overflow_add(_a, _b)
static int64_t fr_unix_time_to_day(fr_unix_time_t delta)
static fr_unix_time_t fr_unix_time_from_integer(bool *overflow, int64_t integer, fr_time_res_t res)
fr_time_delta_t fr_time_gmtoff(void)
Get the offset to gmt.
static int64_t fr_unix_time_to_usec(fr_unix_time_t delta)
#define fr_time_overflow_sub(_a, _b)
static int8_t fr_unix_time_cmp(fr_unix_time_t a, fr_unix_time_t b)
Compare two fr_unix_time_t values.
void fr_time_elapsed_fprint(FILE *fp, fr_time_elapsed_t const *elapsed, char const *prefix, int tabs))
struct fr_time_s fr_time_t
"server local" time.
static fr_time_t fr_time_from_sec(time_t when)
Convert a time_t (wallclock time) to a fr_time_t (internal time)
static uint64_t fr_unix_time_unwrap(fr_unix_time_t time)
static fr_unix_time_t fr_unix_time_add_time_delta(fr_unix_time_t a, fr_time_delta_t b)
#define CLOCK_MONOTONIC_RAW
#define fr_unix_time_max()
static fr_time_delta_t fr_time_delta_from_nsec(int64_t nsec)
fr_slen_t fr_time_delta_to_str(fr_sbuff_t *out, fr_time_delta_t delta, fr_time_res_t res, bool is_unsigned)
Print fr_time_delta_t to a string with an appropriate suffix.
static int64_t fr_unix_time_to_integer(fr_unix_time_t delta, fr_time_res_t res)
static fr_time_delta_t fr_time_delta_sub(fr_time_delta_t a, fr_time_delta_t b)
static fr_time_delta_t fr_time_delta_from_timeval(struct timeval const *tv)
size_t fr_time_strftime_local(fr_sbuff_t *out, fr_time_t time, char const *fmt))
Copy a time string (local timezone) to an sbuff.
static fr_time_delta_t fr_time_delta_from_csec(int64_t csec)
static int64_t fr_unix_time_to_msec(fr_unix_time_t delta)
size_t fr_time_precision_table_len
static fr_time_t fr_time(void)
Return a relative time since the server fr_time_epoch.
static fr_time_t fr_time_sub_time_delta(fr_time_t a, fr_time_delta_t b)
static fr_unix_time_t fr_unix_time_from_time(time_t time)
Convert a time_t into out internal fr_unix_time_t.
static bool fr_time_op_ispos(bool a, bool op, bool b)
static int64_t fr_time_offset_to_realtime(void)
Return the current value of fr_time_monotonic_to_realtime.
static int64_t fr_time_to_csec(fr_time_t when)
Convert an fr_time_t (internal time) to number of csec since the unix epoch (wallclock time)
static fr_time_delta_t fr_time_delta_div(fr_time_delta_t a, fr_time_delta_t b)
static fr_unix_time_t fr_time_to_unix_time(fr_time_t when)
Convert an fr_time_t (internal time) to our version of unix time (wallclock time)
static fr_time_delta_t fr_time_delta_from_usec(int64_t usec)
struct fr_time_delta_s fr_time_delta_t
A time delta, a difference in time measured in nanoseconds.
int fr_time_start(void)
Initialize the local time.
static fr_time_delta_t fr_time_delta_from_timespec(struct timespec const *ts)
static fr_time_delta_t fr_unix_time_sub_time_time(fr_unix_time_t a, fr_unix_time_t b)
#define fr_time_delta_max()
static int64_t fr_unix_time_to_hour(fr_unix_time_t delta)
static int64_t fr_time_delta_to_msec(fr_time_delta_t delta)
fr_slen_t fr_unix_time_to_str(fr_sbuff_t *out, fr_unix_time_t time, fr_time_res_t res, bool utc)
Convert unix time to string.
static int8_t fr_time_cmp(fr_time_t a, fr_time_t b)
Compare two fr_time_t values.
static fr_unix_time_t fr_unix_time_from_usec(int64_t usec)
int64_t fr_time_epoch
monotonic clock at boot, i.e. our epoch
struct fr_unix_time_s fr_unix_time_t
"Unix" time.
int64_t const fr_time_multiplier_by_res[]
A time delta, a difference in time measured in nanoseconds.
static size_t char fr_sbuff_t size_t inlen
int format(printf, 5, 0))
static size_t char ** out