Date Calc
Synopsis
Performs calendar arithmetic: the current time, a time in the past, truncation to a period boundary, and the number of period boundaries between two timestamps.
Schema
- date_calc:
operation: <enum>
field: <ident>
right_field: <ident>
unit: <enum>
amount: <numeric>
description: <text>
if: <script>
ignore_failure: <boolean>
ignore_missing: <boolean>
on_failure: <processor[]>
on_success: <processor[]>
tag: <string>
target_field: <ident>
Configuration
The following fields are used to define the processor:
| Field | Required | Default | Description |
|---|---|---|---|
operation | Y | - | now, ago, start_of, end_of or diff. Matched case-insensitively |
field | Y* | - | Source timestamp. Required by start_of, end_of and diff; unused by now and ago |
right_field | Y* | - | The second timestamp. Required by diff only |
unit | Y* | - | Period unit. Required by every operation except now. Accepted values differ per operation — see below |
amount | Y* | - | How far back to go. Used by ago only |
description | N | - | Explanatory note |
if | N | - | Condition to run |
ignore_failure | N | false | See Handling Failures |
ignore_missing | N | false | If true, quietly exit if field doesn't exist |
on_failure | N | - | See Handling Failures |
on_success | N | - | See Handling Success |
tag | N | - | Identifier |
disabled | N | false | When true, the processor is skipped and the event continues to the next one. Lets you take a processor out of the path without removing its configuration |
target_field | N | field | Field to store the result. Falls back to field; if neither is set the processor fails with date_calc requires a target_field |
* = Conditionally required, by operation. See the table below.
Details
| Operation | Reads | Writes |
|---|---|---|
now | Nothing | The current UTC time |
ago | amount + unit | The current UTC time minus that duration |
start_of | field + unit | The first instant of the period containing that timestamp |
end_of | field + unit | The last instant of that period |
diff | field + right_field + unit | A number: how many period boundaries lie between them |
The four operations that produce a time write an RFC 3339 string in UTC, not a timestamp object. diff is the exception and writes an integer.
Units by operation
The accepted units are not the same for every operation, and a unit valid for one is an error on another:
| Operation | Accepted units |
|---|---|
ago | seconds, minutes, hours, days — plural |
start_of, end_of | day, week, month, year — singular |
diff | second, minute, hour, day, week, month, year — singular |
ago is the only operation taking plural unit names, because it expresses a duration rather than naming a period.
What diff counts
diff counts boundaries crossed, not elapsed time. With unit: day, two timestamps 30 minutes apart return 1 if they fall either side of midnight, and 0 if they do not. With unit: year, the 31st of December and the following 1st of January are 1 year apart even though an hour separates them.
This is what you want for questions like "was this on a different day?" and wrong for "how long did this take?" — use Math on epoch values for elapsed duration.
end_of returns the last representable instant inside the period — one nanosecond before the next period begins — so a range test using it is inclusive at both ends.
Examples
Truncating to a Day
Bucketing an event to the start of its day... | |
as an RFC 3339 string in UTC: | |
A Retention Cutoff
Writing the timestamp of 30 days ago for comparison... | |
note the plural unit, which | |
Counting Boundaries
Asking whether two events fall on different days... | |
which is 1, despite only 30 minutes elapsing: | |
The End of a Month
| |
so an inclusive range test works at both ends: | |