Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 5 Nov 2026. What's built · Install 0.3.0
jadpo
ReferenceTime and calendar

LanguageValues and typesStandard typesTime and calendar

CalendarEvent

On this page

A calendar event, as a calendar app reads one: a title, and its days or its times.

Use it to send an invitation or an .ics entry. For when something repeats on its own, use RecurrenceRule.

Shape

Field Type Required?
summary Text Yes
first_day CalendarDate No
last_day CalendarDate No
start LocalDateTime No
end LocalDateTime No
zone Zone No
location Text No
description Text No
recurrence RecurrenceRule No

Write every field when you build one, and give a field that isn't required as none.

Its parts keep these rules, and a value that breaks one fails with the rule's name:

  • days_or_times: first_day and last_day with no start, end or zone, or start, end and zone with no days
  • last_day_not_before_first: last_day >= first_day
  • end_after_start: end > start
  • recurrence_from_start: recurrence starts on first_day, or at start in zone

Example

example
CalendarEvent {    summary: "Team lunch"    first_day: "2026-12-18"    last_day: "2026-12-18"    start: none    end: none    zone: none    location: none    description: none    recurrence: none}

text.parse(raw, as: CalendarEvent) reads one from text that comes from outside. Text that isn't one at all fails malformed.

Good to know

  • An event has either days (first_day and last_day) or times (start, end and zone), never both.
  • last_day is included, even though calendar files write the day after.
  • == tells you whether two are the same. < and list.sort_by don't take it, so sort by one of its parts instead.

In JSON

An object of its parts, in a request, a response or json.write:

json
{"summary":"Christmas Day","first_day":"2026-12-25","last_day":"2026-12-25","start":null,"end":null,"zone":null,"location":null,"description":null,"recurrence":null}{"summary":"Half-term walk","first_day":"2026-10-24","last_day":"2026-10-26","start":null,"end":null,"zone":null,"location":"Keswick, Cumbria","description":"Boots; maps\nFlask","recurrence":null}{"summary":"Wedding anniversary","first_day":"2024-02-29","last_day":"2024-02-29","start":null,"end":null,"zone":null,"location":null,"description":null,"recurrence":"DTSTART;VALUE=DATE:20240229\nRRULE:FREQ=YEARLY"}

When you read one, a field that isn't required may be left out, or sent as null.

Details

Text form, storage, how it is shown, and operations

CalendarEvent is in the group Time and calendar, and has been in Jadpo since 0.1.0.

Text form

text.from writes one standard text form, the same form text.parse reads back: BEGIN:VEVENT\nDTSTART;VALUE=DATE:20261225\nDTEND;VALUE=DATE:20261226\nSUMMARY:Christmas Day\nEND:VEVENT, BEGIN:VEVENT\nDTSTART;VALUE=DATE:20261024\nDTEND;VALUE=DATE:20261027\nSUMMARY:Half-term walk\nLOCATION:Keswick\, Cumbria\nDESCRIPTION:Boots\; maps\nFlask\nEND:VEVENT and BEGIN:VEVENT\nDTSTART;VALUE=DATE:20240229\nDTEND;VALUE=DATE:20240301\nSUMMARY:Wedding anniversary\nRRULE:FREQ=YEARLY\nEND:VEVENT.

How it is stored

It is stored in 9 columns, each named for the field, _ and its suffix. This is BEGIN:VEVENT\nDTSTART;VALUE=DATE:20240229\nDTEND;VALUE=DATE:20240301\nSUMMARY:Wedding anniversary\nRRULE:FREQ=YEARLY\nEND:VEVENT:

Column Type Holds
<field>_summary text 'Wedding anniversary'
<field>_first_day date '2024-02-29'::date
<field>_last_day date '2024-02-29'::date
<field>_start timestamp NULL::timestamp
<field>_end timestamp NULL::timestamp
<field>_zone text NULL::text
<field>_location text NULL::text
<field>_description text NULL::text
<field>_recurrence text E'DTSTART;VALUE=DATE:20240229\nRRULE:FREQ=YEARLY'

How it is shown to people

text.format(value, locale:) shows it to people in their locale.

With locale: Locale.en_gb:

Value Shown
"BEGIN:VEVENT\nDTSTART;VALUE=DATE:20261225\nDTEND;VALUE=DATE:20261226\nSUMMARY:Christmas Day\nEND:VEVENT" "BEGIN:VEVENT\nDTSTART;VALUE=DATE:20261225\nDTEND;VALUE=DATE:20261226\nSUMMARY:Christmas Day\nEND:VEVENT"
"BEGIN:VEVENT\nDTSTART;VALUE=DATE:20261024\nDTEND;VALUE=DATE:20261027\nSUMMARY:Half-term walk\nLOCATION:Keswick\\, Cumbria\nDESCRIPTION:Boots\\; maps\\nFlask\nEND:VEVENT" "BEGIN:VEVENT\nDTSTART;VALUE=DATE:20261024\nDTEND;VALUE=DATE:20261027\nSUMMARY:Half-term walk\nLOCATION:Keswick\\, Cumbria\nDESCRIPTION:Boots\\; maps\\nFlask\nEND:VEVENT"
"BEGIN:VEVENT\nDTSTART;VALUE=DATE:20240229\nDTEND;VALUE=DATE:20240301\nSUMMARY:Wedding anniversary\nRRULE:FREQ=YEARLY\nEND:VEVENT" "BEGIN:VEVENT\nDTSTART;VALUE=DATE:20240229\nDTEND;VALUE=DATE:20240301\nSUMMARY:Wedding anniversary\nRRULE:FREQ=YEARLY\nEND:VEVENT"
"BEGIN:VEVENT\nDTSTART;TZID=Europe/London:20261024T220000\nDTEND;TZID=Europe/London:20261025T020000\nSUMMARY:Night shift\nRRULE:FREQ=WEEKLY;COUNT=4\nEND:VEVENT" "BEGIN:VEVENT\nDTSTART;TZID=Europe/London:20261024T220000\nDTEND;TZID=Europe/London:20261025T020000\nSUMMARY:Night shift\nRRULE:FREQ=WEEKLY;COUNT=4\nEND:VEVENT"

Operations

It also takes text.parse, text.from, text.format, json.read, json.write and ==. How every standard type behaves says how they work.

Markdown for agents: /docs/types/type-calendar-event.md.Built from Jadpo main at aee2e8f.