Skip to main content
penscript provides operators for creating, formatting, comparing, and manipulating dates. These are used for deadline calculations, age-based eligibility rules, contract expiration checks, and time-sensitive automations.

Date Creation: :date

Creates a date from a string or retrieves the current date/time.
{ ":date": "now" }
// Result: "2026-01-27T16:34:54.757Z"

{ ":date": "2000-11-20" }
// Result: "2000-11-20T00:00:00.000Z"
Strings in ISO 8601 format ("2024-01-15T00:00:00.000Z") and YYYY-MM-DD format ("2024-01-15") are automatically parsed as dates. The system variable {$today} is also available in inline expressions for the current date.

Date Formatting: :format-date

Formats a date according to a pattern string.
{
  ":format-date": { ":date": "now" },
  ":pattern": "Y"
}
// Result: "2026"

{
  ":format-date": { ":date": "now" },
  ":pattern": "Y-M-D"
}
// Result: "2026-01-27"

{
  ":format-date": { ":date": "now" },
  ":pattern": "D/M/Y"
}
// Result: "27/01/2026"

Pattern Characters

CharacterDescription
YYear, 4 digits
yYear, 2–4 digits
MMonth, 2 digits (zero-padded)
mMonth, 1–2 digits
DDay, 2 digits (zero-padded)
dDay, 1–2 digits
xAny non-digit separator

Inline Formatting with Pipes

For quick formatting inside strings, use the formatDdMmYyyy pipe:
"{$today | formatDdMmYyyy}"
// → "27/01/2026"

"{data.created_at | formatDdMmYyyy}"
// Scope: { "data": { "created_at": "2015-10-20" } }
// → "20/10/2015"

Date Comparison

Using :cmp

Combine :cmp with dates and the | age pipe for age-based conditions:
{
  ":if": [
    {
      ":cmp": "{data.birthdate | age}",
      ":gte": 18,
      ":lte": 65
    }
  ],
  ":then": "Eligible",
  ":else": "Not eligible"
}
All standard comparison modifiers work: :eq, :neq, :gt, :gte/:ge, :lt, :lte/:le.

Inline Date Comparisons

Simple date comparisons can be expressed directly inside strings:
{
  ":if": "{{ myDate > now }}",
  ":then": "Future date",
  ":else": "Past or current date"
}
Direct inline comparison patterns:
"{ my_date > $today }"
// → true if my_date is after today

"{ my_date == $today }"
// → equality check with today

"{ data.birthdate | age >= 18 }"
// → age check

"{ my_date > $today ? 'Future' : 'Past' }"
// → ternary
Combined conditions:
"{ my_date != $today | my_date < $today }"
// → true if my_date is not today or is in the past

Date Difference: :diff

Calculates the difference between two dates in a specified unit.
{
  ":diff": [
    "{data.date1}",
    "{data.date2}",
    {
      ":comparator": "day"
    }
  ]
}

// Scope: { "data": { "date1": "2024-01-01", "date2": "2024-02-04" } }
// Result: 34

Available Comparators

ComparatorReturns
"day"Number of days between the dates
"hour"Number of hours
"minute"Number of minutes
"second"Number of seconds

Age Calculation: | age

Calculates the age in years from a date value. Available as an inline pipe.
"{data.birthdate | age}"

// Scope: { "data": { "birthdate": "2007-01-01" } }
// Result: 18
Commonly combined with :cmp for eligibility rules:
{
  ":if": [
    { ":cmp": "{data.birthdate | age}", ":gte": 18 }
  ],
  ":then": "Adult",
  ":else": "Minor"
}

Date Arithmetic: :sum with Dates

Add or subtract time from dates using duration strings. Single duration:
{
  ":format-date": {
    ":sum": ["{$today}", "2d"]
  }
}
// Result: Current date + 2 days
Multiple durations combined:
{
  ":format-date": {
    ":sum": ["{$today}", "2d", "3d", "72h", "2y"]
  }
}
// Result: Current date + 2 days + 3 days + 72 hours + 2 years

Supported Duration Units

UnitExampleDescription
Days"2d", "3d"Add days
Hours"72h"Add hours
Years"2y"Add years

Raw Numbers and Strings

  • Raw numbers are treated as milliseconds. Negative numbers subtract time.
  • Numeric strings (e.g., "+86400") are treated as seconds.
{
  ":format-date": {
    ":sum": [
      { ":date": "now" },
      -8640000000
    ],
    ":pattern": "D-M-Y"
  }
}
// Result: Current date minus 100 days

Building Deadlines

A common pattern — calculate a deadline and format it for display:
{
  ":format-date": {
    ":sum": ["{$today}", "30d"]
  },
  ":pattern": "D/M/Y"
}
// → "13/03/2026" (30 days from today)

Next Steps