ical API reference
Build and parse iCalendar (RFC 5545): a Calendar holding Events (VEVENT) and Todos (VTODO), encoded to a VCALENDAR and parsed back. Pure Jennifer over strings / lists + time - no Go, no system engine.
Beyond the basics (UID / SUMMARY / DESCRIPTION / LOCATION), an event supports recurrence (RRULE / RDATE / EXDATE, with an occurrences expander for FREQ / INTERVAL / COUNT / UNTIL), all-day dates (VALUE=DATE) and a named-zone TZID, an ORGANIZER and ATTENDEEs, and VALARM alarms. Times go through time: UTC values write as 20240615T130000Z; a TZID event stores its wall clock as a floating value paired with the zone name (because time models fixed-offset zones only, add a matching VTIMEZONE for a strict consumer). Text values are RFC 5545-escaped and content lines folded at 75 octets, so parse(encode(cal)) round-trips.
Import with import "ical.j" as ical;. See the ical guide for prose and examples.
Functions
ical.add(cal as Calendar, ev as Event)
A copy of the calendar with an event appended (value-semantic).
Parameters
cal{Calendar}- the calendarev{Event}- the event to add
Returns {Calendar} - a fresh calendar with the event appended
ical.addAlarm(ev as Event, a as Alarm)
A copy of the event with a VALARM appended.
Parameters
ev{Event}- the eventa{Alarm}- the alarm
Returns {Event} - a fresh event with the alarm added
ical.addAttendee(ev as Event, a as Attendee)
A copy of the event with an ATTENDEE appended.
Parameters
ev{Event}- the eventa{Attendee}- the attendee
Returns {Event} - a fresh event with the attendee added
ical.addExdate(ev as Event, t as time.Time)
A copy of the event with an excluded recurrence instant (EXDATE) appended.
Parameters
ev{Event}- the eventt{time.Time}- the excluded instant
Returns {Event} - a fresh event with the EXDATE added
ical.addRdate(ev as Event, t as time.Time)
A copy of the event with an extra recurrence instant (RDATE) appended.
Parameters
ev{Event}- the eventt{time.Time}- the extra instant
Returns {Event} - a fresh event with the RDATE added
ical.addTodo(cal as Calendar, td as Todo)
A copy of the calendar with a to-do appended.
Parameters
cal{Calendar}- the calendartd{Todo}- the to-do to add
Returns {Calendar} - a fresh calendar with the to-do appended
ical.alarm(action as string, trigger as string, description as string)
An alarm (VALARM).
Parameters
action{string}- the action ("DISPLAY" / "AUDIO" / "EMAIL")trigger{string}- the trigger value (e.g.-PT15M)description{string}- the reminder text ("" for none)
Returns {Alarm} - the alarm
ical.attendee(address as string, cn as string, role as string)
An attendee.
Parameters
address{string}- the calendar address (e.g.mailto:bob@example.com)cn{string}- the common name ("" for none)role{string}- the role ("" for none; e.g. "REQ-PARTICIPANT")
Returns {Attendee} - the attendee
ical.calendar()
A calendar with the default Jennifer PRODID and no events.
Returns {Calendar} - the empty calendar
ical.calendarWith(prodid as string)
A calendar with a caller-supplied PRODID.
Parameters
prodid{string}- the product identifier
Returns {Calendar} - the empty calendar
ical.describe(ev as Event, description as string)
A copy of the event with its description set (value-semantic).
Parameters
ev{Event}- the eventdescription{string}- the description text
Returns {Event} - a fresh event with the description set
ical.describeTodo(td as Todo, description as string)
A copy of the to-do with its DESCRIPTION set.
Parameters
td{Todo}- the to-dodescription{string}- the description
Returns {Todo} - a fresh to-do with the description set
ical.encode(cal as Calendar)
Render a calendar to iCalendar text (RFC 5545): a VCALENDAR wrapping one VEVENT per event (and a VTODO per to-do), CRLF line endings, escaped text, folded long lines. Optional properties (DESCRIPTION / LOCATION / recurrence / organizer / attendees / alarms) are emitted only when set.
Parameters
cal{Calendar}- the calendar to encode
Returns {string} - the iCalendar text (CRLF-terminated)
ical.event(uid as string, start as time.Time, end as time.Time, summary as string)
An event. DTSTAMP defaults to the start; the optional fields (DESCRIPTION / LOCATION / recurrence / organizer / attendees / alarms) are empty until set with the describe / locate / recur / ... builders.
Parameters
uid{string}- the unique identifierstart{time.Time}- the start instantend{time.Time}- the end instantsummary{string}- the title
Returns {Event} - the event
ical.locate(ev as Event, location as string)
A copy of the event with its location set (value-semantic).
Parameters
ev{Event}- the eventlocation{string}- the location text
Returns {Event} - a fresh event with the location set
ical.occurrences(ev as Event, max as int)
Expand an event's recurrence into up to max occurrence instants, in order: the RRULE series from DTSTART (honouring FREQ / INTERVAL / COUNT / UNTIL), plus any RDATEs, minus any EXDATEs. A non-recurring event yields just its start. Only the frequency rules are expanded - BYDAY / BYMONTH and other BY* parts are not applied (the base cadence is still produced), so this covers the common "every N days / weeks / months / years" case.
Parameters
ev{Event}- the eventmax{int}- the maximum number of occurrences to return
Returns {list of time.Time} - the occurrence instants (at most max)
ical.parse(text as string)
Parse iCalendar text into a Calendar. Unfolds folded lines and reads the PRODID, each VEVENT (UID / DTSTAMP / DTSTART / DTEND / SUMMARY / DESCRIPTION / LOCATION, the all-day VALUE=DATE and TZID parameters, RRULE / RDATE / EXDATE, ORGANIZER / ATTENDEE, and nested VALARMs), and each VTODO. A VTIMEZONE is parsed and skipped. An event with no DTSTART is skipped; a missing DTEND defaults to the start.
Parameters
text{string}- the iCalendar text
Returns {Calendar} - the parsed calendar
ical.recur(ev as Event, rrule as string)
A copy of the event with a recurrence rule (RRULE). Pass a raw RRULE value (e.g. "FREQ=WEEKLY;COUNT=10") or build one with rule.
Parameters
ev{Event}- the eventrrule{string}- the RRULE value
Returns {Event} - a fresh recurring event
ical.rule(freq as string, interval as int, count as int)
Build a simple RRULE value from a frequency, interval, and count. INTERVAL is omitted when 1 and COUNT when 0 (i.e. unbounded).
Parameters
freq{string}- the frequency ("DAILY" / "WEEKLY" / "MONTHLY" / "YEARLY")interval{int}- the interval (every N periods; 1 = every period)count{int}- the number of occurrences (0 = unbounded)
Returns {string} - the RRULE value
ical.todo(uid as string, stamp as time.Time, summary as string)
A to-do (VTODO). DTSTAMP defaults to stamp; DUE / STATUS / DESCRIPTION are set with the builders.
Parameters
uid{string}- the unique identifierstamp{time.Time}- theDTSTAMPsummary{string}- the title
Returns {Todo} - the to-do
ical.withAllDay(ev as Event, isAllDay as bool)
A copy of the event marked (or unmarked) as an all-day event. All-day DTSTART / DTEND encode as VALUE=DATE (a bare YYYYMMDD).
Parameters
ev{Event}- the eventisAllDay{bool}- whether the event is all-day
Returns {Event} - a fresh event with the all-day flag set
ical.withDue(td as Todo, due as time.Time)
A copy of the to-do with its DUE instant set.
Parameters
td{Todo}- the to-dodue{time.Time}- the due instant
Returns {Todo} - a fresh to-do with the due date set
ical.withOrganizer(ev as Event, address as string)
A copy of the event with its ORGANIZER set.
Parameters
ev{Event}- the eventaddress{string}- the calendar address (e.g.mailto:a@example.com)
Returns {Event} - a fresh event with the organizer set
ical.withStatus(td as Todo, status as string)
A copy of the to-do with its STATUS set (e.g. "NEEDS-ACTION" / "COMPLETED").
Parameters
td{Todo}- the to-dostatus{string}- the status
Returns {Todo} - a fresh to-do with the status set
ical.withZone(ev as Event, tzid as string)
A copy of the event with its time-zone id (TZID) set, so DTSTART / DTEND encode as local time in that zone (DTSTART;TZID=America/New_York:...) instead of UTC. The named zone is preserved verbatim; add a matching VTIMEZONE for a strict consumer.
Parameters
ev{Event}- the eventtzid{string}- the IANA time-zone name (e.g. "Europe/London"); "" restores UTC
Returns {Event} - a fresh event with the time zone set
Structs
ical.Alarm
An event alarm (VALARM).
| Field | Type | Description |
|---|---|---|
action | string | the ACTION ("DISPLAY" / "AUDIO" / "EMAIL") |
trigger | string | the TRIGGER value (e.g. -PT15M = 15 minutes before) |
description | string | the DESCRIPTION (the reminder text; "" when unset) |
ical.Attendee
An event attendee (ATTENDEE).
| Field | Type | Description |
|---|---|---|
address | string | the calendar address (e.g. mailto:bob@example.com) |
cn | string | the common name (CN parameter; "" when unset) |
role | string | the participation role (ROLE; e.g. "REQ-PARTICIPANT"; "" when unset) |
ical.Calendar
A calendar: a product identifier, its events, and its to-dos.
| Field | Type | Description |
|---|---|---|
prodid | string | the PRODID product identifier |
events | list of Event | the calendar's events |
todos | list of Todo | the calendar's to-dos (VTODOs) |
ical.Event
A single calendar event (a VEVENT).
| Field | Type | Description |
|---|---|---|
uid | string | the globally-unique UID |
stamp | time.Time | the DTSTAMP (creation / last-modified instant) |
start | time.Time | the DTSTART start instant |
end | time.Time | the DTEND end instant |
summary | string | the SUMMARY (title) |
description | string | the DESCRIPTION ("" when unset) |
location | string | the LOCATION ("" when unset) |
allDay | bool | whether the event is an all-day event (VALUE=DATE) |
tzid | string | the TZID time-zone name for a local DTSTART / DTEND ("" = UTC) |
rrule | string | the RRULE recurrence rule value ("" when non-recurring) |
rdates | list of time.Time | extra recurrence instants (RDATE) |
exdates | list of time.Time | excluded recurrence instants (EXDATE) |
organizer | string | the ORGANIZER calendar address ("" when unset) |
attendees | list of Attendee | the ATTENDEEs |
alarms | list of Alarm | the event's VALARMs |
ical.Todo
A to-do item (a VTODO).
| Field | Type | Description |
|---|---|---|
uid | string | the globally-unique UID |
stamp | time.Time | the DTSTAMP |
summary | string | the SUMMARY |
due | time.Time | the DUE instant (valid only when hasDue) |
hasDue | bool | whether a DUE is set |
description | string | the DESCRIPTION ("" when unset) |
status | string | the STATUS (e.g. "NEEDS-ACTION" / "COMPLETED"; "" when unset) |