Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

DateTime Operators

Operations for working with dates, times, and durations.

Feature flag (Rust crate). All datetime operators require the datetime feature (which pulls in chrono). Every language binding enables it. See the feature table.

now

Get the current UTC datetime.

Syntax:

{ "now": [] }

Arguments: None

Returns: The current UTC datetime as a datetime value (rendered as an ISO 8601 string in JSON output).

Examples:

{ "now": [] }
// Result: "2024-01-15T14:30:00Z" (current time)

// Check if date is in the future
{ ">": [{ "var": "expiresAt" }, { "now": [] }] }
// Data: { "expiresAt": "2025-12-31T00:00:00Z" }
// Result: true or false depending on current time

// Check if event is happening now
{ "and": [
    { "<=": [{ "var": "startTime" }, { "now": [] }] },
    { ">=": [{ "var": "endTime" }, { "now": [] }] }
]}

Try it:

Notes:

  • Produces a datetime value, rendered as an ISO 8601 string (e.g., “2024-01-15T14:30:00Z”); its type is “datetime”, not “string”
  • Always uses UTC time
  • Useful for time-based conditions and comparisons

datetime

Parse or validate a datetime value.

Syntax:

{ "datetime": value }

Arguments:

  • value - An RFC 3339 datetime string (2024-01-01T00:00:00Z, or with a +HH:MM/-HH:MM offset; fractional seconds and a space instead of T are accepted), or a naive YYYY-MM-DDTHH:MM:SS string, which is read as UTC. Date-only strings (2024-01-01) and colon-less offsets (-0500, +05) are rejected with Invalid datetime format; use parse_date for those and for custom formats

Returns: A datetime value (rendered as an ISO 8601 string, preserving the parsed offset); its type is “datetime”, not “string”.

Examples:

// Parse ISO string
{ "datetime": "2024-01-01T00:00:00Z" }
// Result: "2024-01-01T00:00:00Z"

// With timezone offset
{ "datetime": "2024-01-01T10:00:00+05:30" }
// Result: "2024-01-01T10:00:00+05:30"

// Compare datetimes
{ ">": [
    { "datetime": "2024-06-15T00:00:00Z" },
    { "datetime": "2024-01-01T00:00:00Z" }
]}
// Result: true

// Add duration to datetime
{ "+": [
    { "datetime": "2024-01-01T00:00:00Z" },
    { "timestamp": "7d" }
]}
// Result: "2024-01-08T00:00:00Z"

Try it:


timestamp

Create or parse a duration value. Durations represent time periods (not points in time).

Syntax:

{ "timestamp": duration_string }

Arguments:

  • duration_string - Duration in format like “1d:2h:3m:4s”, partial like “1d”, “2h”, “30m”, “45s”, or compact like “1d2h3m4s”

Returns: A duration value (its type is “duration”, like now/datetime produce “datetime”), rendered as a normalized “Xd:Xh:Xm:Xs” string in JSON output.

Duration Format:

  • d - Days
  • h - Hours
  • m - Minutes
  • s - Seconds

Examples:

// Full duration format
{ "timestamp": "1d:2h:3m:4s" }
// Result: "1d:2h:3m:4s"

// Days only
{ "timestamp": "2d" }
// Result: "2d:0h:0m:0s"

// Hours only
{ "timestamp": "5h" }
// Result: "0d:5h:0m:0s"

// Minutes only
{ "timestamp": "30m" }
// Result: "0d:0h:30m:0s"

// Compare durations
{ ">": [{ "timestamp": "2d" }, { "timestamp": "36h" }] }
// Result: true (2 days > 36 hours)

// Duration equality
{ "==": [{ "timestamp": "1d" }, { "timestamp": "24h" }] }
// Result: true

// Compact form
{ "timestamp": "1d2h3m4s" }
// Result: "1d:2h:3m:4s"

// Units overflow into the next larger unit
{ "timestamp": "36h" }
// Result: "1d:12h:0m:0s"

Notes:

  • Produces a duration value; { "type": { "timestamp": "1d" } } is "duration"
  • Units overflow-normalise ("1d:25h" becomes "2d:1h:0m:0s")
  • Negative ("-1d"), fractional ("1.5h"), week ("1w"), and numeric (3600) inputs are rejected with Invalid duration format

Try it:

Duration Arithmetic

Durations can be used in arithmetic operations:

// Multiply duration
{ "*": [{ "timestamp": "1d" }, 2] }
// Result: "2d:0h:0m:0s"

// Divide duration
{ "/": [{ "timestamp": "2d" }, 2] }
// Result: "1d:0h:0m:0s"

// Add durations
{ "+": [{ "timestamp": "1d" }, { "timestamp": "12h" }] }
// Result: "1d:12h:0m:0s"

// Subtract durations
{ "-": [{ "timestamp": "2d" }, { "timestamp": "12h" }] }
// Result: "1d:12h:0m:0s"

// Add duration to datetime
{ "+": [
    { "datetime": "2024-01-01T00:00:00Z" },
    { "timestamp": "7d" }
]}
// Result: "2024-01-08T00:00:00Z"

// Subtract duration from datetime
{ "-": [
    { "datetime": "2024-01-15T00:00:00Z" },
    { "timestamp": "7d" }
]}
// Result: "2024-01-08T00:00:00Z"

// Difference between two datetimes (returns duration)
{ "-": [
    { "datetime": "2024-01-08T00:00:00Z" },
    { "datetime": "2024-01-01T00:00:00Z" }
]}
// Result: "7d:0h:0m:0s"

// The result of datetime +/- duration is a UTC instant: the parsed offset is not carried through
{ "+": [
    { "datetime": "2024-01-01T10:00:00+05:30" },
    { "timestamp": "1d" }
]}
// Result: "2024-01-02T04:30:00Z"

Note: duration arithmetic on a datetime that carries an offset drops that offset: the result renders as ...Z, and format_date with the bare "z" format reports +0000 for it. To render such a result in a local zone, pass the zone argument to format_date (for example "Asia/Kolkata", which gives "10:00" for the example above with format "HH:mm").


parse_date

Parse a date string with a custom format into a datetime value.

Syntax:

{ "parse_date": [string, format] }
{ "parse_date": [string, format, timezone] }

Arguments:

  • string - Date string to parse
  • format - Format string using simplified tokens
  • timezone - Optional IANA zone name (e.g. "Asia/Kolkata"). Without it, naive input is read as UTC; with it, the input is read as wall-clock time in that zone and resolved to the corresponding UTC instant.

Returns: A datetime value (rendered as an ISO 8601 string in JSON output); its type is “datetime”, not “string”.

Format Tokens:

TokenDescriptionExample
yyyy4-digit year2024
MMMMfull month nameJanuary
MMMabbreviated month nameJan
MM2-digit month01-12
dd2-digit day01-31
HH2-digit hour (24h)00-23
mm2-digit minute00-59
ss2-digit second00-59
EEEEfull weekday nameMonday
EEEabbreviated weekday nameMon

Raw chrono % specifiers also pass through unchanged.

Examples:

// Parse US date format
{ "parse_date": ["12/25/2024", "MM/dd/yyyy"] }
// Result: "2024-12-25T00:00:00Z"

// Parse European format
{ "parse_date": ["25-12-2024", "dd-MM-yyyy"] }
// Result: "2024-12-25T00:00:00Z"

// Parse date only
{ "parse_date": ["2024-01-15", "yyyy-MM-dd"] }
// Result: "2024-01-15T00:00:00Z"

// Read a naive local time as New York wall clock (EDT in June)
{ "parse_date": ["2024-06-15 12:00:00", "yyyy-MM-dd HH:mm:ss", "America/New_York"] }
// Result: "2024-06-15T16:00:00Z"

// With variable
{ "parse_date": [{ "var": "dateStr" }, "yyyy-MM-dd"] }
// Data: { "dateStr": "2024-06-15" }
// Result: "2024-06-15T00:00:00Z"

Timezone notes:

  • Zone offsets (including DST) come from the compiled-in IANA table: no fixed-offset arithmetic, no tzdata I/O.
  • An ambiguous local time (clocks rolled back, the wall-clock occurs twice) resolves to the earlier instant; a nonexistent one (spring-forward gap) is an error.
  • An unknown zone name that appears as a literal in the rule is rejected while the rule is compiled, but Engine::compile itself still succeeds: the call is replaced by a marker that raises Invalid Arguments (naming the operator, not the zone) when the rule is evaluated. A zone arriving through data fails at evaluation with Unknown timezone: <name>.

Try it:


format_date

Format a datetime as a string with a custom format.

Syntax:

{ "format_date": [datetime, format] }
{ "format_date": [datetime, format, timezone] }

Arguments:

  • datetime - Datetime value to format
  • format - Format string using simplified tokens (same as parse_date)
  • timezone - Optional IANA zone name (e.g. "Asia/Kolkata"). When present, the instant is rendered as wall-clock time in that zone (DST-correct via the IANA table) instead of UTC.

Returns: Formatted date string.

Special Format:

  • z - Returns the timezone offset (e.g., “+0500”). Without a zone argument this is the source offset the datetime was parsed with; with a zone argument it is the target zone’s offset at that instant.
  • z is honoured only when it is the entire format string. Inside a longer format it is emitted literally: "yyyy-MM-dd HH:mm z" on 2024-01-01T10:00:00+05:30 gives "2024-01-01 04:30 z".
  • Without a zone argument every other token renders the UTC instant, so "HH:mm" on that same value gives "04:30" and the raw chrono %z gives +0000; the source offset is reachable only through the bare "z" format. To get wall-clock time plus offset in one string, pass the zone argument and use %z or %Z: "HH:mm %z" with "Asia/Kolkata" gives "10:00 +0530", and "HH:mm %Z" gives "10:00 IST".

Examples:

// Format as date only
{ "format_date": [{ "datetime": "2024-01-15T14:30:00Z" }, "yyyy-MM-dd"] }
// Result: "2024-01-15"

// Format as US date
{ "format_date": [{ "datetime": "2024-12-25T00:00:00Z" }, "MM/dd/yyyy"] }
// Result: "12/25/2024"

// Get timezone offset (the format must be exactly "z")
{ "format_date": [{ "datetime": "2024-01-01T10:00:00+05:00" }, "z"] }
// Result: "+0500"

// Without a zone argument the other tokens render the UTC instant
{ "format_date": [{ "datetime": "2024-01-01T10:00:00+05:30" }, "HH:mm"] }
// Result: "04:30"

// Wall-clock time plus offset in one string needs the zone argument
{ "format_date": [{ "datetime": "2024-01-01T10:00:00+05:30" }, "HH:mm %z", "Asia/Kolkata"] }
// Result: "10:00 +0530"

// Render an instant as a calendar date in a zone
{ "format_date": [{ "datetime": "2026-08-17T18:30:00Z" }, "dd MMM yyyy", "Asia/Kolkata"] }
// Result: "18 Aug 2026"

// Zone offset at that instant (DST-aware)
{ "format_date": [{ "datetime": "2024-07-15T12:00:00Z" }, "z", "America/New_York"] }
// Result: "-0400"

// Format current time
{ "format_date": [{ "now": [] }, "yyyy-MM-dd"] }
// Result: "2024-01-15" (current date)

// With variable
{ "format_date": [{ "var": "date" }, "dd/MM/yyyy"] }
// Data: { "date": "2024-12-25T00:00:00Z" }
// Result: "25/12/2024"

Try it:


date_diff

Calculate the difference between two dates in a specified unit.

Syntax:

{ "date_diff": [date1, date2, unit] }

Arguments:

  • date1 - First datetime
  • date2 - Second datetime
  • unit - Unit of measurement: "days", "hours", "minutes", "seconds", or "milliseconds" (lowercase). Any other value is an Invalid Arguments error: date_diff: unknown unit "weeks" (expected days, hours, minutes, seconds, or milliseconds)

Returns: Difference (date1 - date2) as an integer in the specified unit, truncated toward zero; negative when date1 is earlier than date2.

Examples:

// Days between dates
{ "date_diff": [
    { "datetime": "2024-12-31T00:00:00Z" },
    { "datetime": "2024-01-01T00:00:00Z" },
    "days"
]}
// Result: 365

// Hours difference
{ "date_diff": [
    { "datetime": "2024-01-01T12:00:00Z" },
    { "datetime": "2024-01-01T00:00:00Z" },
    "hours"
]}
// Result: 12

// Milliseconds
{ "date_diff": [
    { "datetime": "2024-01-01T00:00:01Z" },
    { "datetime": "2024-01-01T00:00:00Z" },
    "milliseconds"
]}
// Result: 1000

// Negative when the first date is earlier
{ "date_diff": [
    { "datetime": "2024-01-01T00:00:00Z" },
    { "datetime": "2024-01-02T00:00:00Z" },
    "days"
]}
// Result: -1

// Unknown units are an error (catchable with try)
{ "date_diff": [
    { "datetime": "2024-01-02T00:00:00Z" },
    { "datetime": "2024-01-01T00:00:00Z" },
    "weeks"
]}
// Result: error (Invalid Arguments)

// With variables
{ "date_diff": [
    { "var": "end" },
    { "var": "start" },
    "days"
]}
// Data: {
//   "start": "2024-01-01T00:00:00Z",
//   "end": "2024-01-15T00:00:00Z"
// }
// Result: 14

// Check if within 24 hours
{ "<": [
    { "date_diff": [{ "now": [] }, { "var": "timestamp" }, "hours"] },
    24
]}
// Data: { "timestamp": "2024-01-15T10:00:00Z" }
// Result: true or false

// Days since creation
{ "date_diff": [
    { "now": [] },
    { "var": "createdAt" },
    "days"
]}

Try it:


DateTime Patterns

Check if date is in the past

{ "<": [{ "var": "date" }, { "now": [] }] }

Check if date is in the future

{ ">": [{ "var": "date" }, { "now": [] }] }

Check if within time window

{ "and": [
    { ">=": [{ "now": [] }, { "var": "startTime" }] },
    { "<=": [{ "now": [] }, { "var": "endTime" }] }
]}

Add days to a date

{ "+": [
    { "var": "date" },
    { "timestamp": "7d" }
]}

Calculate days until expiration

{ "date_diff": [
    { "var": "expiresAt" },
    { "now": [] },
    "days"
]}

Check if expired

{ "<": [{ "var": "expiresAt" }, { "now": [] }] }