Internet-Draft JSCalendar November 2024
Stepanek Expires 16 May 2025 [Page]
Workgroup:
Calendaring extensions
Internet-Draft:
draft-ietf-calext-jscalendar-icalendar-09
Published:
Intended Status:
Experimental
Expires:
Author:
R. Stepanek
Fastmail

JSCalendar: Converting from and to iCalendar

Abstract

This document defines how to convert calendaring information between the JSCalendar and iCalendar data formats. It considers every JSCalendar and iCalendar element registered at IANA at the time of publication. It defines conversion rules for all elements that are common to both formats, as well as how convert arbitrary or unknown JSCalendar and iCalendar elements.

This note is to be removed before publishing as an RFC.

This document is unfinished. The term TBD stands for any unknown item.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 16 May 2025.

Table of Contents

1. Introduction

1.1. Notational Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

The ABNF definitions in this document use the notations of [RFC5234]. ABNF rules not defined in this document either are defined in [RFC5234] or [RFC5545].

1.2. Scope and Goals

This document outlines how to convert calendaring information between the iCalendar and JSCalendar data formats. It describes which elements are common to both, but also highlights where the two formats differ. For each common element, it defines a conversion rule and includes an example how to convert this element. All iCalendar and JSCalendar elements currently registered at IANA are in scope, but not all of these elements are common to both formats.

For elements that have no counterpart in the other format, it is the goal of this document to define how to preserve them during conversion, but in general it is not the goal to achieve this by defining new standard elements. Instead, this document defines special-purpose properties to preserve arbitrary elements. These conversion-specific properties are defined in Section 4.2.2 for iCalendar, and Sections 5.1.2 and 5.1.3 for JSCalendar. Appendix A further outlines the discrepancies between the two formats.

1.3. How to Read the Examples

Later sections contain examples that illustrate how to convert between the iCalendar and JSCalendar data formats. The notation of these examples is such that their main points should be clear to the reader, but their contents can also be parsed for automated testing. The authors of this document implemented a tool that extracts these examples for interoperation testing. The following sections define the notation for such examples.

1.3.1. iCalendar Examples

An iCalendar example contains either an extract or a complete representation of iCalendar data. It always represents an iCalendar object, even if the example only depicts non-VCALENDAR components or properties.

An example that only contains iCalendar properties implicitly represents a VEVENT component that is part of a VCALENDAR component. An example that only contains one or more non-VCALENDAR components implicitly represents a VCALENDAR component that contains them. Implicit components are assumed to contain mandatory properties with some value, but the actual value is irrelevant for the main point of the example. Notably, if an implicit component includes an ATTENDEE but not an ORGANIZER property, then an ORGANIZER property implicitly is present, too. The same applies for an example with an ORGANIZER but no ATTENDEE property.

Figure 1 contains three examples, all of which represent the same iCalendar data. In the first example, both the VEVENT component and VCALENDAR component are implicit. In the second example, only the VCALENDAR component and its mandatory properties are implicit. The third example depicts a complete VCALENDAR component, nothing is implicit.

SUMMARY:hello
BEGIN:VEVENT
DTSTAMP:20060102T030405Z
DTSTART:20060102T030405Z
SUMMARY:hello
UID:CC0A494A-6E07-4827-8294-0752DD1ECFA4
END:VEVENT
BEGIN:VCALENDAR
PRODID:-//FOO//bar//EN
VERSION:2.0
BEGIN:VEVENT
DTSTAMP:20060102T030405Z
DTSTART:20060102T030405Z
SUMMARY:hello
UID:CC0A494A-6E07-4827-8294-0752DD1ECFA4
END:VEVENT
END:VCALENDAR
Figure 1: Examples for implicit and explicit iCalendar component notation

A line containing just the value ... stands for any other properties that might be present in a component but are irrelevant for this example. This includes mandatory properties as described for implicit components. The line ... at the end of the example additionally stands for any END content lines to complete components that started with BEGIN content lines, and any of their missing mandatory properties. Figure 2 illustrates this as an alternative representation for the examples of Figure 1.

A line starting with a single space represents the continuation of a folded content line (Section 3.1 of [RFC5545]). Figure 3 illustrates this.

1.3.2. JSCalendar Examples

A JSCalendar example always represents a Group object, even if the example only depicts one of the Group entries or properties.

JSCalendar objects are depicted either explicitly or implicitly. An explicit JSCalendar object starts and ends with braces. An implicit JSCalendar object omits braces, it only consists of JSON name/value pairs, separated by comma.

An implicit JSCalendar object is assumed to be of type Event, unless it contains the @type property with a different value. It is assumed to contain all mandatory properties with some value; if they are not depicted, their actual value is irrelevant for the main point of the example.

Figure 4 illustrates this with multiple examples, all of which represent the same JSCalendar data. The first example contains an implicit JSCalendar object of type Event. The second example contains an implicit JSCalendar object with a @type property. The third example contains an explicit Event object but the Group object containing it is omitted. The fourth example contains the full Group object, nothing is omitted.

"title": "hello"
"@type": "Event",
"title": "hello"
{
  "@type": "Event",
  "title": "hello",
  "start": "2006-01-02T03:04:05",
  "timeZone": "Etc/UTC",
  "uid": "CC0A494A-6E07-4827-8294-0752DD1ECFA4",
  "updated": "2006-01-02T03:04:05Z"
}
{
  "@type": "Group",
  "entries": [
    {
      "@type": "Event",
      "title": "hello",
      "start": "2006-01-02T03:04:05",
      "timeZone": "Etc/UTC",
      "uid": "CC0A494A-6E07-4827-8294-0752DD1ECFA4",
      "updated": "2006-01-02T03:04:05Z"
    }
  ]
}
Figure 4: Examples for implicit and explicit JSCalendar object notation

A property with name "..." and value "" stands for additional properties that might be present in a JSCalendar object, but which are irrelevant for this example. This includes mandatory properties. Figure 5 illustrates this as an alternative representation for the examples of Figure 4.

{
  "@type": "Event",
  "title": "hello",
  "...": ""
}
Figure 5: Example for additional properties represented by ...

2. Converting iCalendar to JSCalendar

2.1. General rules

2.1.1. iCalendar Objects

Section 3.4 of [RFC5545] allows for an iCalendar stream to contain one or more iCalendar objects. In contrast, this specification only defines conversion for streams consisting of a single iCalendar object. Converting streams of multiple iCalendar objects is implementation-specific. All following sections of this document use the terms "iCalendar object" and "VCALENDAR component" interchangeably.

The VCALENDAR component [RFC5545] (Section 3.4) converts to a Group object [RFC8984] (Section 2.3).

Its properties convert as follows:

Table 1: Properties of the VCALENDAR component
Name Reference Group property See Note
CATEGORIES [RFC5545], Section 3.8.1.2 keywords Section 2.3.6
COLOR [RFC7986], Section 5.9 color Section 2.3.8
CONCEPT [RFC9253], Section 8.1 categories Section 2.3.11
CREATED [RFC5545], Section 3.8.7.1 created Section 2.3.13
DESCRIPTION [RFC5545], Section 3.8.1.5 description Section 2.3.14
LAST-MODIFIED [RFC5545], Section 3.8.7.3 updated Section 2.3.24
LINK [RFC9253], Section 8.2 links Section 2.3.25
METHOD [RFC5545], Section 3.7.2 entries/*/method Section 2.3.28
NAME [RFC7986], Section 5.1 title Section 2.3.29
PRODID [RFC5545], Section 3.7.3 prodId, entries/*/prodId Section 2.3.34
SOURCE [RFC7986], Section 5.8 source Section 2.3.42
UID [RFC5545], Section 3.8.4.7 uid Section 2.3.55
URL [RFC5545], Section 3.8.4.6 links Section 2.3.56

Its components convert as follows:

Table 2: Components of the VCALENDAR component
Name Reference Group property See Note
VEVENT [RFC5545], Section 3.6.1 entries Section 2.2.3
VTIMEZONE [RFC5545], Section 3.6.5 timeZones Section 2.2.6
VTODO [RFC5545], Section 3.6.2 entries Section 2.2.7

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the Group object.

The following example illustrates how to convert the VCALENDAR component:

BEGIN:VCALENDAR
UID:41aa02b6-42d0-4f45-8cb4-8b5075be2e14
BEGIN:VEVENT
...
{
  "...": "",
  "@type": "Group",
  "entries": [
    {
      "...": "",
      "@type": "Event"
    }
  ],
  "uid": "41aa02b6-42d0-4f45-8cb4-8b5075be2e14"
}
Figure 6: Converting the VCALENDAR component

2.1.2. Recurring Components

Components in an iCalendar object generally convert to distinct JSCalendar objects. For example, two VEVENT components with different UID property values in the same iCalendar object convert to two separate Event objects in the Group object's entries. This rule does not apply to recurrence overrides, defined as follows.

A VEVENT (or VTODO) component is a recurrence override if it has the RECURRENCE-ID property set, and the iCalendar object contains a VEVENT (or VTODO) component that does not have the RECURRENCE-ID but the RRULE property set, and the UID property values of the two components are equal. The component without the RECURRENCE-ID property is in that case referred to as the "main component".

The main component converts to an entry in the Group object's entries property.

The recurrence override converts to the recurrenceOverrides property of the converted main component. Its RECURRENCE-ID property value converts to the key in the recurrenceOverrides property. The value of the recurrenceOverrides property at that key is the PatchObject that transform the converted main component into the converted recurrence override. The recurrenceId and recurrenceIdTimeZone properties MUST NOT be set in the PatchObject.

The following example illustrates how to convert a main component and its recurrence override:

BEGIN:VCALENDAR
BEGIN:VEVENT
UID:F4257E1D-5461-4EF6-840F-9DFC653EB559
RRULE:FREQ=DAILY
DTSTART;TZID=Europe/Berlin:20240101T140000
...
END:VEVENT
BEGIN:VEVENT
UID:F4257E1D-5461-4EF6-840F-9DFC653EB559
RECURRENCE-ID;TZID=Europe/Berlin:20240202T140000
DTSTART;TZID=Europe/Berlin:20240202T160000
...
END:VEVENT
END:VCALENDAR
{
  "...": "",
  "@type": "Group",
  "entries": [
    {
      "...": "",
      "@type": "Event",
      "recurrenceOverrides": {
        "2024-02-02T14:00:00": {
          "start": "2024-02-02T16:00:00"
        }
      },
      "recurrenceRules": [
        {
          "@type": "RecurrenceRule",
          "frequency": "daily"
        }
      ],
      "start": "2024-01-01T14:00:00",
      "timeZone": "Europe/Berlin",
      "uid": "F4257E1D-5461-4EF6-840F-9DFC653EB559"
    }
  ]
}
Figure 7: Converting VEVENT recurrence overrides

A VEVENT (or VTODO) component is a stand-alone recurrence instance if it has the RECURRENCE-ID property set and the iCalendar object does not contain its related main component. Each stand-alone recurrence instance converts to a distinct Event (or Task) object in the Group object's entries property. The recurrenceId property MUST be set, the recurrenceIdTimeZone property MUST be set if not "null". The converted objects sort in order of appearance of the iCalendar components.

The following example illustrates how to convert stand-alone recurrence instances:

BEGIN:VCALENDAR
BEGIN:VEVENT
UID:F4257E1D-5461-4EF6-840F-9DFC653EB559
RECURRENCE-ID;TZID=Europe/Berlin:20240202T140000
DTSTART;TZID=Europe/Berlin:20240202T160000
...
END:VEVENT
BEGIN:VEVENT
UID:F4257E1D-5461-4EF6-840F-9DFC653EB559
RECURRENCE-ID;TZID=Europe/Berlin:20240103T140000
DTSTART;TZID=Europe/Berlin:20240103T170000
...
END:VEVENT
END:VCALENDAR
{
  "...": "",
  "@type": "Group",
  "entries": [
    {
      "...": "",
      "@type": "Event",
      "recurrenceId": "2024-02-02T14:00:00",
      "recurrenceIdTimeZone": "Europe/Berlin",
      "start": "2024-02-02T16:00:00",
      "timeZone": "Europe/Berlin",
      "uid": "F4257E1D-5461-4EF6-840F-9DFC653EB559"
    },
    {
      "...": "",
      "@type": "Event",
      "recurrenceId": "2024-01-03T14:00:00",
      "recurrenceIdTimeZone": "Europe/Berlin",
      "start": "2024-01-03T17:00:00",
      "timeZone": "Europe/Berlin",
      "uid": "F4257E1D-5461-4EF6-840F-9DFC653EB559"
    }
  ]
}
Figure 8: Converting VEVENT recurrence instances

2.1.3. JSCalendar Ids

JSCalendar generally uses JSON objects to represent a collection of same-typed values. The keys are of type Id [RFC8984] (Section 1.4.1), the values are JSCalendar object types. If an iCalendar element converts to a value in such a collection, then an implementation needs to choose an identifier as key.

This document defines the new JSCALID (Section 4.1.1) parameter and JSCALID property (Section 4.2.1), which allow to set a JSCalendar Id value when converting from JSCalendar to iCalendar. If they are set on a property or the component, then its value MUST be used as key when converting that element from iCalendar to JSCalendar. If no such parameter or property is set, then an implementation is free to choose any identifier, as long the following requirements are met:

  • The identifier MUST be a valid Id value.
  • The identifiers for the exact same iCalendar element MUST stay the same, irrespective of the order in which components, properties and parameters are processed.

2.1.4. Timezone identifiers

Converting temporal properties such as DTSTART, DTEND, and RECURRENCE-ID requires to not only determine the date and time of the property value, but also the timezone it references.

If the property value data type is DATE [RFC5545] (Section 3.3.4) or DATE-TIME in FORM #1: DATE WITH LOCAL TIME [RFC5545] (Section 3.3.5) then the timezone identifier is the JSON null value in JSCalendar.

If the property value data type is DATE-TIME in FORM #2: DATE WITH UTC TIME [RFC5545] (Section 3.3.5) then the timezone identifier is the string "Etc/UTC" in JSCalendar.

If the property value data type is DATE-TIME in FORM #3: DATE WITH LOCAL TIME AND TIME ZONE REFERENCE [RFC5545] (Section 3.3.5) then the timezone identifier is determined by the TZID parameter value:

If the TZID parameter value is equal to a name in the IANA Time Zone Database [TZDB] then the timezone identifier is that verbatim name.

If the TZID parameter value is unequal to an IANA timezone name then implementations MAY determine the name of an IANA timezone which has the same timezone rules over the timespan of the calendar object. Otherwise, the non-IANA timezone identifier is represented in JSCalendar as a string starting with the / (SLASH) character, followed by the TZID parameter value. The corresponding VTIMEZONE MUST be converted to the timeZones property with the prefixed identifier as key. See Figure 14 for an example.

2.1.5. DATE and DATE-TIME

iCalendar provides the DATE and DATE-TIME value types to distinguish date-only from date-time values. JSCalendar only supports date-time values. A property value of type DATE-TIME converts to either a LocalDateTime or UTCDateTime, depending on the JSCalendar property definition. A DATE value type converts to a LocalDateTime with zero time.

2.2. Components

2.2.1. PARTICIPANT

The PARTICIPANT component [RFC9073] (Section 7.1) converts to a Participant object [RFC8984] (Section 4.4.6).

Its properties convert as follows:

Table 3: Properties of the PARTICIPANT component
Name Reference Participant property See Note
ATTACH [RFC5545], Section 3.8.1.1 links Section 2.3.3
CALENDAR-ADDRESS [RFC9073], Section 6.4 calendarAddress Section 2.3.5
COMMENT [RFC5545], Section 3.8.1.4 participationComment Section 2.3.9 Only one comment supported
DESCRIPTION [RFC5545], Section 3.8.1.5 description Section 2.3.14
DTSTAMP [RFC5545], Section 3.8.7.2 scheduleUpdated Section 2.3.16
GEO [RFC5545], Section 3.8.1.6 locations Section 2.3.22
LINK [RFC9253], Section 8.2 links Section 2.3.25
LOCATION [RFC5545], Section 3.8.1.7 locations Section 2.3.26
PARTICIPANT-TYPE [RFC9073], Section 6.2 roles Section 2.3.31
SEQUENCE [RFC5545], Section 3.8.7.4 scheduleSequence Section 2.3.40
STRUCTURED-DATA [RFC9073], Section 6.6 links Section 2.3.43
SUMMARY [RFC5545], Section 3.8.1.12 name Section 2.3.45
URL [RFC5545], Section 3.8.4.6 links Section 2.3.56

Its components convert as follows:

Table 4: Components of the PARTICIPANT component
Name Reference Participant property See Note
VLOCATION [RFC9073], Section 7.2 locations (Section 5.1.4) Section 2.2.4

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the Participant object. This includes mandatory properties such as UID [RFC5545] (Section 3.8.4.7).

The following example illustrates how to convert the PARTICIPANT component:

BEGIN:VEVENT
BEGIN:PARTICIPANT
UID:47AD2E1C-49D4-45DF-BD83-8398ACC7D8E2
STRUCTURED-DATA;VALUE=URI:
 http://dir.example.com/vcard/contacts/contact1.vcf
PARTICIPANT-TYPE:CONTACT
DESCRIPTION:A contact
END:PARTICIPANT
...
{
  "...": "",
  "@type": "Event",
  "participants": {
    "p32": {
      "@type": "Participant",
      "description": "A contact",
      "iCalComponent": {
        "name": "participant",
        "properties": [
          [
            "uid",
            {},
            "text",
            "47AD2E1C-49D4-45DF-BD83-8398ACC7D8E2"
          ]
        ]
      },
      "links": {
        "l4": {
          "@type": "Link",
          "href": "http://dir.example.com/vcard/contacts/contact1.vcf"
        }
      },
      "roles": {
        "contact": true
      }
    }
  }
}
Figure 9: Converting the PARTICIPANT component

2.2.2. VALARM

The VALARM component [RFC5545] (Section 3.6.6) converts to a Alert object [RFC8984] (Section 4.5.2).

Its properties convert as follows:

Table 5: Properties of the VALARM component
Name Reference Alert property See Note
ACKNOWLEDGED [RFC9074], Section 6.1 acknowledged Section 2.3.1
ACTION [RFC5545], Section 3.8.6.1 action Section 2.3.2 Only if ACTION is EMAIL or DISPLAY.
RELATED-TO [RFC5545], Section 3.8.4.5 relatedTo Section 2.3.37
TRIGGER [RFC5545], Section 3.8.6.3 trigger Section 2.3.47

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the Alert object. This includes mandatory properties such as ATTENDEE [RFC5545] (Section 3.8.4.1), DESCRIPTION [RFC5545] (Section 3.8.1.5), or SUMMARY [RFC5545] (Section 3.8.1.12).

The following example illustrates how to convert the VALARM component:

BEGIN:VEVENT
BEGIN:VALARM
TRIGGER:-PT30M
ACTION:DISPLAY
DESCRIPTION:Breakfast meeting
END:VALARM
...
{
  "...": "",
  "@type": "Event",
  "alerts": {
    "a8": {
      "@type": "Alert",
      "iCalComponent": {
        "@type": "ICalComponent",
        "name": "valarm",
        "properties": [
          [
            "description",
            {},
            "text",
            "Breakfast meeting"
          ]
        ]
      },
      "trigger": {
        "@type": "OffsetTrigger",
        "offset": "-PT30M"
      },
      "action": "display"
    }
  }
}
Figure 10: Converting the VALARM component

2.2.3. VEVENT

The VEVENT component [RFC5545] (Section 3.6.1) converts to a Event object [RFC8984] (Section 2.1).

VEVENT components with different UID property values in the same iCalendar object convert to different entries in the Group. They sort in the same order as in the VCALENDAR component.

Its properties convert as follows:

Table 6: Properties of the VEVENT component
Name Reference Event property See Note
ATTACH [RFC5545], Section 3.8.1.1 links Section 2.3.3
ATTENDEE [RFC5545], Section 3.8.4.1 participants Section 2.3.4
CATEGORIES [RFC5545], Section 3.8.1.2 keywords Section 2.3.6
CLASS [RFC5545], Section 3.8.1.3 privacy Section 2.3.7
COLOR [RFC7986], Section 5.9 color Section 2.3.8
COMMENT [RFC5545], Section 3.8.1.4 participants/*/participationComment Section 2.3.9
CONCEPT [RFC9253], Section 8.1 categories Section 2.3.11
CONFERENCE [RFC7986], Section 5.11 virtualLocations Section 2.3.12
CREATED [RFC5545], Section 3.8.7.1 created Section 2.3.13
DESCRIPTION [RFC5545], Section 3.8.1.5 description Section 2.3.14
DTEND [RFC5545], Section 3.8.2.2 duration Section 2.3.15
DTSTAMP [RFC5545], Section 3.8.7.2 updated, scheduleUpdated Section 2.3.16
DTSTART [RFC5545], Section 3.8.2.4 start Section 2.3.17
DURATION [RFC5545], Section 3.8.2.5 duration Section 2.3.19
EXDATE [RFC5545], Section 3.8.5.1 recurrenceOverrides Section 2.3.20
EXRULE [RFC2445], Section 4.8.5.2 excludedRecurrenceRules Section 2.3.21
GEO [RFC5545], Section 3.8.1.6 locations Section 2.3.22
IMAGE [RFC7986], Section 5.10 links Section 2.3.23
LAST-MODIFIED [RFC5545], Section 3.8.7.3 updated Section 2.3.24
LINK [RFC9253], Section 8.2 links Section 2.3.25
LOCATION [RFC5545], Section 3.8.1.7 locations Section 2.3.26
ORGANIZER [RFC5545], Section 3.8.4.3 replyTo Section 2.3.30
PRIORITY [RFC5545], Section 3.8.1.9 priority Section 2.3.33
RDATE [RFC5545], Section 3.8.5.2 recurrenceOverrides Section 2.3.35
RECURRENCE-ID [RFC5545], Section 3.8.4.4 recurrenceId Section 2.3.36
RELATED-TO [RFC5545], Section 3.8.4.5 relatedTo Section 2.3.37
REQUEST-STATUS [RFC5545], Section 3.8.8.3 requestStatus Section 2.3.38
RRULE [RFC5545], Section 3.8.5.3 recurrenceRules Section 2.3.39
SEQUENCE [RFC5545], Section 3.8.7.4 sequence Section 2.3.40
STATUS [RFC5545], Section 3.8.1.11 status Section 2.3.41
STRUCTURED-DATA [RFC9073], Section 6.6 links Section 2.3.43
STYLED-DESCRIPTION [RFC9073], Section 6.5 description Section 2.3.44
SUMMARY [RFC5545], Section 3.8.1.12 title Section 2.3.45
TRANSP [RFC5545], Section 3.8.2.7 freeBusyStatus Section 2.3.46
UID [RFC5545], Section 3.8.4.7 uid Section 2.3.55
URL [RFC5545], Section 3.8.4.6 links Section 2.3.56

Its components convert as follows:

Table 7: Components of the VEVENT component
Name Reference Event property See Note
VALARM [RFC5545], Section 3.6.6 alerts Section 2.2.2

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the Event object.

The following example illustrates how to convert the VEVENT component:

BEGIN:VCALENDAR
BEGIN:VEVENT
UID:DE935D01-3DF7-4201-B61A-D77D05C8B21A
DTSTART:20060102T030405Z
...
END:VEVENT
BEGIN:VEVENT
UID:60BE3D6E-6383-473A-BCF1-3C43EA1FA571
...
END:VEVENT
END:VCALENDAR
{
  "...": "",
  "@type": "Group",
  "entries": [
    {
      "@type": "Event",
      "showWithoutTime": false,
      "start": "2006-01-02T03:04:05",
      "timeZone": "Etc/UTC",
      "uid": "DE935D01-3DF7-4201-B61A-D77D05C8B21A",
      "...": ""
    },
    {
      "@type": "Event",
      "uid": "60BE3D6E-6383-473A-BCF1-3C43EA1FA571",
      "...": ""
    }
  ]
}
Figure 11: Converting the VEVENT component

2.2.4. VLOCATION

The VLOCATION component [RFC9073] (Section 7.2) converts to a Location object [RFC8984] (Section 4.2.5).

Its properties convert as follows:

Table 8: Properties of the VLOCATION component
Name Reference Location property See Note
ATTACH [RFC5545], Section 3.8.1.1 links Section 2.3.3
DESCRIPTION [RFC5545], Section 3.8.1.5 description Section 2.3.14
GEO [RFC5545], Section 3.8.1.6 coordinates Section 2.3.22
IMAGE [RFC7986], Section 5.10 links Section 2.3.23
LINK [RFC9253], Section 8.2 links Section 2.3.25
LOCATION-TYPE [RFC9073], Section 6.1 locationTypes Section 2.3.27
NAME [RFC7986], Section 5.1 name Section 2.3.29
STRUCTURED-DATA [RFC9073], Section 6.6 links Section 2.3.43

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the Location object. This includes mandatory properties such as UID [RFC5545] (Section 3.8.4.7).

The following example illustrates how to convert the VLOCATION component:

BEGIN:VLOCATION
UID:4954DC22-5BD6-4E98-844D-0302982F54AC
NAME:The venue
STRUCTURED-DATA;VALUE=URI:
 http://dir.example.com/venues/big-hall.vcf
END:VLOCATION
"locations": {
  "e4": {
    "@type": "Location",
    "name": "The venue",
    "links": {
      "21": {
        "@type": "Link",
        "href": "http://dir.example.com/venues/big-hall.vcf",
        "iCalProperty": {
          "@type": "ICalProperty",
          "name": "structured-data"
        }
      }
    },
    "iCalComponent": {
      "@type": "ICalComponent",
      "properties": [
        [
          "uid",
          {},
          "text",
          "4954DC22-5BD6-4E98-844D-0302982F54AC"
        ]
      ]
    }
  }
}
Figure 12: Converting the VLOCATION component

2.2.5. VRESOURCE

The VRESOURCE component [RFC9073] (Section 7.3) converts to a Participant object [RFC8984] (Section 4.4.6). The kind property value of the Participant object MUST be "resource".

Its properties convert as follows:

Table 9: Properties of the VRESOURCE component
Name Reference Participant property See Note
ATTACH [RFC5545], Section 3.8.1.1 links Section 2.3.3
DESCRIPTION [RFC5545], Section 3.8.1.5 description Section 2.3.14
GEO [RFC5545], Section 3.8.1.6 locations Section 2.3.22
IMAGE [RFC7986], Section 5.10 links Section 2.3.23
LINK [RFC9253], Section 8.2 links Section 2.3.25
NAME [RFC7986], Section 5.1 name Section 2.3.29
STRUCTURED-DATA [RFC9073], Section 6.6 links Section 2.3.43

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the Participant object. This includes mandatory properties such as UID [RFC5545] (Section 3.8.4.7).

The following example illustrates how to convert the VRESOURCE component:

BEGIN:VEVENT
BEGIN:VRESOURCE
UID:456789-abcdef-98765432
NAME:The projector
RESOURCE-TYPE:projector
STRUCTURED-DATA;VALUE=URI:http://dir.example.com/projectors/3d.vcf
END:VRESOURCE
...
{
  "...": "",
  "@type": "Event",
  "participants": {
    "p2": {
      "@type": "Participant",
      "description": "A contact",
      "iCalComponent": {
        "name": "vresource",
        "properties": [
          [
            "uid",
            {},
            "text",
            "456789-abcdef-98765432"
          ],
          [
            "resource-type",
            {},
            "text",
            "projector"
          ]
        ]
      },
      "kind": "resource",
      "links": {
        "l4": {
          "@type": "Link",
          "href": "http://dir.example.com/projectors/3d.vcf"
        }
      },
      "name": "The projector"
    }
  }
}
Figure 13: Converting the VRESOURCE component

2.2.6. VTIMEZONE

The VTIMEZONE component [RFC5545] (Section 3.6.5) converts to a TimeZone object [RFC8984] (Section 4.7.2).

Its properties convert as follows:

Table 10: Properties of the VTIMEZONE component
Name Reference TimeZone property See Note
LAST-MODIFIED [RFC5545], Section 3.8.7.3 updated Section 2.3.24
TZID [RFC5545], Section 3.8.3.1 tzId Section 2.3.48
TZID-ALIAS-OF [RFC7808], Section 7.2 aliases Section 2.3.49
TZUNTIL [RFC7808], Section 7.1 validUntil Section 2.3.53
TZURL [RFC5545], Section 3.8.3.5 url Section 2.3.54

Its components convert as follows:

Table 11: Components of the VTIMEZONE component
Name Reference TimeZone property See Note
DAYLIGHT [RFC5545], Section 3.6.5 daylight In this section
STANDARD [RFC5545], Section 3.6.5 standard In this section

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the TimeZone object.

The DAYLIGHT component [RFC5545] (Section 3.6.5) and STANDARD component [RFC5545] (Section 3.6.5) convert to a TimeZoneRule object [RFC8984] (Section 4.7.2).

Their properties convert as follows:

Table 12: Properties of the DAYLIGHT or STANDARD component
Name Reference TimeZoneRule property See Note
COMMENT [RFC5545], Section 3.8.1.4 comments Section 2.3.9
DTSTART [RFC5545], Section 3.8.2.4 start Section 2.3.17
RDATE [RFC5545], Section 3.8.5.2 recurrenceOverrides Section 2.3.35
RRULE [RFC5545], Section 3.8.5.3 recurrenceRules Section 2.3.39
TZNAME [RFC5545], Section 3.8.3.2 names Section 2.3.50
TZOFFSETFROM [RFC5545], Section 3.8.3.3 offsetFrom Section 2.3.51
TZOFFSETTO [RFC5545], Section 3.8.3.4 offsetTo Section 2.3.52

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the TimeZoneRule object.

The following example illustrates how to convert the VTIMEZONE component:

BEGIN:VCALENDAR
BEGIN:VTIMEZONE
TZID:CustomTz
TZID-ALIAS-OF:Puerto_Rico
TZID-ALIAS-OF:America/Anguilla
LAST-MODIFIED:20240909T122233Z
TZUNTIL:20080709T000000Z
TZURL:https://example.com/tz/CustomTz.ics
BEGIN:DAYLIGHT
TZNAME:AWT
TZOFFSETFROM:-0400
TZOFFSETTO:-0300
DTSTART:19420503T000000
END:DAYLIGHT
BEGIN:DAYLIGHT
TZNAME:APT
TZOFFSETFROM:-0300
TZOFFSETTO:-0300
DTSTART:19450814T200000
END:DAYLIGHT
BEGIN:STANDARD
TZNAME:AST
TZOFFSETFROM:-0300
TZOFFSETTO:-0400
DTSTART:19450930T020000
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=CustomTz:20080708T130000
...
{
  "...": "",
  "@type": "Group",
  "entries": [
    {
      "...": "",
      "@type": "Event",
      "start": "2008-07-08T13:00:00",
      "timeZone": "/CustomTz"
    }
  ],
  "timeZones": {
    "/CustomTz": {
      "@type": "TimeZone",
      "aliases": {
        "Puerto_Rico": true,
        "America/Anguilla": true
      },
      "validUntil": "2008-07-09T00:00:00Z",
      "daylight": [
        {
          "@type": "TimeZoneRule",
          "offsetFrom": "-0400",
          "offsetTo": "-0300",
          "start": "1942-05-03T00:00:00",
          "names": {
            "AWT": true
          }
        },
        {
          "@type": "TimeZoneRule",
          "offsetFrom": "-0300",
          "offsetTo": "-0300",
          "start": "1945-08-14T20:00:00",
          "names": {
            "APT": true
          }
        }
      ],
      "standard": [
        {
          "@type": "TimeZoneRule",
          "offsetFrom": "-0300",
          "offsetTo": "-0400",
          "start": "1945-09-30T02:00:00",
          "names": {
            "AST": true
          }
        }
      ],
      "tzId": "CustomTz",
      "updated": "2024-09-09T12:22:33Z",
      "url": "https://example.com/tz/CustomTz.ics"
    }
  }
}
Figure 14: Converting the VTIMEZONE component

2.2.7. VTODO

The VTODO component [RFC5545] (Section 3.6.2) converts to a Task object [RFC8984] (Section 2.2).

VTODO components with different UID property values in the same iCalendar object convert to different entries in the Group. They sort in the same order as in the VCALENDAR component.

Its properties convert as follows:

Table 13: Properties of the VTODO component
Name Reference Task property See Note
ATTACH [RFC5545], Section 3.8.1.1 links Section 2.3.3
ATTENDEE [RFC5545], Section 3.8.4.1 participants Section 2.3.4
CATEGORIES [RFC5545], Section 3.8.1.2 keywords Section 2.3.6
CLASS [RFC5545], Section 3.8.1.3 privacy Section 2.3.7
COLOR [RFC7986], Section 5.9 color Section 2.3.8
COMMENT [RFC5545], Section 3.8.1.4 participants/*/participationComment Section 2.3.9
COMPLETED [RFC5545], Section 3.8.2.1 completed Section 2.3.10
CONCEPT [RFC9253], Section 8.1 categories Section 2.3.11
CONFERENCE [RFC7986], Section 5.11 virtualLocations Section 2.3.12
CREATED [RFC5545], Section 3.8.7.1 created Section 2.3.13
DESCRIPTION [RFC5545], Section 3.8.1.5 description Section 2.3.14
DTSTAMP [RFC5545], Section 3.8.7.2 updated, scheduleUpdated Section 2.3.16
DTSTART [RFC5545], Section 3.8.2.4 start Section 2.3.17
DUE [RFC5545], Section 3.8.2.3 due Section 2.3.18
DURATION [RFC5545], Section 3.8.2.5 duration Section 2.3.19
EXDATE [RFC5545], Section 3.8.5.1 recurrenceOverrides Section 2.3.20
EXRULE [RFC2445], Section 4.8.5.2 excludedRecurrenceRules Section 2.3.21
GEO [RFC5545], Section 3.8.1.6 locations Section 2.3.22
IMAGE [RFC7986], Section 5.10 links Section 2.3.23
LAST-MODIFIED [RFC5545], Section 3.8.7.3 updated Section 2.3.24
LINK [RFC9253], Section 8.2 links Section 2.3.25
LOCATION [RFC5545], Section 3.8.1.7 locations Section 2.3.26
ORGANIZER [RFC5545], Section 3.8.4.3 replyTo Section 2.3.30
PERCENT-COMPLETE [RFC5545], Section 3.8.1.8 percentComplete Section 2.3.32
PRIORITY [RFC5545], Section 3.8.1.9 priority Section 2.3.33
RDATE [RFC5545], Section 3.8.5.2 recurrenceOverrides Section 2.3.35
RECURRENCE-ID [RFC5545], Section 3.8.4.4 recurrenceId Section 2.3.36
RELATED-TO [RFC5545], Section 3.8.4.5 relatedTo Section 2.3.37
REQUEST-STATUS [RFC5545], Section 3.8.8.3 requestStatus Section 2.3.38
RRULE [RFC5545], Section 3.8.5.3 recurrenceRules Section 2.3.39
SEQUENCE [RFC5545], Section 3.8.7.4 sequence Section 2.3.40
STRUCTURED-DATA [RFC9073], Section 6.6 links Section 2.3.43
STYLED-DESCRIPTION [RFC9073], Section 6.5 description Section 2.3.44
SUMMARY [RFC5545], Section 3.8.1.12 title Section 2.3.45
TRANSP [RFC5545], Section 3.8.2.7 freeBusyStatus Section 2.3.46
UID [RFC5545], Section 3.8.4.7 uid Section 2.3.55
URL [RFC5545], Section 3.8.4.6 links Section 2.3.56

Its components convert as follows:

Table 14: Components of the VTODO component
Name Reference Task property See Note
VALARM [RFC5545], Section 3.6.6 alerts Section 2.2.2

Other properties or components MAY be converted to the iCalComponent property (Section 5.1.2) of the Task object.

The following example illustrates how to convert the VTODO component:

BEGIN:VCALENDAR
BEGIN:VTODO
UID:83C80482-806D-41C4-8029-E438F793005D
DUE:20060102T030405Z
...
{
  "...": "",
  "@type": "Group",
  "entries": [
    {
      "...": "",
      "@type": "Task",
      "due": "2006-01-02T03:04:05",
      "timeZone": "Etc/UTC",
      "uid": "83C80482-806D-41C4-8029-E438F793005D"
    }
  ]
}
Figure 15: Converting the VTODO component

2.3. Properties

2.3.1. ACKNOWLEDGED

The ACKNOWLEDGED property [RFC9074] (Section 6.1) in a VALARM component converts to the acknowledged property [RFC8984] (Section 4.5.2) of the Alert object.

The following example illustrates how to convert the ACKNOWLEDGED property:

BEGIN:VEVENT
BEGIN:VALARM
TRIGGER:-PT5M
ACTION:DISPLAY
ACKNOWLEDGED:20241002T114703Z
...
"alerts": {
  "a": {
    "@type": "Alert",
    "acknowledged": "2024-10-02T11:47:03Z",
    "...": ""
  }
}
Figure 16: Converting the ACKNOWLEDGED property

2.3.2. ACTION

The ACTION property [RFC5545] (Section 3.8.6.1) in a VALARM component converts to the action property [RFC8984] (Section 4.5.2) of the Alert object.

Its values convert as follows:

Table 15: Values of the ACTION property
iCalendar value JSCalendar value
DISPLAY display
EMAIL email

An ACTION property with value AUDIO or any other not listed in Table 15 does not convert to the action property. Instead, the property converts to the iCalComponent/properties property (Section 5.1.2) of the Alert.

The following examples illustrate how to convert the ACTION property:

BEGIN:VEVENT
BEGIN:VALARM
TRIGGER:-PT5M
ACTION:DISPLAY
...
"alerts": {
  "a": {
    "@type": "Alert",
    "action": "display",
    "...": ""
  }
}
Figure 17: Converting the ACTION property for value DISPLAY
BEGIN:VEVENT
BEGIN:VALARM
TRIGGER:-PT5M
ACTION:AUDIO
...
"alerts": {
  "a": {
    "@type": "Alert",
    "iCalComponent": {
      "name": "valarm",
      "properties": [
        [
          "action",
          {},
          "text",
          "AUDIO"
        ]
      ]
    },
    "...": ""
  }
}
Figure 18: Converting the ACTION property for value AUDIO

2.3.3. ATTACH

The ATTACH property [RFC5545] (Section 3.8.1.1) in a VEVENT, VTODO, VRESOURCE, PARTICIPANT, or VLOCATION component converts to a Link object [RFC8984] (Section 1.4.11). The converted object is set in the links property of the Event, Task, Participant, or Location object.

The property value converts to the href property of the Link object. A value of type URI converts as-is. A value of type BINARY converts to a URI in the "data" URL scheme ([RFC2397]. If the FMTTYPE parameter is set on the ATTACH property, then the parameter value SHOULD be set in the mediatype part of the data URL.

The ATTACH property parameters convert as follows:

Table 16: Parameters of the ATTACH property
Name Reference Link Property Note
FMTTYPE [RFC5545], Section 3.2.8 contentType
SIZE [RFC8607], Section 4.1 size

The following examples illustrate how to convert the ATTACH property:

ATTACH:https://example.com/foo.pdf
"links": {
  "a": {
    "@type": "Link",
    "href": "https://example.com/foo.pdf"
  }
}
Figure 19: Converting the ATTACH property with URI value
ATTACH;ENCODING=BASE64;VALUE=BINARY;FMTTYPE=image/png:iVBORw
 0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAAAmJLR0QAAd2KE6QAA
 AAKSURBVAjXY2gAAACCAIHdQ2r0AAAAAElFTkSuQmCC
"links": {
  "a": {
    "@type": "Link",
    "href": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAAAmJLR0QAAd2KE6QAAAAKSURBVAjXY2gAAACCAIHdQ2r0AAAAAElFTkSuQmCC",
    "contentType": "image/png"
  }
}
Figure 20: Converting the ATTACH property with BINARY value

2.3.4. ATTENDEE

The ATTENDEE property [RFC5545] (Section 3.8.4.1) in a VEVENT or VTODO component converts to a Participant object [RFC8984] (Section 4.4.6). The converted object is set in the participants property of the Event or Task object.

The property value converts to both the calendarAddress and sendTo properties of the Participant object. If the CAL-ADDRESS value is in the "mailto" scheme, then it converts to the "imip" method in the sendTo property, otherwise it converts to the "other" method.

An ATTENDEE property and a PARTICIPANT component in the same iCalendar component convert to the same Participant object, if their converted calendarAddress property values are equal after URI normalization [RFC3986] (Section 6). How to deal with conflicting values when converting other Participant properties is implementation-specific.

The ATTENDEE property parameters convert as follows:

Table 17: Parameters of the ATTENDEE property
Name Reference Participant Property Note
CN [RFC5545], Section 3.2.2 name
CUTYPE [RFC5545], Section 3.2.3 kind
DELEGATED-FROM [RFC5545], Section 3.2.4 delegatedFrom
DELEGATED-TO [RFC5545], Section 3.2.5 delegatedTo
DIR [RFC5545], Section 3.2.6 links
EMAIL [RFC7986], Section 6.2 email
MEMBER [RFC5545], Section 3.2.11 memberOf
PARTSTAT [RFC5545], Section 3.2.12 participationStatus
ROLE [RFC5545], Section 3.2.16 roles
RSVP [RFC5545], Section 3.2.17 expectReply
SCHEDULE-AGENT [RFC6638], Section 7.1 scheduleAgent
SCHEDULE-FORCE-SEND [RFC6638], Section 7.2 scheduleForceSend
SCHEDULE-STATUS [RFC6638], Section 7.3 scheduleStatus

If no ROLE parameter is set, then the "attendee" role in the roles property MUST be set.

Every calendar address value of the DELEGATED-FROM, DELEGATED-TO, or MEMBER parameters converts to the identifier of an Participant object. This identifier is determined by finding that Participant object in the participants property, which has a calendarAddress property value matching the parameter value. If no such Participant object exists after all properties and components have been converted, then a new Participant object having that calendarAddress property value is created. If multiple Participant objects match, then choosing the Participant identifier is implementation-specific.

The PARTSTAT of an ATTENDEE property in a VTODO component converts not only to the participationStatus property of the Participant object, but also to its progress property if the PARTSTAT parameter value is specific for VTODO components:

Table 18: Converting the PARTSTAT parameter in a VTODO component to Participant properties
PARTSTAT Reference participationStatus progress
NEEDS-ACTION [RFC5545], Section 3.2.12 needs-action
ACCEPTED [RFC5545], Section 3.2.12 accepted
DECLINED [RFC5545], Section 3.2.12 declined
TENTATIVE [RFC5545], Section 3.2.12 tentative
DELEGATED [RFC5545], Section 3.2.12 delegated
COMPLETED [RFC5545], Section 3.2.12 accepted completed
IN-PROCESS [RFC5545], Section 3.2.12 accepted in-process
FAILED [I-D.ietf-calext-ical-tasks], Section 11.1 accepted failed

The following examples illustrate how to convert the ATTENDEE property:

ATTENDEE;PARTSTAT=TENTATIVE;CN=Henry Cabot:mailto:hcabot@example.com
"participants": {
  "p3": {
    "@type": "Participant",
    "calendarAddress": "mailto:hcabot@example.com",
    "name": "Henry Cabot",
    "participationStatus": "tentative",
    "roles": {
      "attendee": true
    },
    "sendTo": {
      "imip": "mailto:hcabot@example.com"
    }
  },
  "o4": {
    "...": ""
  }
}
Figure 21: Converting the ATTENDEE property
BEGIN:PARTICIPANT
CALENDAR-ADDRESS:mailto:foo@example.com
DTSTAMP:20230723T125201Z
...
END:PARTICIPANT
ATTENDEE;PARTSTAT=TENTATIVE:mailto:foo@example.com
"participants": {
  "23": {
    "@type": "Participant",
    "calendarAddress": "mailto:foo@example.com",
    "participationStatus": "tentative",
    "scheduleUpdated": "2023-07-23T12:52:01Z",
    "...": ""
  },
  "o4": {
    "...": ""
  }
}
Figure 22: Converting the ATTENDEE property and PARTICIPANT component
BEGIN:VTODO
ATTENDEE;PARTSTAT=IN-PROCESS:mailto:foo@example.com
...
"@type": "Task",
"participants": {
  "1": {
    "@type": "Participant",
    "calendarAddress": "mailto:foo@example.com",
    "participationStatus": "accepted",
    "progress": "in-process",
    "...": ""
  },
  "o": {
    "...": ""
  }
}
Figure 23: Converting the ATTENDEE property with a VTODO-specific participation status

2.3.5. CALENDAR-ADDRESS

The CALENDAR-ADDRESS property [RFC9073] (Section 6.4) in a PARTICIPANT component converts to the calendarAddress property [I-D.ietf-jmap-calendars] (Section 5.1.1) of the Participant object.

The following example illustrates how to convert the CALENDAR-ADDRESS property:

BEGIN:PARTICIPANT
CALENDAR-ADDRESS:mailto:foo@example.com
...
"participants": {
  "a2": {
    "@type": "Participant",
    "calendarAddress": "mailto:foo@example.com",
    "...": ""
  }
}
Figure 24: Converting the CALENDAR-ADDRESS property

2.3.6. CATEGORIES

The CATEGORIES property [RFC5545] (Section 3.8.1.2) in a VEVENT, VTODO, or VCALENDAR component converts to the keywords property [RFC8984] (Section 4.2.9) of the Event, Task, or Group object.

The list of category values converts to a set of keywords. The values convert case-sensitively. All CATEGORIES properties in the same iCalendar component convert to the keywords property in the JSCalendar object.

The following example illustrates how to convert the CATEGORIES property:

CATEGORIES:APPOINTMENT,EDUCATION
CATEGORIES:meeting
"keywords": {
  "APPOINTMENT": true,
  "EDUCATION": true,
  "meeting": true
}
Figure 25: Converting the CATEGORIES property

2.3.7. CLASS

The CLASS property [RFC5545] (Section 3.8.1.3) in a VEVENT or VTODO component converts to the privacy property [RFC8984] (Section 4.4.3) of the Event or Task object.

Its values convert as follows:

Table 19: Values of the CLASS property
iCalendar value JSCalendar value
PUBLIC public
PRIVATE private
CONFIDENTIAL secret

Any other value does not convert to the class property. Instead, the property converts to the iCalComponent/properties property (Section 5.1.2) of the JSCalendar object.

The following example illustrates how to convert the CLASS property:

CLASS:PRIVATE
"privacy": "private"
Figure 26: Converting the CLASS property

2.3.8. COLOR

The COLOR property [RFC7986] (Section 5.9) in a VEVENT, VTODO, or VCALENDAR component converts to the color property [RFC8984] (Section 4.2.11) of the Event, Task, or Group object.

Its value converts verbatim.

The following examples illustrate how to convert the COLOR property:

2.3.9. COMMENT

The COMMENT property [RFC5545] (Section 3.8.1.4) in a DAYLIGHT or STANDARD component converts to the comments property [RFC8984] (Section 4.7.2) of the TimeZoneRule object.

The COMMENT property [RFC5545] (Section 3.8.1.4) in a PARTICIPANT component converts to the participationComment property [RFC8984] (Section 4.4.6).

The COMMENT property [RFC5545] (Section 3.8.1.4) in an iTIP-scheduled [RFC5546] VEVENT or VTODO component converts to the participationComment property [RFC8984] (Section 4.4.6) of that Participant object, which represents the source of this scheduling message, if any. It otherwise converts to the iCalComponent/properties property (Section 5.1.2) of the Event or Task object.

Multiple COMMENT properties in a DAYLIGHT or STANDARD component convert in order of appearance in the comments property. Converting multiple COMMENT properties to the single-valued participationComment property is implementation-specific.

The following examples illustrate how to convert the COMMENT property:

BEGIN:VCALENDAR
BEGIN:VTIMEZONE
TZID:NonIana
BEGIN:DAYLIGHT
TZOFFSETFROM:-0400
TZOFFSETTO:-0300
DTSTART:20010503T000000
COMMENT:take note of this
COMMENT:and this
END:DAYLIGHT
END:VTIMEZONE
...
{
  "@type": "Group",
  "timeZones": {
    "/NonIana": {
      "@type": "TimeZone",
      "daylight": [
        {
          "@type": "TimeZoneRule",
          "comments": [
            "take note of this",
            "and this"
          ],
          "...": ""
        }
      ],
      "...": ""
    }
  },
  "...": ""
}
Figure 29: Converting the COMMENT property in a DAYLIGHT component
BEGIN:PARTICIPANT
UID:127ABD62-D07A-4F39-AA62-530E37A8DF78
COMMENT:I'll think about it
...
"participants": {
  "g2": {
    "@type": "Participant",
    "participationComment": "I'll think about it",
    "...": ""
  }
}
Figure 30: Converting the COMMENT property in a PARTICIPANT component

2.3.10. COMPLETED

The COMPLETED property [RFC5545] (Section 3.8.2.1) in a VTODO component converts to the completed property (Section 5.1.1) of the Task object.

The following example illustrates how to convert the COMPLETED property:

BEGIN:VTODO
COMPLETED:20241108T111029Z
...
{
  "@type": "Task",
  "completed": "2024-11-08T11:10:29Z",
  "...": ""
}
Figure 31: Converting the COMPLETED property

2.3.11. CONCEPT

The CONCEPT property [RFC9253] (Section 8.1) in a VEVENT, VTODO, or VCALENDAR component converts to the categories property [RFC8984] (Section 4.2.10) of the Event, Task, or Group object.

The list of URI values converts to a set of URIs. Multiple occurrences of the CONCEPT property in the same iCalendar component convert to the same categories property in the JSCalendar object.

The following example illustrates how to convert the CONCEPT property:

CONCEPT:https://example.com/event-types/arts/music
CONCEPT:https://example.com/event-types/arts/literature
"categories": {
  "https://example.com/event-types/arts/music": true,
  "https://example.com/event-types/arts/literature": true
}
Figure 32: Converting the CONCEPT property

2.3.12. CONFERENCE

The CONFERENCE property [RFC7986] (Section 5.11) in a VEVENT or VTODO component converts to a VirtualLocation object [RFC8984] (Section 4.2.6). The converted object is set in the virtualLocations property of the Event or Task object.

The property value converts to the uri property of the VirtualLocation object.

Its parameters convert as follows:

Table 20: Parameters of the CONFERENCE property
Name Reference Property Note
FEATURE [RFC7986], Section 6.3 features
LABEL [RFC7986], Section 6.4 name

The following example illustrates how to convert the CONFERENCE property:

CONFERENCE;VALUE=URI;FEATURE=AUDIO,VIDEO;
 LABEL=Attendee dial-in:https://chat.example.com/audio?id=123456
"virtualLocations": {
  "b2": {
    "@type": "VirtualLocation",
    "name": "Attendee dial-in",
    "uri": "https://chat.example.com/audio?id=123456",
    "features": {
      "audio": true,
      "video": true
    }
  }
}
Figure 33: Converting the CONFERENCE property

2.3.13. CREATED

The CREATED property [RFC5545] (Section 3.8.7.1) in a VEVENT, VTODO, or VCALENDAR component converts to the created property [RFC8984] (Section 4.1.5) of the Event, Task, or Group object.

The following example illustrates how to convert the CREATED property:

CREATED:20240329T133000Z
"created": "2024-03-29T13:30:00Z"
Figure 34: Converting the CREATED property

2.3.14. DESCRIPTION

The DESCRIPTION property [RFC5545] (Section 3.8.1.5) in a VEVENT, VTODO, VCALENDAR, VLOCATION, VRESOURCE, or PARTICIPANT component converts to the description property [RFC8984] (Section 4.2.2) of the Event, Task, Group, Location, Link, or Participant object, unless its DERIVED parameter value is TRUE.

If the DERIVED parameter value is TRUE, then the property does not convert to the description property. Instead, a non-derived STYLED-DESCRIPTION property is expected to contain the description. Implementations MAY preserve the property in the iCalComponent property (Section 5.1.2).

The following example illustrates how to convert the DESCRIPTION property:

DESCRIPTION:The pancakes there are delicious\; they are fluffy and sweet.
"description": "The pancakes there are delicious; they are fluffy and sweet."
Figure 35: Converting the DESCRIPTION property

2.3.15. DTEND

The DTEND property [RFC5545] (Section 3.8.2.2) in a VEVENT component converts to the duration property [RFC8984] (Section 5.1.2) of the Event object.

The duration is the timespan between the points in time of the DTSTART and DTEND property values when converted to UTC time.

If the timezone identifier (Section 2.1.4) of the DTEND property differs from that of the DTSTART property, then the DTEND property also converts to a Location object. The timezone identifier converts to the timeZone property of the Location object. The relativeTo property of the Location is set to "end". The Location object is set in the locations property of the Event object.

Implementations MAY preserve the fact that the duration got determined by the DTEND property. How to this depends on if the timezone identifiers of DTSTART and DTEND are equal. If the identifiers are equal, then implementations MUST set the iCalComponent property (Section 5.1.2) in the Event object and there add an entry for the path "duration" in the convertedProperties property. The value MUST be an ICalProperty object with the name property set to "dtend". If instead the timezone identifiers are not equal, then implementations MUST set the iCalProperty property (Section 5.1.3) of the Location object.

The following examples illustrate how to convert the DTEND property:

DTSTART;TZID=Australia/Melbourne:20241002T130000
DTEND;TZID=Australia/Melbourne:20241002T140000
"start": "2024-10-02T13:00:00",
"timeZone": "Australia/Melbourne",
"duration": "PT1H",
"iCalComponent": {
  "convertedProperties": {
    "duration": {
      "@type": "ICalProperty",
      "name": "dtend"
    }
  }
}
Figure 36: Converting the DTEND property with same timezone
DTSTART;TZID=Europe/Berlin:20241017T130005
DTEND;TZID=Asia/Bangkok:20241018T020325
"start": "2024-10-17T13:00:05",
"timeZone": "Europe/Berlin",
"duration": "PT9H20M",
"locations": {
  "l5": {
    "timeZone": "Asia/Bangkok",
    "relativeTo": "end",
    "iCalProperty": {
      "@type": "ICalProperty",
      "name": "dtend"
    }
  }
}
Figure 37: Converting the DTEND property with different timezone
DTSTART;VALUE=DATE:20240102
DTEND;VALUE=DATE:20240112
"start": "2024-01-02T00:00:00",
"timeZone": null,
"duration": "P1W2D",
"showWithoutTime": true
Figure 38: Converting the DTEND property with DATE value type

2.3.16. DTSTAMP

The DTSTAMP property [RFC5545] (Section 3.8.7.2) in a VEVENT or VTODO component converts to the updated property [RFC8984] (Section 4.1.6) of the Event or Task object.

Both the LAST-MODIFIED and DTSTAMP properties convert to the updated property. If both are present in the same component, then the DTSTAMP property value has higher precedence. Implementations MAY in that case preserve the value of the LAST-MODIFIED property in the iCalComponent property.

An Event or Task object which has the method property set might represent an iTIP reply of one of the participants in the object. In this case the value of the updated property in the Event or Task also converts to the scheduleUpdated property [RFC8984] (Section 4.4.6) of that Participant object, which represents the participant from which the iTIP reply originated.

The DTSTAMP property in a PARTICIPANT component converts to the scheduleUpdated property [RFC8984] (Section 4.4.6) of the Participant object.

The following examples illustrate how to convert the DTSTAMP property:

BEGIN:VCALENDAR
METHOD:REPLY
BEGIN:VEVENT
DTSTAMP:20240304T132000Z
...
{
  "@type": "Group",
  "entries": [
    {
      "@type": "Event",
      "method": "reply",
      "updated": "2024-03-04T13:20:00Z",
      "...": ""
    }
  ],
  "...": ""
}
Figure 39: Converting the DTSTAMP property in a VEVENT component
BEGIN:VEVENT
BEGIN:PARTICIPANT
DTSTAMP:20240304T132000Z
...
"participants": {
  "f4": {
    "@type": "Participant",
    "scheduleUpdated": "2024-03-04T13:20:00Z",
    "...": ""
  }
}
Figure 40: Converting the DTSTAMP property in a PARTICIPANT component

2.3.17. DTSTART

The DTSTART property [RFC5545] (Section 3.8.2.4) in a VEVENT, VTODO, DAYLIGHT or STANDARD component converts to the start property [RFC8984] (Section 4.7.2) of the Event, Task, or TimeZoneRule object.

See Section 2.1.5 how to convert DATE and DATE-TIME values.

For VEVENT and VTODO components, the timezone identifier (Section 2.1.4) of the DTSTART property converts to the timeZone property of the Event or Task object. In addition, if the value type of the DTSTART property is DATE, then the value of the showWithoutTime property [RFC8984] (Section 4.2.4) is "true".

The following examples illustrate how to convert the DTSTART property for the VEVENT and VTODO components. See Section 2.2.6 for examples how to convert the DTSTART property for the DAYLIGHT and STANDARD components.

DTSTART;TZID=Europe/Berlin:20240921T105302
"start": "2024-09-21T10:53:02",
"timeZone": "Europe/Berlin",
"showWithoutTime": "false"
Figure 41: Converting the DTSTART property with TZID parameter
DTSTART:20240921T105302Z
"start": "2024-09-21T10:53:02",
"timeZone": "Etc/UTC",
"showWithoutTime": "false"
Figure 42: Converting the DTSTART property with UTC time
DTSTART:20240921T105302
"start": "2024-09-21T10:53:02",
"timeZone": null,
"showWithoutTime": "false"
Figure 43: Converting the DTSTART property with floating time
DTSTART;VALUE=DATE:20240921
"start": "2024-09-21T00:00:00",
"timeZone": null,
"showWithoutTime": "true"
Figure 44: Converting the DTSTART property with value type DATE

2.3.18. DUE

The DUE property [RFC5545] (Section 3.8.2.3) in a VTODO component converts to the due property [RFC8984] (Section 5.2.1) of the Task object.

See Section 2.1.5 how to convert DATE and DATE-TIME values.

If the VTODO component does not contain a DTSTART property, then the timezone identifier (Section 2.1.4) of the DUE property converts to the timeZone property of the Task object. If instead the VTODO component contains both the DUE and DTSTART properties, then the timezone identifier of the DUE property does not convert to a standard JSCalendar element. The value of the due property MUST denote the date and time relative to the timezone of the DTSTART property.

If the value type of the DUE property is DATE, then the value of the showWithoutTime property [RFC8984] (Section 4.2.4) is "true".

The following examples illustrate how to convert the DUE property:

DUE;TZID=Europe/Berlin:20240921T105302
"due": "2024-09-21T10:53:02",
"timeZone": "Europe/Berlin",
"showWithoutTime": "false"
Figure 45: Converting the DUE property with TZID parameter
DUE:20240921T105302Z
"start": "2024-09-21T10:53:02",
"timeZone": "Etc/UTC",
"showWithoutTime": "false"
Figure 46: Converting the DUE property with UTC time
DUE:20240921T105302
"start": "2024-09-21T10:53:02",
"timeZone": null,
"showWithoutTime": "false"
Figure 47: Converting the DUE property with floating time
DUE;VALUE=DATE:20240921
"start": "2024-09-21T00:00:00",
"timeZone": null,
"showWithoutTime": "true"
Figure 48: Converting the DUE property with value type DATE

2.3.19. DURATION

The DURATION property [RFC5545] (Section 3.8.2.5) in a VEVENT or VTODO component converts to the duration property [RFC8984] (Section 5.1.2) of the Event or Task object.

The following example illustrates how to convert the DURATION property:

DURATION:PT1H
"duration": "PT1H"
Figure 49: Converting the DURATION

2.3.20. EXDATE

The EXDATE property [RFC5545] (Section 3.8.5.1) of value type DATE or DATE-TIME in a VEVENT or VTODO component converts to a PatchObject object [RFC8984] (Section 1.4.9). The converted object is set in the recurrenceOverrides property of the Event or Task object.

The property value converts to the key in the recurrenceOverrides property value. See Section 2.1.5 how to convert DATE and DATE-TIME values. The date-time MUST be relative to the timezone identified by the timeZone property of the Event or Task. The PatchObject value MUST set the excluded property to "true" and MUST NOT set any other property.

An EXDATE property of value type PERIOD does not convert to a standard JSCalendar element. Implementations MAY convert it to the iCalComponent property (Section 5.1.2) of the Event or Task object.

The following example illustrates how to convert the EXDATE property:

DTSTART:20230101T130000Z
RRULE:FREQ=MONTHLY
EXDATE:20230801T130000Z
"start": "2023-01-01T13:00:00",
"timeZone": "Etc/UTC",
"recurrenceRules": [
  {
    "@type": "RecurrenceRule",
    "frequency": "monthly"
  }
],
"recurrenceOverrides": {
  "2023-08-01T13:00:00": {
    "excluded": true
  }
}
Figure 50: Converting the EXDATE property

2.3.21. EXRULE

The EXRULE property [RFC2445] (Section 4.8.5.2) in a VEVENT or VTODO component converts to a RecurrenceRule object [RFC8984] (Section 4.3.3). The converted object is set in the excludedRecurrenceRules property of the Event or Task.

See Section 2.3.39 for an example how to convert a recurrence rule.

2.3.22. GEO

The GEO property [RFC5545] (Section 3.8.1.6) in a VEVENT, VTODO, PARTICIPANT or VRESOURCE component converts to a Location object [RFC8984] (Section 4.2.5). The converted object is set in the locations property of the Event, Task, or Participant object.

The GEO property [RFC5545] (Section 3.8.1.6) in a VLOCATION component converts to the coordinates property [RFC8984] (Section 4.2.5) of the Location object.

The pair of FLOAT values converts to an URI with the "geo" scheme [RFC5870]. The first FLOAT value converts to the "coord-a" part of the URI, the second FLOAT value to the "coord-b" part. A preceding plus sign (+) of the FLOAT value MUST be omitted, a preceding minus sign (-) MUST be preserved. The third, altitude coordinate MUST NOT be set, unless its value is known.

The following examples illustrate how to convert the GEO property:

GEO:+45.5;-93.3
"locations": {
  "d4": {
    "@type": "Location",
    "coordinates": "geo:45.5,-93.3"
  }
}
Figure 51: Converting the GEO property in a VEVENT
BEGIN:VEVENT
BEGIN:VLOCATION
NAME:Eiffel Tower
GEO:48.858222;2.2945
...
"locations": {
  "2": {
    "@type": "Location",
    "name": "Eiffel Tower",
    "coordinates": "geo:48.858222,2.2945"
  }
}
Figure 52: Converting the GEO property in a VLOCATION

2.3.23. IMAGE

The IMAGE property [RFC7986] (Section 5.10) in a VEVENT, VTODO, VLOCATION, or VRESOURCE component converts to a Link object [RFC8984] (Section 1.4.11). The converted object is set in the links property of the Event, Task, Location, or Participant object.

The property value converts to the href property of the Link object. A value of type URI converts as-is. See Section 2.3.3 how to convert a BINARY value. If the DISPLAY parameter is set, then the "rel" property of the Link object MUST be set to "icon".

Its parameters convert as follows:

Table 21: Parameters of the IMAGE property
Name Reference Property Note
DISPLAY [RFC7986], Section 6.1 display
FMTTYPE [RFC5545], Section 3.2.8 contentType
SIZE [RFC8607], Section 4.1 size

Implementations MAY preserve the fact that the Link object got converted from an IMAGE property. To so, they MUST set the iCalProperty (Section 5.1.3) on the Link object.

The following example illustrates how to convert the IMAGE property:

IMAGE;VALUE=URI;DISPLAY=BADGE;FMTTYPE=image/png:
 https://example.com/images/party.png
"links": {
  "4": {
    "@type": "Link",
    "href": "https://example.com/images/party.png",
    "display": "badge",
    "rel": "icon",
    "contentType": "image/png",
    "iCalProperty": {
      "@type": "ICalProperty",
      "name": "image"
    }
  }
}
Figure 53: Converting the IMAGE property

2.3.24. LAST-MODIFIED

The LAST-MODIFIED property [RFC5545] (Section 3.8.7.3) in a VEVENT, VTODO, VCALENDAR, or VTIMEZONE component converts to the updated property [RFC8984] (Section 4.1.6) of the Event, Task, Group, or TimeZone object.

Both the LAST-MODIFIED and DTSTAMP properties convert to the updated property. If both are present in the same component, then the DTSTAMP property value has higher precedence. Implementations MAY in that case preserve the value of the LAST-MODIFIED property in the iCalComponent property.

The following example illustrates how to convert the LAST-MODIFIED property:

LAST-MODIFIED:20240914T231257Z
"updated": "2024-09-14T23:12:57Z"
Figure 54: Converting the IMAGE property

2.3.26. LOCATION

The LOCATION property [RFC5545] (Section 3.8.1.7) in a VEVENT, VTODO, or PARTICIPANT component converts to a Location object [RFC8984] (Section 4.2.5), unless its DERIVED parameter value is TRUE. The converted object is set in the locations property of the Event, Task, or Participant object.

The property value converts to the title property of the Location object.

If the DERIVED parameter value is TRUE, then the property does not convert to a Location object. Instead, a VLOCATION component is expected to represent the location. Implementations MAY preserve the property in the iCalComponent property (Section 5.1.2).

The following example illustrates how to convert the LOCATION property:

LOCATION:Conference Room - F123\, Bldg. 002
"locations": {
  "f45": {
    "@type": "Location",
    "title": "Conference Room - F123, Bldg. 002"
  }
}
Figure 57: Converting the LOCATION property

2.3.27. LOCATION-TYPE

The LOCATION-TYPE property [RFC9073] (Section 6.1) in a VLOCATION component converts to the locationTypes property [RFC8984] (Section 4.2.5) of the Location object.

The list of location type values converts to a set of location types. The values convert case-sensitively. All LOCATION-TYPE properties in the same VLOCATION convert to the locationTypes property in the Location object.

The following example illustrates how to convert the LOCATION-TYPE property:

BEGIN:VEVENT
BEGIN:VLOCATION
LOCATION-TYPE:hotel,restaurant
LOCATION-TYPE:bar
...
"locations": {
  "1": {
    "@type": "Location",
    "locationTypes": {
      "bar": true,
      "hotel": true,
      "restaurant": true
    },
    "...": ""
  }
}
Figure 58: Converting the LOCATION property

2.3.28. METHOD

The METHOD property [RFC5545] (Section 3.7.2) in a VCALENDAR component converts to the method property [RFC8984] (Section 4.1.8) of all Event or Task objects that are listed in the Group object's entries property.

The property value converts in lowercase.

The following example illustrates how to convert the METHOD property:

BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VEVENT
...
{
  "@type": "Group",
  "entries": [
    {
      "@type": "Event",
      "method": "request",
      "...": ""
    }
  ],
  "...": ""
}
Figure 59: Converting the METHOD property

2.3.29. NAME

The NAME property [RFC7986] (Section 5.1) in a VLOCATION or VRESOURCE component converts to the name property of the Location [RFC8984] (Section 4.2.5) or Participant [RFC8984] (Section 4.4.6) object.

The NAME property [RFC7986] (Section 5.1) in a VCALENDAR component converts to the title property [RFC8984] (Section 4.2.1) of the Group object.

The following examples illustrate how to convert the NAME property:

BEGIN:VCALENDAR
NAME:Company Vacation Days
...
{
  "@type": "Group",
  "title": "Company Vacation Days",
  "...": ""
}
Figure 60: Converting the NAME property in a VCALENDAR component
BEGIN:VEVENT
BEGIN:PARTICIPANT
NAME:John Doe
...
END:PARTICIPANT
BEGIN:VLOCATION
NAME:Fred's Bar
...
END:VLOCATION
...
"locations": {
  "1": {
    "@type": "Location",
    "name": "Fred's Bar",
    "...": ""
  }
},
"participants": {
  "1": {
    "@type": "Participant",
    "name": "John Doe",
    "...": ""
  }
}
Figure 61: Converting the NAME property in the VLOCATION and PARTICIPANT components

2.3.30. ORGANIZER

The ORGANIZER property [RFC5545] (Section 3.8.4.3) in a VEVENT or VTODO component converts to the replyTo property [RFC8984] (Section 4.4.4) of the Event or Task object. In addition, it converts to a Participant object in the participants property [RFC8984] (Section 4.4.6).

If the CAL-ADDRESS property value is in the "mailto" scheme, then it converts to the "imip" method in the replyTo property, otherwise it converts to the "other" method. The property value also converts to the calendarAddress property of the Participant object. The "owner" role is set in the roles property of the Participant. In contrast to the ATTENDEE property, the property value does not convert to the sendTo property of the Participant object.

An ORGANIZER property, an ATTENDEE property, and a PARTICIPANT component in the same iCalendar component all convert to the same Participant object, if their converted calendarAddress property values are equal after URI normalization [RFC3986] (Section 6). How to deal with conflicting values when converting other Participant properties is implementation-specific.

Implementations MAY preserve arbitrary parameters of the ORGANIZER property, in which case they MUST convert these to a "replyTo" entry in the convertedProperties property of the Event or Task object's iCalComponent property (Section 5.1.2).

The ORGANIZER property parameters convert as follows:

Table 23: Parameters of the ORGANIZER property
Name Reference Property Note
CN [RFC5545], Section 3.2.2 name
DIR [RFC5545], Section 3.2.6 links
SCHEDULE-AGENT [RFC6638], Section 7.1 scheduleAgent (Section 5.1.5)
SCHEDULE-FORCE-SEND [RFC6638], Section 7.2 scheduleForceSend (Section 5.1.6)
SCHEDULE-STATUS [RFC6638], Section 7.3 scheduleStatus (Section 5.1.7)

The following examples illustrate how to convert the ORGANIZER property:

ORGANIZER:mailto:foo@example.com
...
ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:bar@example.com
"replyTo": {
  "imip": "mailto:foo@example.com"
},
"participants": {
  "a": {
    "@type": "Participant",
    "calendarAddress": "mailto:foo@example.com",
    "roles": {
      "owner": true
    }
  },
  "b": {
    "@type": "Participant",
    "...": ""
  }
}
Figure 62: Converting an ORGANIZER property
ORGANIZER:mailto:foo@example.com
ATTENDEE;RSVP=FALSE;PARTSTAT=ACCEPTED;CN="Jane Doe":mailto:foo@example.com
...
ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:bar@example.com
"replyTo": {
  "imip": "mailto:foo@example.com"
},
"participants": {
  "a": {
    "@type": "Participant",
    "calendarAddress": "mailto:foo@example.com",
    "name": "Jane Doe",
    "participationStatus": "accepted",
    "roles": {
      "attendee": true,
      "owner": true
    },
    "sendTo": {
      "imip": "mailto:foo@example.com"
    }
  },
  "b": {
    "@type": "Participant",
    "...": ""
  }
}
Figure 63: Converting an ORGANIZER and ATTENDEE property

2.3.31. PARTICIPANT-TYPE

The PARTICIPANT-TYPE property [RFC9073] (Section 6.2) in a PARTICIPANT component converts to the roles property [RFC8984] (Section 4.4.6) of the Participant object.

The property value converts in lowercase.

The following example illustrates how to convert the PARTICIPANT-TYPE property:

BEGIN:PARTICIPANT
PARTICIPANT-TYPE:CONTACT
CALENDAR-ADDRESS:mailto:foo@example.com
...
END:PARTICIPANT
ATTENDEE;RSVP=YES;PARTSTAT=NEEDS-ACTION:mailto:foo@example.com
"participants": {
  "a": {
    "@type": "Participant",
    "roles": {
      "attendee": true,
      "contact": true
    },
    "...": ""
  },
  "b": {
    "...": ""
  }
}
Figure 64: Converting the PARTICIPANT-TYPE property

2.3.32. PERCENT-COMPLETE

The PERCENT-COMPLETE property [RFC5545] (Section 3.8.1.8) in a VTODO component converts to the percentComplete property [RFC8984] (Section 5.2.4) of the Task object.

A Task object which has the method property set might represent an iTIP reply of one of the participants in the object. In this case the value of the percentComplete property in the Task also converts to the percentComplete [RFC8984] (Section 4.4.6) of that Participant object, which represents the participant from which the iTIP reply originated.

The PERCENT-COMPLETE property in a PARTICIPANT component converts to the percentComplete property [RFC8984] (Section 4.4.6) of the Participant object.

The following examples illustrate how to convert the PERCENT-COMPLETE property:

BEGIN:VCALENDAR
METHOD:REPLY
BEGIN:VTODO
PERCENT-COMPLETE:53
...
{
  "@type": "Group",
  "entries": [
    {
      "@type": "Task",
      "method": "reply",
      "percentComplete": 53,
      "...": ""
    }
  ],
  "...": ""
}
Figure 65: Converting the PERCENT-COMPLETE property in a VEVENT component
BEGIN:VTODO
BEGIN:PARTICIPANT
PERCENT-COMPLETE:78
...
"@type": "Task",
"participants": {
  "f4": {
    "@type": "Participant",
    "percentComplete": 78,
    "...": ""
  }
}
Figure 66: Converting the PERCENT-COMPLETE property in a PARTICIPANT component

2.3.33. PRIORITY

The PRIORITY property [RFC5545] (Section 3.8.1.9) in a VEVENT or VTODO component converts to the priority property [RFC8984] (Section 4.4.1) of the Event or Task object.

The following example illustrates how to convert the PRIORITY property:

PRIORITY:3
"priority": 3
Figure 67: Converting the PRIORITY property

2.3.34. PRODID

The PRODID property [RFC5545] (Section 3.7.3) in a VCALENDAR component converts to the prodId property [RFC8984] (Section 4.1.4) of the Group object, and to the prodId property of all Event or Task objects that are listed in the Group object's entries property.

The property value converts verbatim.

The following example illustrates how to convert the PRODID property:

BEGIN:VCALENDAR
PRODID:-//BAZ//bam//EN
BEGIN:VEVENT
...
{
  "@type": "Group",
  "prodId": "-//BAZ//bam//EN",
  "entries": [
    {
      "@type": "Event",
      "prodId": "-//BAZ//bam//EN",
      "...": ""
    }
  ],
  "...": ""
}
Figure 68: Converting the PRODID property

2.3.35. RDATE

The RDATE property [RFC5545] (Section 3.8.5.2) of type DATE or DATE-TIME in a VEVENT, VTODO, DAYLIGHT or STANDARD component converts to a PatchObject object [RFC8984] (Section 1.4.9). The converted object is set in the recurrenceOverrides property of the Event, Task, or TimeZoneRule object.

The property value converts to the key in the recurrenceOverrides property value. See Section 2.1.5 how to convert DATE and DATE-TIME values. For Event Task objects, the date-time MUST be relative to the timezone identified by the timeZone property, for TimeZoneRule objects the date-time is relative to the UTC offset specified in the offsetFrom property. The PatchObject value MUST be an empty JSON object.

An RDATE property of value type PERIOD does not convert to a standard JSCalendar element. Implementations MAY convert it to the iCalComponent property (Section 5.1.2) of the Event, Task, or TimeZoneRule object.

The following example illustrates how to convert the RDATE property:

DTSTART:20230101T130000Z
RRULE:FREQ=MONTHLY
RDATE:20230805T170000Z
"start": "2023-01-01T13:00:00",
"timeZone": "Etc/UTC",
"recurrenceRules": [
  {
    "@type": "RecurrenceRule",
    "frequency": "monthly"
  }
],
"recurrenceOverrides": {
  "2023-08-05T17:00:00": {}
}
Figure 69: Converting the RDATE property

2.3.36. RECURRENCE-ID

The RECURRENCE-ID property [RFC5545] (Section 3.8.4.4) in a VEVENT or VTODO component converts to the recurrenceId property [RFC8984] (Section 4.3.1) of the Event or Task object. The timezone identifier (Section 2.1.4) of the RECURRENCE-ID property converts to the recurrenceIdTimeZone property.

See Section 2.1.5 how to convert DATE and DATE-TIME values.

The RANGE parameter [RFC5545] (Section 3.2.13) does not convert to a standard JSCalendar element. Implementations MAY preserve it in the iCalComponent (Section 5.1.2) property.

See Section 2.1.2 for further requirements and examples.

2.3.38. REQUEST-STATUS

The REQUEST-STATUS property [RFC5545] (Section 3.8.8.3) in a VEVENT or VTODO component converts to the requestStatus property [RFC8984] (Section 4.4.7) of the Event or Task object.

The following example illustrates how to convert the REQUEST-STATUS property:

2.3.39. RRULE

The RRULE property [RFC5545] (Section 3.8.5.3) in a VEVENT, VTODO, DAYLIGHT or STANDARD component converts to a RecurrenceRule object [RFC8984] (Section 4.3.3). The converted object is set in the recurrenceRules property of the Event, Task, or TimeZoneRule object.

The RECUR value data type converts to a RecurrenceRule object as follows:

Table 24: Converting the RECUR value type to a RecurrenceRule object
RRULE field RecurrenceRule property
FREQ frequency
UNTIL until
COUNT count
INTERVAL interval
BYSECOND bySecond
BYMINUTE byMinute
BYHOUR byHour
BYDAY byDay
BYMONTHDAY byMonthDay
BYYEARDAY byYearDay
BYWEEKNO byWeekNo
BYMONTH byMonth
BYSETPOS bySetPosition
WKST firstDayOfWeek
RSCALE [RFC7529] rscale
SKIP [RFC7529] skip

The string values of the FREQ, WKST, RSCALE convert to lowercase. The UNTIL part in a VEVENT or VTODO converts to a LocalDateTime value relative to the timezone of the Event or Task, or to floating time for the TimeZoneRule object.

The following example illustrates how to convert the RRULE property:

DTSTART;TZID=Europe/Berlin:20240101T010000
RRULE:FREQ=YEARLY
 ;INTERVAL=2
 ;BYMONTH=1
 ;BYDAY=SU
 ;BYHOUR=8,9
 ;BYMINUTE=30
 ;UNTIL=20240930T120000Z
"recurrenceRules": [
  {
    "@type": "RecurrenceRule",
    "frequency": "yearly",
    "interval": 2,
    "byMonth": [
      "1"
    ],
    "byDay": [
      {
        "@type": "NDay",
        "day": "su"
      }
    ],
    "byHour": [
      8,
      9
    ],
    "byMinute": [
      30
    ],
    "until": "2024-09-30T14:00:00"
  }
],
"start": "2024-01-01T01:00:00",
"timeZone": "Europe/Berlin"
Figure 73: Example for converting the RRULE property

2.3.40. SEQUENCE

The SEQUENCE property [RFC5545] (Section 3.8.7.4) in a VEVENT or VTODO component converts to the sequence property [RFC8984] (Section 4.1.7) of the Event or Task object. The SEQUENCE property in a PARTICIPANT component converts to the scheduleSequence property [RFC8984] (Section 4.4.6) of the Participant object.

The following example illustrates how to convert the SEQUENCE property:

2.3.41. STATUS

The STATUS property [RFC5545] (Section 3.8.1.11) in a VEVENT component converts to the status property [RFC8984] (Section 5.1.3) of the Event object. The STATUS property in a VTODO component converts to the progress property [RFC8984] (Section 5.2.5) of the Task object.

The property value converts in lowercase.

The following examples illustrate how to convert the STATUS property:

BEGIN:VTODO
STATUS:IN-PROCESS
...
{
  "@type": "Task",
  "progress": "in-process",
  "...": ""
}
Figure 76: Example for converting the STATUS property in a VTODO component

2.3.42. SOURCE

The SOURCE property [RFC7986] (Section 5.8) in a VCALENDAR component converts to the source property [RFC8984] (Section 5.3.2) of the Group object.

The following example illustrates how to convert the SOURCE property:

BEGIN:VCALENDAR
SOURCE;VALUE=URI:https://example.com/holidays.ics
...
{
  "@type": "Group",
  "source": "https://example.com/holidays.ics",
  "...": ""
}
Figure 77: Example for converting the SOURCE property

2.3.43. STRUCTURED-DATA

The STRUCTURED-DATA property [RFC9073] (Section 6.6) of type URI or BINARY in a VEVENT, VTODO, VCALENDAR, VRESOURCE, PARTICIPANT, or VLOCATION component converts to a Link object [RFC8984] (Section 1.4.11). The converted object is set in the links property of the Event, Task, Group, Participant, or Location object.

The property value converts to the href property of the Link object. A value of type URI converts as-is. See Section 2.3.3 how to convert a BINARY value.

Its parameters convert as follows:

Table 25: Parameters of the STRUCTURED-DATA property
Name Reference Property Note
FMTTYPE [RFC5545], Section 3.2.8 contentType

Implementations MAY preserve the fact that the Link object got converted from a STRUCTURED-DATA property. To so, they MUST set the iCalProperty (Section 5.1.3) on the Link object.

The following example illustrates how to convert the STRUCTURED-DATA property:

STRUCTURED-DATA;FMTTYPE=application/ld+json;
 SCHEMA="https://schema.org/FlightReservation";
 ENCODING=BASE64;VALUE=BINARY:InRydW5jYXRlZC4uLiIK
"links": {
  "@type": "Link",
  "contentType": "application/ld+json",
  "href": "data:application/ld+json;base64,InRydW5jYXRlZC4uLiIK",
  "iCalProperty": {
    "@type": "ICalProperty",
    "name": "structured-data",
    "parameters": {
      "schema": "https://schema.org/FlightReservation"
    },
    "valueType": "binary"
  }
}
Figure 78: Converting the STRUCTURED-DATA property

2.3.44. STYLED-DESCRIPTION

The STYLED-DESCRIPTION property [RFC9073] (Section 6.5) in a VEVENT or VTODO component converts to the description property [RFC8984] (Section 4.2.2) of the Event or Task object under the following conditions:

  • The property value type MUST be TEXT.
  • The FMTTYPE parameter either MUST NOT not be set, or its value MUST be a media type [RFC6838] with top-level type "text".
  • Its DERIVED parameter value MUST NOT be TRUE.

If the DERIVED parameter value is TRUE, then the property does not convert to the description property. Instead, an non-derived STYLED-DESCRIPTION property or the DESCRIPTION property is expected to contain the description. Implementations MAY preserve the property in the iCalComponent property (Section 5.1.2).

Its parameters convert as follows:

Table 26: Parameters of the STYLED-DESCRIPTION property
Name Reference Property Note
FMTTYPE [RFC5545], Section 3.2.8 descriptionContentType

The following example illustrates how to convert the STYLED-DESCRIPTION property:

STYLED-DESCRIPTION;VALUE=TEXT;FMTTYPE=text/html:
 <!DOCTYPE html><html><body>hello,<b>world</b></body></html>
"description": "<!DOCTYPE html><html><body>hello,<b>world</b></body></html>",
"descriptionContentType": "text/html"
Figure 79: Converting the STYLED-DESCRIPTION property

2.3.45. SUMMARY

The SUMMARY property [RFC5545] (Section 3.8.1.12) in a VEVENT or VTODO component converts to the title property [RFC8984] (Section 4.2.1) of the Event or Task object.

The SUMMARY property [RFC5545] (Section 3.8.1.12) in a PARTICIPANT component converts to the name property [RFC8984] (Section 4.2.5).

The following examples illustrate how to convert the SUMMARY property:

SUMMARY:Birthday Party
"title": "Birthday Party"
Figure 80: Converting the SUMMARY property in a VEVENT
BEGIN:VEVENT
BEGIN:PARTICIPANT
SUMMARY:John
...
"participants": {
  "1": {
    "@type": "Participant",
    "name": "John",
    "...": ""
  }
}
Figure 81: Converting the SUMMARY property in a PARTICIPANT

2.3.46. TRANSP

The TRANSP property [RFC5545] (Section 3.8.2.7) in a VEVENT or VTODO component converts to the freeBusyStatus property [RFC8984] (Section 4.4.2) of the Event or Task object.

Its values convert as follows:

Table 27: Values of the TRANSP property
iCalendar value JSCalendar value
OPAQUE busy
TRANSPARENT free

The following example illustrates how to convert the TRANSP property:

TRANSP:TRANSPARENT
"freeBusyStatus": "free"
Figure 82: Converting the TRANSP property

2.3.47. TRIGGER

The TRIGGER property [RFC5545] (Section 3.8.6.3) in a VALARM component converts to either an AbsoluteTrigger or OffsetTrigger object. The converted object is set in the trigger property [RFC8984] (Section 4.5.2) of the Alert object.

A property of value type DURATION converts an OffsetTrigger object. The property value converts to its offset property. A value of type DATE-TIME converts to an AbsoluteTrigger object. The property value converts to its when property.

Its parameters convert as follows:

Table 28: Parameters of the TRIGGER property
Name Reference Property Note
RELATED [RFC5545], Section 3.2.14 relativeTo If VALUE=DURATION

The following examples illustrate how to convert the TRIGGER property:

BEGIN:VEVENT
...
BEGIN:VALARM
TRIGGER;RELATED=END:PT5M
...
"alerts": {
  "2d": {
    "@type": "Alert",
    "trigger": {
      "@type": "OffsetTrigger",
      "offset": "PT5M",
      "relativeTo": "end"
    },
    "...": ""
  }
}
Figure 83: Converting the TRIGGER property to an OffsetTrigger
BEGIN:VEVENT
...
BEGIN:VALARM
TRIGGER;VALUE=DATE-TIME:20250302T010203Z
...
"alerts": {
  "14": {
    "@type": "Alert",
    "trigger": {
      "@type": "AbsoluteTrigger",
      "when": "2025-03-02T01:02:03Z"
    },
    "...": ""
  }
}
Figure 84: Converting the TRIGGER property to an AbsoluteTrigger

2.3.48. TZID

The TZID property [RFC5545] (Section 3.8.3.1) in a VTIMEZONE component converts to the tzId property [RFC8984] (Section 4.7.2) of the TimeZone object.

See Figure 14 for an example.

2.3.49. TZID-ALIAS-OF

The TZID-ALIAS-OF property [RFC7808] (Section 7.2) in a VTIMEZONE component converts to an entry in the aliases property [RFC8984] (Section 4.7.2) of the TimeZone object.

See Figure 14 for an example.

2.3.50. TZNAME

The TZNAME property [RFC5545] (Section 3.8.3.2) in a DAYLIGHT or STANDARD component converts to an entry in the names property [RFC8984] (Section 4.7.2) of the TimeZoneRule object.

See Figure 14 for an example.

2.3.51. TZOFFSETFROM

The TZOFFSETFROM property [RFC5545] (Section 3.8.3.3) in a DAYLIGHT or STANDARD component converts to the offsetFrom property [RFC8984] (Section 4.7.2) of the TimeZoneRule object.

See Figure 14 for an example.

2.3.52. TZOFFSETTO

The TZOFFSETTO property [RFC5545] (Section 3.8.3.4) in a DAYLIGHT or STANDARD component converts to the offsetTo property [RFC8984] (Section 4.7.2) of the TimeZoneRule object.

See Figure 14 for an example.

2.3.53. TZUNTIL

The TZUNTIL property [RFC7808] (Section 7.1) in a VTIMEZONE component converts to the validUntil property [RFC8984] (Section 4.7.2) of the TimeZone object.

See Section 2.1.5 how to convert DATE and DATE-TIME values.

See Figure 14 for an example.

2.3.54. TZURL

The TZURL property [RFC5545] (Section 3.8.3.5) in a VTIMEZONE component converts to the url property [RFC8984] (Section 4.7.2) of the TimeZone object.

See Figure 14 for an example.

2.3.55. UID

The UID property [RFC5545] (Section 3.8.4.7) in a VEVENT, VTODO, or VCALENDAR component converts to the uid property [RFC8984] (Section 4.1.2) of the Event, Task, or Group object.

The following example illustrates how to convert the UID property:

UID:5ACEA86F-40CF-47EE-9CCA-7C85588A589F
"uid": "5ACEA86F-40CF-47EE-9CCA-7C85588A589F"
Figure 85: Converting the UID property

2.3.56. URL

The URL property [RFC5545] (Section 3.8.4.6) in a VEVENT, VTODO, VCALENDAR, or PARTICIPANT component converts to a Link object [RFC8984] (Section 1.4.11). The converted object is set in the links property of the Event, Task, Group, or Participant object.

The property value converts to the href property of the Link object.

Implementations MAY preserve the fact that the Link object got converted from an URL property. To so, they MUST set the iCalProperty (Section 5.1.3) on the Link object.

The following example illustrates how to convert the URL property:

URL:https://example.com/calendar/birtdays.ics
"links": {
  "3": {
    "@type": "Link",
    "href": "https://example.com/calendar/birtdays.ics",
    "iCalProperty": {
      "@type": "ICalProperty",
      "name": "url"
    }
  }
}
Figure 86: Converting the IMAGE property

3. Converting JSCalendar to iCalendar

3.1. Alert

The Alert object [RFC8984] (Section 4.5.2) converts to a VALARM component (Section 2.2.2).

Its properties convert as follows:

Table 29: Properties of the Alert object
Name Reference Property (or other) See
acknowledged [RFC8984], Section 4.5.2 ACKNOWLEDGED Section 2.3.1
action [RFC8984], Section 4.5.2 ACTION Section 2.3.2
relatedTo [RFC8984], Section 4.1.3 RELATED-TO

Section 2.3.37, and remarks below

trigger [RFC8984], Section 4.5.2 TRIGGER Section 2.3.47

Remarks:

  • The value of the RELATED-TO property is the UID property value of that VALARM component, to which the related Alert object converts to. Consequently, the UID property for such a VALARM MUST be set, otherwise the UID property SHOULD be set.

3.2. Event and Task

The Event object [RFC8984] (Section 2.1) converts to a VEVENT component (Section 2.2.3), the Task object [RFC8984] (Section 2.2) converts to a VTODO component (Section 2.2.7).

The following table defines how to convert properties that are common to both the Event and Task object types. Table 31 and Table 32 later in this section define how to convert properties specific to either Event or Task objects.

Table 30: Properties of the Event and Task object
Name Reference Property (or other) See
alerts [RFC8984], Section 4.5.2 VALARM (component) Alert object (Section 3.1)
categories [RFC8984], Section 4.2.10 CONCEPT Section 2.3.11
color [RFC8984], Section 4.2.11 COLOR Section 2.3.8
created [RFC8984], Section 4.1.5 CREATED Section 2.3.13
description [RFC8984], Section 4.2.2 DESCRIPTION, or STYLED-DESCRIPTION

Section 2.3.14, Section 2.3.44, and remarks below

descriptionContentType [RFC8984], Section 4.2.3 FMTTYPE (parameter) of STYLED-DESCRIPTION

Section 2.3.44, and remarks below

excluded [RFC8984], Section 4.3.6

Section 2.3.20, and remarks about recurrenceOverrides below

excludedRecurrenceRules [RFC8984], Section 4.3.4 EXRULE

Section 2.3.21

freeBusyStatus [RFC8984], Section 4.4.2 TRANSP

Section 2.3.46

keywords [RFC8984], Section 4.2.9 CATEGORIES

Section 2.3.6

links [RFC8984], Section 4.2.7 ATTACH, or other

Link object (Section 3.4)

locale [RFC8984], Section 4.2.8 TBD
localizations [RFC8984], Section 4.6.1 TBD
locations [RFC8984], Section 4.2.5 LOCATION, GEO, or VLOCATION (component)

Location object (Section 3.5)

method [RFC8984], Section 4.1.8 METHOD of iCalendar object

Section 2.3.28, and Group object (Section 3.3)

participants [RFC8984], Section 4.4.6 ATTENDEE, or PARTICIPANT (component)

Participant object (Section 3.6)

priority [RFC8984], Section 4.4.1 PRIORITY

Section 2.3.33

privacy [RFC8984], Section 4.4.3 CLASS

Section 2.3.7

prodId [RFC8984], Section 4.1.4 PRODID of iCalendar object

Section 2.3.34, and Group object (Section 3.3)

recurrenceId [RFC8984], Section 4.3.1 RECURRENCE-ID

Section 2.3.36

recurrenceIdTimeZone [RFC8984], Section 4.3.2 TZID (parameter) of RECURRENCE-ID

Section 2.3.36

recurrenceOverrides [RFC8984], Section 4.3.5 RDATE, EXDATE or recurrence override component Section 2.1.2, and remarks below
recurrenceRules [RFC8984], Section 4.3.3 RRULE

Section 2.3.39

relatedTo [RFC8984], Section 4.1.3 RELATED-TO

Section 2.3.37

replyTo [RFC8984], Section 4.4.4 ORGANIZER

Section 2.3.30, and remarks below

requestStatus [RFC8984], Section 4.4.7 REQUEST-STATUS

Section 2.3.38

sentBy [RFC8984], Section 4.4.5 TBD
sequence [RFC8984], Section 4.1.7 SEQUENCE

Section 2.3.40

showWithoutTime [RFC8984], Section 4.2.4 TBD
start [RFC8984], Section 4.7.2 DTSTART

Section 2.3.17

timeZone [RFC8984], Section 4.7.1 TZID (parameter) of DTSTART and DUE

Section 2.3.17, Section 2.3.18

timeZones [RFC8984], Section 4.7.2 VTIMEZONE (component) of iCalendar object

TimeZone object (Section 3.7)

title [RFC8984], Section 4.2.1 SUMMARY

Section 2.3.45

uid [RFC8984], Section 4.1.2 UID

Section 2.3.55

updated [RFC8984], Section 4.1.6 DTSTAMP, and LAST-MODIFIED

Section 2.3.16, Section 2.3.24

useDefaultAlerts [RFC8984], Section 4.5.1 TBD
virtualLocations [RFC8984], Section 4.2.6 CONFERENCE

Section 2.3.12

Remarks:

  • The descriptionContentType property value determines if to convert the description property to the DESCRIPTION or STYLED-DESCRIPTION property. A description of content type "text/plain" converts to the DESCRIPTION property. Any other description converts to a STYLED-DESCRIPTION; in this case, a plain text version of the rich-text description SHOULD be set in the DESCRIPTION property and its DERIVED parameter MUST be set to "TRUE".

  • The entries in the recurrenceOverrides property convert depending on the contents of the patch object value. A patch object that sets the excluded property to "true" converts to an EXDATE property for the date-time of that recurrence instance. An empty patch object converts to an RDATE property. Any other patch object converts to a recurrence override component in the embedding VCALENDAR component.

  • The replyTo property converts to the ORGANIZER property. If the replyTo property value only defines a single scheduling method then the URI value of that method converts to the ORGANIZER property value. If the replyTo property defines multiple scheduling methods, and a Participant object with a calendarAddress property value matching one of the replyTo URIs exists in the same Event or Task, then the URI matching the calendarAddress property converts to the ORGANIZER property value. Otherwise choosing the ORGANIZER property value is implementation-specific. TBD how to convert other replyTo methods.

Properties specific to the Event object type convert to iCalendar properties as follows:

Table 31: Properties of the Event object
Name Reference Property (or other) See
duration [RFC8984], Section 5.1.2 DURATION, or DTEND

Section 2.3.19, Section 2.3.15

status [RFC8984], Section 5.1.3 STATUS

Section 2.3.41

Properties specific to the Task object type convert to iCalendar properties as follows:

Table 32: Properties of the Task object
Name Reference Property (or other) See
due [RFC8984], Section 5.2.1 DUE

Section 2.3.18

estimatedDuration [RFC8984], Section 5.2.3 TBD
percentComplete [RFC8984], Section 5.2.4 PERCENT-COMPLETE

Section 2.3.32

progress [RFC8984], Section 5.2.5 STATUS

Section 2.3.41

progressUpdated [RFC8984], Section 5.2.6 TBD

3.3. Group

The Group object [RFC8984] (Section 2.3) converts to a VCALENDAR component (Section 2.1.1).

Its properties convert as follows:

Table 33: Properties of the Group object
Name Reference Property (or other) See
categories [RFC8984], Section 4.2.10 CONCEPT

Section 2.3.11

color [RFC8984], Section 4.2.11 COLOR

Section 2.3.8

created [RFC8984], Section 4.1.5 CREATED

Section 2.3.13

entries [RFC8984], Section 5.3.1 VEVENT or VTODO (component)

Event and Task object (Section 3.2), and remarks below

keywords [RFC8984], Section 4.2.9 CATEGORIES

Section 2.3.6

links [RFC8984], Section 4.2.7 ATTACH, or other

Link object (Section 3.4)

locale [RFC8984], Section 4.2.8 TBD
prodId [RFC8984], Section 4.1.4 PRODID

Section 2.3.34, and remarks below

source [RFC8984], Section 5.3.2 SOURCE

Section 2.3.42

title [RFC8984], Section 4.2.1 NAME

Section 2.3.29

uid [RFC8984], Section 4.1.2 UID

Section 2.3.55

updated [RFC8984], Section 4.1.6 LAST-MODIFIED

Section 2.3.24

Remarks:

  • The prodId property value of the Group object is expected to be equal to the prodId property value of all the Group entries. They all convert to the same, single PRODID property in the VCALENDAR component. How to convert unequal prodId property values is implementation-specific.

  • The method property value in all the Group entries is expected to be equal. How to convert entries with unequal method property values is implementation-specific.

3.5. Location

The Location object [RFC8984] (Section 4.2.5) converts to either a LOCATION (Section 2.3.26), GEO (Section 2.3.22), or DTEND (Section 2.3.22) property, or it converts to a VLOCATION component (Section 2.2.4). Which iCalendar element to choose is implementation-specific. As a guideline:

  • Choose LOCATION, if only the title property is set and the iCalendar component not already contains a LOCATION property. The title property converts to the LOCATION property value.
  • Choose GEO, if only the coordinates property is set the iCalendar component not already contains a GEO property. The coordinates property converts to the GEO property value. TBD - How to convert arbitrary geo: URIs?
  • Choose DTEND, if the embedding object is an Event, only the timeZone and the relativeTo properties are set, the relativeTo property value is "end" and the iCalendar component not already contains a DTEND property. The timeZone property converts to the TZID parameter of the DTEND property. The duration of the embedding Event object determines the DTEND property value.
  • Choose the VLOCATION component otherwise.

Implementations MAY convert one of the Location objects that convert to a VLOCATION also to the LOCATION property; converting the title or description property to the LOCATION property value is a reasonable choice. The DERIVED parameter MUST be set on the LOCATION property.

The properties convert to a VLOCATION component as follows:

Table 35: Properties of the Location object
Name Reference Property (or other) See
coordinates [RFC8984], Section 4.2.5 GEO Section 2.3.22
description [RFC8984], Section 4.2.2 DESCRIPTION Section 2.3.14
links [RFC8984], Section 4.2.7 ATTACH, or other

Link object (Section 3.4)

locationTypes [RFC8984], Section 4.2.5 LOCATION-TYPE Section 2.3.27
name [RFC8984], Section 4.2.5 NAME Section 2.3.29
relativeTo [RFC8984], Section 4.5.2 TBD
timeZone [RFC8984], Section 4.7.1 TBD

3.6. Participant

The Participant object [RFC8984] (Section 4.4.6) either converts to one of an ATTENDEE property (Section 2.3.4), a PARTICIPANT component (Section 2.2.1), or a VRESOURCE component (Section 2.2.5); or it converts to both an ATTENDEE property and a PARTICIPANT component:

  • It converts to an ATTENDEE property if at least one of the calendarAddress [I-D.ietf-jmap-calendars] (Section 5.1.1) or sendTo [RFC8984] (Section 4.4.6) properties is set. The calendarAddress property converts to the ATTENDEE property value, if set; otherwise one of the scheduling methods in the sendTo property converts to the ATTENDEE property value.

  • It converts to a PARTICIPANT component if it converts to an ATTENDEE property but not all of its properties convert to ATTENDEE property parameters as depicted in Table 36. In this case the CALENDAR-ADDRESS property value of the PARTICIPANT MUST be set to the ATTENDEE property value. Alternatively, the Participant object also converts to a PARTICIPANT component if it does not convert to an ATTENDEE property but its kind property value is unequal to "resource".

  • It converts to a VRESOURCE component if it does not convert to an ATTENDEE property and its kind property value is "resource".

The following Participant properties convert to the ATTENDEE property. How to convert these properties if the Participant does not convert to an ATTENDEE is implementation-specific.

Table 36: Properties of the Participant object that convert to the ATTENDEE property
Name Reference Parameter (or other) See
delegatedFrom [RFC8984], Section 4.4.6 DELEGATED-FROM Section 2.3.4
delegatedTo [RFC8984], Section 4.4.6 DELEGATED-TO Section 2.3.4
email [RFC8984], Section 4.4.6 EMAIL Section 2.3.4
expectReply [RFC8984], Section 4.4.6 RSVP Section 2.3.4
kind [RFC8984], Section 4.4.6 CUTYPE Section 2.3.4
invitedBy [RFC8984], Section 4.4.6 TBD
memberOf [RFC8984], Section 4.4.6 MEMBER Section 2.3.4
name [RFC8984], Section 4.2.5 CN Section 2.3.4
participationStatus [RFC8984], Section 4.4.6 PARTSTAT Section 2.3.4
progress [RFC8984], Section 5.2.5 PARTSTAT Section 2.3.4, and remarks below
roles [RFC8984], Section 4.4.6 ROLE, or PARTICIPANT-TYPE property of the PARTICIPANT component Section 2.3.4, Section 2.3.31, and remarks below
scheduleAgent [RFC8984], Section 4.4.6 SCHEDULE-AGENT Section 2.3.4
scheduleForceSend [RFC8984], Section 4.4.6 SCHEDULE-FORCE-SEND Section 2.3.4
scheduleSequence [RFC8984], Section 4.4.6 TBD
scheduleStatus [RFC8984], Section 4.4.6 SCHEDULE-STATUS Section 2.3.4
scheduleUpdated [RFC8984], Section 4.4.6 TBD
sendTo [RFC8984], Section 4.4.6 TBD
sentBy [RFC8984], Section 4.4.5 TBD

Remarks:

  • The "optional" role converts to the "OPT-PARTICIPANT" ROLE parameter value, the "chair" role to "CHAIR", "informational" to "NON-PARTICIPANT". The "attendee" role does convert to the ROLE parameter, it is implied by the ATTENDEE property. The "owner" role does not convert to the ROLE parameter, if the property value of the ATTENDEE is equal to the value of the ORGANIZER property in the same component. All other roles require a PARTICIPANT component and convert to the PARTICIPANT-TYPE property in that component.

  • The progress property converts to the PARTSTAT parameter as outlined in Table 18.

The following Participant properties convert to the PARTICIPANT or VRESOURCE component:

Table 37: Properties of the Participant object that convert to the PARTICIPANT or VRESOURCE component
Name Reference Property (or other) See
description [RFC8984], Section 4.2.2 DESCRIPTION Section 2.3.14
language [RFC8984], Section 4.4.6 TBD
links [RFC8984], Section 4.2.7 ATTACH, or other

Link object (Section 3.4)

locationId [RFC8984], Section 4.4.6 TBD
name [RFC8984], Section 4.2.5 NAME

Section 2.3.29

participationComment [RFC8984], Section 4.4.6 COMMENT

Section 2.3.9

percentComplete [RFC8984], Section 5.2.4 PERCENT-COMPLETE

Section 2.3.32

progressUpdated [RFC8984], Section 5.2.6 TBD
roles [RFC8984], Section 4.4.6 PARTICIPANT-TYPE Section 2.3.31

3.7. TimeZone

The TimeZone object [RFC8984] (Section 4.7.2) converts to a VTIMEZONE component (Section 2.2.6).

Its properties convert as follows:

Table 38: Properties of the TimeZone object
Name Reference Property (or other) See
aliases [RFC8984], Section 4.7.2 TZID-ALIAS-OF

Section 2.3.49

daylight [RFC8984], Section 4.7.2 DAYLIGHT (component)

TimeZoneRule below

standard [RFC8984], Section 4.7.2 STANDARD (component)

TimeZoneRule below

tzId [RFC8984], Section 4.7.2 TZID

Section 2.3.48

url [RFC8984], Section 4.7.2 TZURL

Section 2.3.54

validUntil [RFC8984], Section 4.7.2 TZUNTIL

Section 2.3.53

The TimeZoneRule object [RFC8984] (Section 4.7.2) converts to a DAYLIGHT or STANDARD component (Section 2.2.6).

Its properties convert as follows:

Table 39: Properties of the TimeZoneRule object
Name Reference Property (or other) See
comments [RFC8984], Section 4.7.2 COMMENT

Section 2.3.9

names [RFC8984], Section 4.7.2 TZNAME

Section 2.3.50

offsetFrom [RFC8984], Section 4.7.2 TZOFFSETFROM

Section 2.3.51

offsetTo [RFC8984], Section 4.7.2 TZOFFSETTO

Section 2.3.52

recurrenceOverrides [RFC8984], Section 4.3.5 RDATE

Section 2.3.35

recurrenceRules [RFC8984], Section 4.3.3 RRULE

Section 2.3.39

start [RFC8984], Section 4.7.2 DTSTART

Section 2.3.17

3.8. VirtualLocation

The VirtualLocation object [RFC8984] (Section 4.2.6) converts to a CONFERENCE property (Section 2.3.12).

The uri property converts to the CONFERENCE property value. Its other properties convert as follows:

Table 40: Properties of the VirtualLocation object
Name Reference Parameter (or other) See
description [RFC8984], Section 4.2.2 TBD
features [RFC8984], Section 4.2.6 FEATURE Section 2.3.12
name [RFC8984], Section 4.2.5 LABEL Section 2.3.12

4. Updates to iCalendar

5. Updates to JSCalendar

5.1. New Properties

5.1.1. completed

Name:
completed
Context:
Task
Type:
UTCDateTime (optional)
Description:
This is the date and time when the task was completed.

5.1.2. iCalComponent

Name:
iCalComponent
Context:
Any JSCalendar object
Type:
ICalComponent (optional)
Description

This contains information about an iCalendar component that got partially or fully converted to JSCalendar. It allows to preserve the name of the iCalendar component and some or all of its properties and subcomponents.

An ICalComponent object has the following properties:

@type: String (mandatory)
This specifies the type of this object. This MUST be ICalComponent.
name: String (mandatory)
This is the name of the iCalendar component in lowercase.
components: *[][] (optional)
This contains subcomponents of the iCalendar component. The value MUST be a list of iCalendar components formatted in jCal as defined in Section 3.3 of [RFC7265].
convertedProperties: String[ICalProperty] (optional)

This contains conversion-related information about the component's properties that got partially or fully converted to JSCalendar. Each key defines the path to a property of the JSCalendar object on which the iCalComponent property is set on. The value for each key contains information about the iCalendar property which converted to the object property located at that key (see Section 5.1.3).

The key MUST be a valid key of a PatchObject as defined in Section 1.4.9 of [RFC8984]. The key MUST NOT point into a nested property, unless there is no way to otherwise preserve the iCalendar property elements. For example, if a VEVENT contains an ATTENDEE property, then any iCalendar information about the ATTENDEE property MUST be set in the iCalProperty property of the converted Participant object (see Section 2.3.4). In contrast, information about a RDATE property contained in a VEVENT would be located by a key pointing into the recurrenceOverrides property of the Event object (see Section 2.3.35).

properties: *[][] (optional)
This contains properties of the iCalendar component. The value MUST be a list of iCalendar properties formatted in jCal as defined in Section 3.4 of [RFC7265].

5.1.3. iCalProperty

Name:
iCalProperty
Context:
Any JSCalendar object
Type:
ICalProperty (optional)
Description:

This contains conversion-related information about an iCalendar property that got partially or fully converted to JSCalendar. It allows to preserve the name of the iCalendar property and some or all of its parameters.

An ICalProperty object has the following properties:

@type: String (mandatory)
This specifies the type of this object. This MUST be ICalProperty.
name: String (mandatory)
This is the name of the iCalendar property in lowercase.
valueType: String (optional)
This is the name of the iCalendar property value type in lowercase.
parameters: String[String] (optional)
This contains parameters of the iCalendar property. The value MUST comply with iCalendar parameters formatted in jCal as defined in Section 3.5 of [RFC7265].

5.1.4. locations (Participant)

Name:
locations
Context:
Participant
Type:
Id[Location] (optional)
Description:
This represents locations associated with the participant. In contrast to the locationId property, this allows to associate multiple locations with the Participant object, and to express that a location just is relevant for this participant.

5.1.5. scheduleAgent (Event, Task)

Name:
scheduleAgent
Context:
Event, Task
Type:
String (optional, default "server")
Description:

This property represents the SCHEDULE-AGENT parameter [RFC6638] (Section 7.1) specified on an ORGANIZER property. In context of scheduling as outlined in [RFC6638], a scheduling client can set this property to indicate who is responsible for sending scheduling messages to the organizer in the replyTo property. The same values as for the scheduleAgent property of the Participant object [RFC8984] (Section 4.4.6) are allowed, the "none" value indicates that no scheduling message is to be sent to the organizer. The property MUST NOT be preserved in the JSCalendar object on the server or appear in a scheduling message. If this property is set, then the replyTo property MUST be set.

5.1.6. scheduleForceSend (Event, Task)

Name:
scheduleForceSend
Context:
Event, Task
Type:
Boolean (optional, default "false")
Description:

This property represents the SCHEDULE-FORCE-SEND parameter [RFC6638] (Section 7.2) specified on an ORGANIZER property. In context of scheduling as outlined in [RFC6638], a scheduling client can set this property to true to request that the server send a scheduling message to the organizer defined in the replyTo property, when it would not normally do so (e.g., if no significant change is made the object or the scheduleAgent is set to client). The property MUST NOT be preserved in the JSCalendar object on the server or appear in a scheduling message. If this property is set, then the replyTo property MUST be set.

5.1.7. scheduleStatus (Event, Task)

Name:
scheduleStatus
Context:
Event, Task
Type:
String[] (optional)
Description:

This property represents the SCHEDULE-STATUS parameter [RFC6638] (Section 7.3) specified on an ORGANIZER property. In context of scheduling as outlined in [RFC6638], the scheduling client or server can set this property to a list of status codes, returned from processing the most recent scheduling message sent to the organizer defined in the replyTo property. The status codes MUST be valid "statcode" values as defined in the ABNF in Section 3.8.8.3 of [RFC5545]. Servers MUST only add or change this property when they send a scheduling message to the organizer. Clients SHOULD NOT change or remove this property if it was provided by the server. Clients MAY add, change, or remove the property for participants where the client is handling the scheduling. This property MUST NOT be included in scheduling messages.

5.2. Updated Properties

6. IANA Considerations

7. References

7.1. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC2397]
Masinter, L., "The "data" URL scheme", RFC 2397, DOI 10.17487/RFC2397, , <https://www.rfc-editor.org/info/rfc2397>.
[RFC2445]
Dawson, F. and D. Stenerson, "Internet Calendaring and Scheduling Core Object Specification (iCalendar)", RFC 2445, DOI 10.17487/RFC2445, , <https://www.rfc-editor.org/info/rfc2445>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC5234]
Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, , <https://www.rfc-editor.org/info/rfc5234>.
[RFC5545]
Desruisseaux, B., Ed., "Internet Calendaring and Scheduling Core Object Specification (iCalendar)", RFC 5545, DOI 10.17487/RFC5545, , <https://www.rfc-editor.org/info/rfc5545>.
[RFC5546]
Daboo, C., Ed., "iCalendar Transport-Independent Interoperability Protocol (iTIP)", RFC 5546, DOI 10.17487/RFC5546, , <https://www.rfc-editor.org/info/rfc5546>.
[RFC5870]
Mayrhofer, A. and C. Spanring, "A Uniform Resource Identifier for Geographic Locations ('geo' URI)", RFC 5870, DOI 10.17487/RFC5870, , <https://www.rfc-editor.org/info/rfc5870>.
[RFC6638]
Daboo, C. and B. Desruisseaux, "Scheduling Extensions to CalDAV", RFC 6638, DOI 10.17487/RFC6638, , <https://www.rfc-editor.org/info/rfc6638>.
[RFC6838]
Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, , <https://www.rfc-editor.org/info/rfc6838>.
[RFC7265]
Kewisch, P., Daboo, C., and M. Douglass, "jCal: The JSON Format for iCalendar", RFC 7265, DOI 10.17487/RFC7265, , <https://www.rfc-editor.org/info/rfc7265>.
[RFC7529]
Daboo, C. and G. Yakushev, "Non-Gregorian Recurrence Rules in the Internet Calendaring and Scheduling Core Object Specification (iCalendar)", RFC 7529, DOI 10.17487/RFC7529, , <https://www.rfc-editor.org/info/rfc7529>.
[RFC7808]
Douglass, M. and C. Daboo, "Time Zone Data Distribution Service", RFC 7808, DOI 10.17487/RFC7808, , <https://www.rfc-editor.org/info/rfc7808>.
[RFC7953]
Daboo, C. and M. Douglass, "Calendar Availability", RFC 7953, DOI 10.17487/RFC7953, , <https://www.rfc-editor.org/info/rfc7953>.
[RFC7986]
Daboo, C., "New Properties for iCalendar", RFC 7986, DOI 10.17487/RFC7986, , <https://www.rfc-editor.org/info/rfc7986>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8288]
Nottingham, M., "Web Linking", RFC 8288, DOI 10.17487/RFC8288, , <https://www.rfc-editor.org/info/rfc8288>.
[RFC8607]
Daboo, C., Quillaud, A., and K. Murchison, Ed., "Calendaring Extensions to WebDAV (CalDAV): Managed Attachments", RFC 8607, DOI 10.17487/RFC8607, , <https://www.rfc-editor.org/info/rfc8607>.
[RFC8984]
Jenkins, N. and R. Stepanek, "JSCalendar: A JSON Representation of Calendar Data", RFC 8984, DOI 10.17487/RFC8984, , <https://www.rfc-editor.org/info/rfc8984>.
[RFC9073]
Douglass, M., "Event Publishing Extensions to iCalendar", RFC 9073, DOI 10.17487/RFC9073, , <https://www.rfc-editor.org/info/rfc9073>.
[RFC9074]
Daboo, C. and K. Murchison, Ed., ""VALARM" Extensions for iCalendar", RFC 9074, DOI 10.17487/RFC9074, , <https://www.rfc-editor.org/info/rfc9074>.
[RFC9253]
Douglass, M., "Support for iCalendar Relationships", RFC 9253, DOI 10.17487/RFC9253, , <https://www.rfc-editor.org/info/rfc9253>.
[TZDB]
"IANA Time Zone Database", <https://www.iana.org/time-zones>.

7.2. Informative References

[I-D.ietf-calext-ical-tasks]
Douglass, M. and A. Apthorp, "Task Extensions to iCalendar", Work in Progress, Internet-Draft, draft-ietf-calext-ical-tasks, , <https://datatracker.ietf.org/doc/draft-ietf-calext-ical-tasks>.
[I-D.ietf-jmap-calendars]
Jenkins, N.M. and M. Douglass, "JMAP for Calendars", Work in Progress, Internet-Draft, draft-ietf-jmap-calendars, , <https://datatracker.ietf.org/doc/draft-ietf-jmap-calendars/>.

Appendix A. Discrepancies between iCalendar and JSCalendar

This section highlights iCalendar and JSCalendar elements for which no conversion rule to a standard element is defined in this document. This is informational; implementations MAY convert these elements, for example by use of the special-purpose properties defined in this document, or some vendor-specific extension properties. Alternatively newer standards might define new standard elements and register them at IANA.

A.1. Unsupported iCalendar Elements

A.1.1. Components

The following components do not convert to a standard element in JSCalendar:

A.1.2. Properties by Component

The following components are defined to contain the listed properties. But these properties do not convert to a standard JSCalendar element.

A.1.2.1. PARTICIPANT
A.1.2.2. VALARM
A.1.2.3. VCALENDAR
A.1.2.4. VEVENT
A.1.2.5. VLOCATION
A.1.2.6. VRESOURCE
A.1.2.7. VTODO

A.1.3. Properties by Value Type

The following properties convert to a standard JSCalendar element for some other value type, but they do not for the listed value types.

A.1.3.2. RDATE
A.1.3.3. STRUCTURED-DATA

A.1.4. Parameters by Property

The following properties are defined to contain the listed parameters. But these parameters do not convert to a standard JSCalendar element.

A.1.4.1. ATTACH
A.1.4.2. ATTENDEE
A.1.4.3. CATEGORIES
A.1.4.4. COMMENT
A.1.4.5. CONFERENCE
A.1.4.6. DESCRIPTION
A.1.4.7. IMAGE
A.1.4.9. LOCATION
A.1.4.10. NAME
A.1.4.11. ORGANIZER
A.1.4.12. PARTICIPANT-TYPE
A.1.4.13. RECURRENCE-ID
A.1.4.15. REQUEST-STATUS
A.1.4.16. RESOURCES
A.1.4.17. STRUCTURED-DATA
A.1.4.18. STYLED-DESCRIPTION
A.1.4.19. SUMMARY
A.1.4.20. TZNAME

A.2. Unsupported JSCalendar Elements

Unfinished JSCalendar elements and conversion rules are marked with the term "TBD" in Section 3.

Author's Address

Robert Stepanek
Fastmail
PO Box 234
Collins St West
Melbourne VIC 8007
Australia