From: Alan T. DeKok Date: Sat, 21 Jan 2023 21:46:54 +0000 (-0500) Subject: date % time_delta --> time_delta X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2cf20250ed659c4a52bd10d2a2bb656ec9bab8c8;p=thirdparty%2Ffreeradius-server.git date % time_delta --> time_delta so we can round dates up / down as appropriate. Note that this really only works for fixed periods of time_delta, such as seconds / minutes / hours / days. It doesn't work for months. --- diff --git a/src/lib/util/calc.c b/src/lib/util/calc.c index 09d38f8ec61..691f0c74a6d 100644 --- a/src/lib/util/calc.c +++ b/src/lib/util/calc.c @@ -774,6 +774,22 @@ static int calc_time_delta(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value } } + /* + * date % (time_delta) 1d --> time_delta + */ + if (op == T_MOD) { + /* + * We MUST specify date ranges as a time delta, not as an integer. And it must be a + * positive time delta. + */ + if ((b->type != FR_TYPE_TIME_DELTA) || !fr_time_delta_ispos(b->vb_time_delta)) { + return ERR_INVALID; + } + + dst->vb_time_delta = fr_time_delta_wrap(fr_unix_time_unwrap(a->vb_date) % fr_time_delta_unwrap(b->vb_time_delta)); + return 0; + } + /* * Unix times are always converted 1-1 to our internal * TIME_DELTA. @@ -1837,6 +1853,14 @@ int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint if (hint != FR_TYPE_NULL) break; } + /* + * date % time_delta --> time_delta + */ + if ((op == T_MOD) && (a->type == FR_TYPE_DATE)) { + hint = FR_TYPE_TIME_DELTA; + break; + } + switch (op) { case T_OP_CMP_EQ: case T_OP_NE: