If no argument is passed, it returns the current time. Otherwise if the argument is:
+* `dst` - returns a `bool` indicating whether or not the system is running in daylight savings time.
+* `mday_offset` - returns the `time_delta` offset since the start of the month. Use `%d` to get an integer representing the day of the month.
* `now` - returns the current time
-* `request` - returns the time at which the request packet was received (always less than `now`!)
* `offset` - returns a `time_delta` of the current time zone offset. This value may be negative.
-* `dst` - returns a `bool` indicating whether or not the system is running in daylight savings time.
+* `request` - returns the time at which the request packet was received (always less than `now`!)
+* `wday_offset` - returns the `time_delta` offset since the start of the week.
* any other string is parsed as type `date`, using the normal date parsing routines.
.Example
/** Return the time as a #FR_TYPE_DATE
*
+ * Note that all operations are UTC.
+ *
@verbatim
%(time:)
@endverbatim
vb->vb_bool = fr_time_is_dst();
goto append;
+ } else if (strcmp(arg->vb_strvalue, "mday_offset") == 0) {
+ struct tm tm;
+ fr_unix_time_t unix_time = fr_time_to_unix_time(request->packet->timestamp);
+ time_t when = fr_unix_time_to_sec(unix_time);
+ int64_t nsec;
+
+ gmtime_r(&when, &tm);
+
+ nsec = 86400 * (tm.tm_mday - 1);
+ nsec += when % 86400;
+ nsec *= NSEC;
+ nsec += fr_unix_time_unwrap(unix_time) % NSEC;
+
+ MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_TIME_DELTA, NULL, false));
+ vb->vb_time_delta = fr_time_delta_wrap(nsec);
+ goto append;
+
+ } else if (strcmp(arg->vb_strvalue, "wday_offset") == 0) {
+ struct tm tm;
+ fr_unix_time_t unix_time = fr_time_to_unix_time(request->packet->timestamp);
+ time_t when = fr_unix_time_to_sec(unix_time);
+ int64_t nsec;
+
+ gmtime_r(&when, &tm);
+
+ nsec = 86400 * tm.tm_wday;
+ nsec += when % 86400;
+ nsec *= NSEC;
+ nsec += fr_unix_time_unwrap(unix_time) % NSEC;
+
+ MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_TIME_DELTA, NULL, false));
+ vb->vb_time_delta = fr_time_delta_wrap(nsec);
+
+ MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_TIME_DELTA, NULL, false));
+ vb->vb_time_delta = fr_time_delta_wrap(nsec);
+ goto append;
+
} else if (fr_unix_time_from_str(&value, arg->vb_strvalue, FR_TIME_RES_SEC) < 0) {
REDEBUG("Invalid time specification '%s'", arg->vb_strvalue);
return XLAT_ACTION_FAIL;