RFC 7265
jCal: The JSON Format for iCalendar
jCal: The JSON Format for iCalendar β¨
okay bestie, this is RFC 7265 π Its title is "jCal: The JSON Format for iCalendar," and it's an IETF Request for Comments (RFC) numbered 7265, dated May 2014. The three authors are P. Kewisch from Mozilla, C. Daboo from Apple, Inc., and M. Douglass from RPI. The ISSN is 2070-1721.
It's a Standards Track document. The title block doesn't mention any RFCs that it obsoletes or updates π¦
Abstract π
This spec defines "jCal," a JSON format for iCalendar data. iCalendar is a text format for capturing and exchanging the info you'd normally keep in a calendaring and scheduling app, like tasks and events. JSON is a lightweight, text-based, language-independent data interchange format that's super common in internet apps π
Status of This Memo π
This is an Internet Standards Track document.
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 5741.
Info about the current status of this document, any errata, and how to send feedback is at http://www.rfc-editor.org/info/rfc7265 π
Copyright Notice Β©
Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
Table of Contents π
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Conventions Used in This Document . . . . . . . . . . . . . . 4
3. Converting from iCalendar to jCal . . . . . . . . . . . . . . 4
3.1. Pre-processing . . . . . . . . . . . . . . . . . . . . . 4
3.2. iCalendar Stream and Objects (RFC 5545, Section 3.4) . . 5
3.3. Components (RFC 5545, Section 3.6) . . . . . . . . . . . 6
3.4. Properties (RFC 5545, Sections 3.7 and 3.8) . . . . . . . 6
3.4.1. Special Cases for Properties . . . . . . . . . . . . 8
3.4.1.1. GEO Property (RFC 5545, Section 3.8.1.6) . . . . 8
3.4.1.2. REQUEST-STATUS Property (RFC 5545, Section
3.8.8.3) . . . . . . . . . . . . . . . . . . . . 8
3.5. Parameters (RFC 5545, Section 3.2) . . . . . . . . . . . 9
3.5.1. VALUE Parameter . . . . . . . . . . . . . . . . . . . 10
3.5.2. Multi-value Parameters . . . . . . . . . . . . . . . 11
3.6. Values (RFC 5545, Section 3.3) . . . . . . . . . . . . . 11
3.6.1. Binary (RFC 5545, Section 3.3.1) . . . . . . . . . . 12
3.6.2. Boolean (RFC 5545, Section 3.3.2) . . . . . . . . . 12
3.6.3. Calendar User Address (RFC 5545, Section 3.3.3) . . . 12
3.6.4. Date (RFC 5545, Section 3.3.4) . . . . . . . . . . . 12
3.6.5. Date-Time (RFC 5545, Section 3.3.5) . . . . . . . . . 13
3.6.6. Duration (RFC 5545, Section 3.3.6) . . . . . . . . . 13
3.6.7. Float (RFC 5545, Section 3.3.7) . . . . . . . . . . . 14
3.6.8. Integer (RFC 5545, Section 3.3.8) . . . . . . . . . . 14
3.6.9. Period of Time (RFC 5545, Section 3.3.9) . . . . . . 14
3.6.10. Recurrence Rule (RFC 5545, Section 3.3.10) . . . . . 15
3.6.11. Text (RFC 5545, Section 3.3.11) . . . . . . . . . . . 16
3.6.12. Time (RFC 5545, Section 3.3.12) . . . . . . . . . . . 16
3.6.13. URI (RFC 5545, Section 3.3.13) . . . . . . . . . . . 17
3.6.14. UTC Offset (RFC 5545, Section 3.3.14) . . . . . . . . 17
3.7. Extensions . . . . . . . . . . . . . . . . . . . . . . . 17
4. Converting from jCal into iCalendar . . . . . . . . . . . . . 17
5. Handling Unrecognized Properties or Parameters . . . . . . . 18
5.1. Converting iCalendar into jCal . . . . . . . . . . . . . 18
5.2. Converting jCal into iCalendar . . . . . . . . . . . . . 19
5.3. Examples . . . . . . . . . . . . . . . . . . . . . . . . 19
6. Security Considerations . . . . . . . . . . . . . . . . . . . 20
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 21
7.1. UNKNOWN iCalendar Value Data Type . . . . . . . . . . . . 22
8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 23
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 23
9.1. Normative References . . . . . . . . . . . . . . . . . . 23
9.2. Informative References . . . . . . . . . . . . . . . . . 24
Appendix A. ABNF Schema . . . . . . . . . . . . . . . . . . . . 25
Appendix B. Examples . . . . . . . . . . . . . . . . . . . . . . 27
B.1. Example 1 . . . . . . . . . . . . . . . . . . . . . . . . 27
B.1.1. iCalendar Data . . . . . . . . . . . . . . . . . . . 27
B.1.2. jCal Data . . . . . . . . . . . . . . . . . . . . . . 27
B.2. Example 2 . . . . . . . . . . . . . . . . . . . . . . . . 28
B.2.1. iCalendar Data . . . . . . . . . . . . . . . . . . . 28
B.2.2. jCal Data . . . . . . . . . . . . . . . . . . . . . . 29
1. Introduction πΈ
okay so the iCalendar data format [RFC5545] is widely deployed π It's the standard way to swap calendaring and scheduling data. Tons of apps and services make and read calendar data, but iCalendar is a specialized format, so it needs its own parser and generator. JSON-based formats defined in [RFC7159] are the native format for JavaScript widgets and libraries, so it makes total sense to have a standard form of calendar data that's easier to work with than iCalendar π§
The purpose of this spec is to define "jCal," a JSON format for iCalendar data. jCal is a straightforward mapping from iCalendar into JSON, so iCalendar data can be converted to JSON and then back to iCalendar without losing any semantic meaning. Anyone who creates jCal calendar data under this spec will know their data can be converted to a valid iCalendar representation too β¨
The key design considerations are basically the same as the ones in [RFC6321], which means:
- Round-tripping (converting an iCalendar instance to jCal and back) will give the same semantic result as the starting point. For example, all components, properties, and property parameters are guaranteed to be preserved. π
- Ordering of elements and case of property and parameter names will not necessarily be preserved.
- The iCalendar data semantics are to be preserved, which lets a simple consumer easily browse the data in jCal. A full understanding of iCalendar is still required in order to modify and/or fully comprehend the calendar data.
- Extensions to the underlying iCalendar specification must not lead to requiring an update to jCal. π«Ά
2. Conventions Used in This Document π
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. The underlying format used for jCal is JSON, so the terms "object" and "array" as well as the four primitive types (strings, numbers, booleans, and null) are to be interpreted as described in Section 1 of [RFC7159] π
Some examples in this document contain "partial" JSON documents for illustration. In these examples, three periods ... are used to show a part of the document that has been removed for compactness.
3. Converting from iCalendar to jCal π¦
This section describes how iCalendar data is converted to jCal using a simple mapping between the iCalendar data model and JSON elements. Aside from the formal description in this section, an informative ABNF is specified in Appendix A.
In [RFC5545], an iCalendar object comprises a set of "components," "properties," "parameters," and "values." The top level of iCalendar data typically contains a stream of iCalendar objects, and each one can be considered a "component." A "component" can contain other "components" or "properties." A "property" has a "value" and a set of zero or more "parameters." Each of these entities has a representation in jCal, defined in the following sections. The representation of an iCalendar object in JSON will be called a "jCal object" throughout this document π§©
3.1. Pre-processing π§Ή
iCalendar uses a line-folding mechanism to limit lines of data to a maximum line length (typically 75 octets). This keeps data integrity as strong as possible while it's transported by various means (e.g., email). See Section 3.1 of [RFC5545] π¬
iCalendar data uses an "escape" character sequence for text values and property parameter values. See Sections 3.1 and 3.3 of [RFC5545] as well as [RFC6868].
There is a subtle difference in how numbers are represented in JSON and iCalendar. In iCalendar, a number may have leading zeros as well as a leading plus sign, but that is not the case in JSON. Numbers should be represented in whatever way is needed for the underlying format π’
When converting from iCalendar to jCal: First, iCalendar lines MUST be unfolded. Afterwards, any iCalendar escaping MUST be unescaped. Finally, JSON escaping, as described in Section 7 of [RFC7159], MUST be applied. The reverse order applies when converting from jCal to iCalendar, which is further described in Section 4 π
iCalendar uses a base64 encoding for binary data. However, it doesn't restrict the encoding from being applied to non-binary value types. So, the following rules apply when processing a property with the "ENCODING" property parameter set to "BASE64":
- If the property value type is "BINARY", the base64 encoding MUST be preserved.
- If the value type is not "BINARY", the
ENCODINGproperty parameter MUST be removed, and the value MUST be base64 decoded.
When base64 encoding is used, it MUST conform to Section 4 of [RFC4648], which is the base64 method used in [RFC5545] π
One key difference in how values are formatted in iCalendar and jCal is that jCal uses date/time values aligned with the extended format of [ISO.8601.2004], which is more commonly used in internet applications that work with the JSON format. The sections of this document that describe the various date and time formats contain more information on the use of the complete representation, reduced accuracy, or truncated representation πβ¨
3.2. iCalendar Stream and Objects (RFC 5545, Section 3.4) π
okay so at the very top of the iCalendar object model there's this thing called an "iCalendar stream" π. A stream can hold multiple "iCalendar objects". Most of the time you're only sending one iCalendar object, so jCal doesn't define a matching "stream" thing at all π«Ά. If you want to send several jCal objects together, you just use a plain JSON array β¨.
Example:
["vcalendar",
[ /* Add jCal properties in place of this comment */ ],
[ /* Add jCal components in place of this comment */ ]
]
3.3. Components (RFC 5545, Section 3.6) π§
every iCalendar component is wrapped in "BEGIN" and "END", and in jCal it turns into a fixed-length array with three fields that have a specific structure π :
- A string with the name of the iCalendar component, but in lowercase.
- An array of jCal properties as described in Section 3.4.
- An array of jCal components, representing the sub-components of the component in question.
This same mapping works for the top-level iCalendar objects and for sub-components too, so it's giving consistency π. The mapping is valid for current iCalendar components and for any new ones that get added in the future, and the conversion is done the same way every time π.
ngl, the grouping of properties and sub-components doesn't keep the original order from the iCalendar data π. But the semantics of the component are still preserved, so the meaning is safe even if the order got shuffled πΈ.
Example:
["vevent",
[ /* Add jCal properties in place of this comment */ ],
[ /* Add jCal components in place of this comment */ ]
]
3.4. Properties (RFC 5545, Sections 3.7 and 3.8) π¦
iCalendar properties are handled in one consistent way in jCal, whether they belong to the "VCALENDAR" object or to a component β¨.
In jCal, each individual iCalendar property MUST be represented by an array with three fixed elements, followed by one or more additional elements. Which ones depends on whether the property is multi-valued, as described in Section 3.1.2 of [RFC5545] π.
The array has these three fixed elements:
- The name of the property, as a lowercase string. The iCalendar format says property names are case insensitive and recommends that they be rendered in uppercase. In jCal, they MUST be in lowercase π.
- An object containing the parameters as described in Section 3.5. If the property has no parameters, an empty object is used to represent that π«§.
- The type identifier string of the value, in lowercase. Because of the special casing of certain properties described in Section 3.4.1, it's really important that parsers check both the type identifier and the value data type. Don't just rely on assumptions based on the property name π ββοΈ.
The rest of the array holds one or more values of the property. Single-valued properties have exactly four elements. Multi-valued properties, as described in Section 3.1.2 of [RFC5545], get one element per value, and there can be any number of additional elements π.
In this example, "categories" is multi-valued with two values, and "summary" is single-valued π :
Example:
["vevent",
[
["summary", {}, "text", "Meeting with Fred"],
["categories", {}, "text", "Meetings", "Work"]
...
],
[ /* sub-components */ ]
]
3.4.1. Special Cases for Properties π
this section covers some properties that get special handling when converting to jCal π.
3.4.1.1. GEO Property (RFC 5545, Section 3.8.1.6) π
in iCalendar, the "GEO" property value is a semicolon-separated list of two "FLOAT" values. The first one is latitude and the second one is longitude π.
in jCal, the "geo" value is an array of two values. The first value is the latitude, and the second value is the longitude β¨.
When you convert from jCal to iCalendar, be careful to use a semicolon as the separator between the two values, since [RFC5545] requires it π«Ά.
When converting from jCal to iCalendar, the two values MUST be converted using a semicolon as the separator character. π€
Example
["vevent",
[
["geo", {}, "float", [ 37.386013, -122.082932 ] ]
...
],
...
]
3.4.1.2. REQUEST-STATUS Property (RFC 5545, Section 3.8.8.3) π¨
in iCalendar, "REQUEST-STATUS" is a semicolon-separated list of two or three "TEXT" values. The first is a code, the second is a description, and the third is any additional data π§Ύ.
in jCal, "request-status" is an array with two or three values. The first element is the code, the second is the description, and the third is the additional data. Each value is a string. If there's no additional data in the iCalendar value, the last element of the array SHOULD NOT be present π.
When converting from jCal to iCalendar, the two or three values MUST be converted using a semicolon as the separator character π₯.
iCalendar Example:
BEGIN:VEVENT
...
REQUEST-STATUS:2.0;Success
REQUEST-STATUS:3.7;Invalid calendar user;ATTENDEE:
mailto:jsmith@example.com
...
END:VEVENT
jCal Example:
["vevent":
[
["request-status", {}, "text", ["2.0", "Success"] ],
["request-status", {}, "text",
[
"3.7",
"Invalid calendar user",
"ATTENDEE:mailto:jsmith@example.org"
]
],
...
],
...
]
3.5. Parameters (RFC 5545, Section 3.2) π
property parameters are represented as a JSON object, where each key-value pair is an iCalendar parameter name and its value π. The parameter name MUST be in lowercase, but the original case of the parameter value MUST be preserved π«Ά. For example, the "PARTSTAT" parameter becomes the "partstat" key in jCal. Any new iCalendar parameters added in the future get converted the same way πΈ.
Example:
["vevent":
[
["attendee",
{
"partstat": "ACCEPTED",
"rsvp": "TRUE",
"role": "REQ-PARTICIPANT"
},
"cal-address",
"mailto:jsmith@example.org"
],
["summary", {}, "text", "Meeting"],
...
],
...
]
3.5.1. VALUE Parameter β¨
iCalendar defines a "VALUE" property parameter (Section 3.2.20 of [RFC5545]) π§. This parameter MUST NOT be added to the parameters object. Instead, the value type gets signaled through the type identifier in the third element of the property's array π«§. When converting a property from iCalendar to jCal, the value type gets figured out like this:
- If the property has a "VALUE" parameter, that parameter's value is used as the value type.
- If the property has no "VALUE" parameter but has a default value type, the default value type is used.
- If the property has no "VALUE" parameter and no default value type, "unknown" is used.
Converting from jCal into iCalendar goes like this:
- If the property's value type is "unknown", no "VALUE" parameter is included.
- If the property's value type is the default type for that property, no "VALUE" parameter is included.
- Otherwise, a "VALUE" parameter is included, and the value type is used as the parameter value.
See Section 5 for info on handling unknown value types π.
3.5.2. Multi-value Parameters π
in [RFC5545], some parameters allow a COMMA-separated list of values. To make processing easier in jCal, the value of these parameters MUST be represented in an array containing the separated values π . The array elements MUST be string values. Single-value parameters can be represented with either a single string value or an array with one string element π¦. A jCal parser MUST be able to understand both value data types π«Ά. Examples are the iCalendar "DELEGATED-FROM" and "DELEGATED-TO" parameters, and more of these may be added in extensions β¨.
The iCalendar specification requires DQUOTE characters around a parameter value if it contains a colon, a semicolon, or a comma. Those extra DQUOTE characters aren't part of the actual parameter value, so they aren't included when the parameter gets converted to jCal π.
Example 1:
["attendee",
{
"delegated-to": ["mailto:jdoe@example.org",
"mailto:jqpublic@example.org"]
},
"cal-address",
"mailto:jsmith@example.org"
]
Example 2:
["attendee",
{
"delegated-to": "mailto:jdoe@example.org"
},
"cal-address",
"mailto:jsmith@example.org"
]
3.6. Values (RFC 5545, Section 3.3) π
the next subsections explain how iCalendar property value data types are represented in jCal π§. The data types are defined in the subsections of [RFC5545], Section 3.3 πΈ.
3.6.1. Binary (RFC 5545, Section 3.3.1) π
Description: iCalendar "BINARY" property values are represented by a property with the type identifier "binary". The value element is a JSON string, encoded with base64 encoding as specified in Section 4 of [RFC4648] π«§.
Example:
["attach", {}, "binary", "SGVsbG8gV29ybGQh"]
3.6.2. Boolean (RFC 5545, Section 3.3.2) β
Description: iCalendar "BOOLEAN" property values are represented by a property with the type identifier "boolean". The value is a JSON boolean value π.
Example:
["x-non-smoking", {}, "boolean", true]
3.6.3. Calendar User Address (RFC 5545, Section 3.3.3) π¬
Description: iCalendar "CAL-ADDRESS" property values are represented by a property with the type identifier "cal-address". The value is a JSON string with the URI as described in [RFC3986] π.
Example:
["attendee", {}, "cal-address", "mailto:kewisch@example.com"]
3.6.4. Date (RFC 5545, Section 3.3.4) π
Description: iCalendar "DATE" property values are represented by a property with the type identifier "date". The value elements are JSON strings with the same date value specified by [RFC5545], but written in the extended format of the complete representation from [ISO.8601.2004], Section 4.1.2.2 ποΈ. Other variations, like representations with reduced accuracy, MUST NOT be used π«.
ABNF Schema:
; year, month, and day rules are
; defined in [ISO.8601.2004], Section 2.2.
date = year "-" month "-" day ;YYYY-MM-DD
Example:
["dtstart", {}, "date", "2011-05-17"]
3.6.5. Date-Time (RFC 5545, Section 3.3.5) π°οΈ
Description: okay so iCalendar DATE-TIME values get the type identifier "date-time" π The value elements are JSON strings holding the same date value that [RFC5545] talks about, but written in the extended format of the complete representation from [ISO.8601.2004], Section 4.3.2 β¨ Other variations, like representation with reduced accuracy, MUST NOT be used π
ββοΈ The same restrictions apply to leap seconds and time zone offsets as specified in [RFC5545], Section 3.3.5 π«Ά
ABNF Schema:
; year, month, day, hour, minute, and second rules are
; defined in [ISO.8601.2004], Section 2.2.
; The zone identifier is described in [ISO.8601.2004], Section 4.3.2.
date-complete = year "-" month "-" day ;YYYY-MM-DD
time-complete = hour ":" minute ":" second [zone] ; HH:MM:SS
datetime = date-complete "T" time-complete
Examples:
["dtstart", {}, "date-time", "2012-10-17T12:00:00"],
["dtstamp", {}, "date-time", "2012-10-17T12:00:00Z"],
["dtend",
{ "tzid": "Europe/Berlin" },
"date-time",
"2011-10-17T13:00:00"
]
3.6.6. Duration (RFC 5545, Section 3.3.6) β³
Description: iCalendar DURATION values get the type identifier "duration" π The value elements are JSON strings with the same duration value specified by [RFC5545] π
Example:
["duration", {}, "duration", "P1D"]
3.6.7. Float (RFC 5545, Section 3.3.7) π¦
Description: iCalendar FLOAT values get the type identifier "float" πΈ The value elements are plain JSON primitive number values π’
Example:
["x-grade", {}, "float", 1.3]
3.6.8. Integer (RFC 5545, Section 3.3.8) π
Description: vCard "INTEGER" property values get the type identifier "integer" π§ The value elements are JSON primitive number values that MUST resolve to an integer value in the range specified in [RFC5545], Section 3.3.8 π₯ So a fractional and/or exponential part is only allowed under limited circumstances π
Examples:
["percent-complete", {}, "integer", 42]
3.6.9. Period of Time (RFC 5545, Section 3.3.9) π
Description: iCalendar PERIOD values are represented by a jCal property with the type identifier "period" π The value element is an array of JSON strings. The first element is the start of the period, and the second is the end of the period β¨ As in [RFC5545], the start is always formatted as a date-time value, and the end MUST be either a date-time or a duration value π Any date, date-time, or duration values inside the period value MUST be formatted following the rules for date, date-time, or duration values specified in this document π«Ά
Example:
["freebusy",
{ "fbtype": "FREE" },
"period",
["1997-03-08T16:00:00Z", "P1D"]
]
3.6.10. Recurrence Rule (RFC 5545, Section 3.3.10) π
Description: iCalendar RECUR values get the type identifier "recur" π The value elements are objects describing the structured data that [RFC5545] defines π§ Each rule part is described by a combination of key and value. The key is the name of the rule part and MUST be converted to lowercase π€ The value of the rule part MUST be mapped by these rules:
- The value of the "freq" and "wkst" rule parts MUST be a string as specified in [RFC5545], with case preserved π
- The value of the "until" rule part MUST be a date or date-time value, formatted following the rules for date or date-time specified in this document π
- The "count" and "interval" rule parts MUST be specified as a single JSON number value π’
- The following rule parts can have one or more numeric values: "bysecond", "byminute", "byhour", "bymonthday", "byyearday", "byweekno", "bymonth", and "bysetpos" π If a rule part has multiple values, an array of numbers MUST be used for that rule part πͺ Single-valued rule parts can be written as either a single number value, with the array left out completely, or as an array with one number element. A jCal parser MUST be able to understand both data types π«Ά
- Similarly, the "byday" rule part can have one or more string values ποΈ If it has multiple values, an array of strings MUST be used. As before, a single-valued rule part can be written as either a single string value or an array with one string element, and a jCal parser MUST be able to understand both of those π
Example 1:
["rrule",
{},
"recur",
{
"freq": "YEARLY",
"count": 5,
"byday": [ "-1SU", "2MO" ],
"bymonth": 10
}
]
Example 2:
["rrule",
{},
"recur",
{
"freq": "MONTHLY",
"interval": 2,
"bymonthday": [ 1, 15, -1 ],
"until": "2013-10-01"
}
]
3.6.11. Text (RFC 5545, Section 3.3.11) π
Description: iCalendar TEXT values get the type identifier "text" π The value elements are JSON strings π
Example:
["comment", {}, "text", "hello, world"]
3.6.12. Time (RFC 5545, Section 3.3.12) β°
Description: iCalendar TIME values get the type identifier "time" πΈ The value elements are JSON strings with the same time value that [RFC5545] specifies, but written in the extended format of the complete representation from [ISO.8601.2004], Section 4.2.2.2 β¨ Other variations, like representation with reduced accuracy, MUST NOT be used π
ββοΈ The same restrictions apply to leap seconds, time fractions, and time zone offsets as specified in [RFC5545], Section 3.3.12 π
ABNF Schema:
; hour, minute, and second rules are
; defined in [ISO.8601.2004], Section 2.2.
; The zone identifier is described in [ISO.8601.2004], Section 4.3.2.
time-complete = hour ":" minute ":" second [zone] ; HH:MM:SS
Example:
["x-time-local", {}, "time", "12:30:00"],
["x-time-utc", {}, "time", "12:30:00Z"],
["x-time-offset", { "tzid": "Europe/Berlin" }, "time", "12:30:00"]
3.6.13. URI (RFC 5545, Section 3.3.13) π
Description: iCalendar URI values get the type identifier "uri" π The value elements are JSON strings representing the URI π
Example:
["tzurl", {}, "uri", "http://example.org/tz/Europe-Berlin.ics"]
3.6.14. UTC Offset (RFC 5545, Section 3.3.14) π
Description: iCalendar UTC-OFFSET values get the type identifier "utc-offset" π¦ The value elements are JSON strings with the same UTC offset value that [RFC5545] specifies, with one twist: the hour and minute parts are separated by a ":" character, to match the [ISO.8601.2004] time zone offset in extended format π«Ά
Example:
["tzoffsetfrom", {}, "utc-offset", "-05:00"],
["tzoffsetto", {}, "utc-offset", "+12:45"]
3.7. Extensions π§©
iCalendar extension properties and property parameters (the ones with an "X-" prefix in their name) are handled exactly like everything else π The property becomes an array, and the property parameter becomes an object. The name uses the same name as the iCalendar extension, just in lowercase. For example, the "X-FOO" property in iCalendar turns into the "x-foo" jCal property β¨ See Section 5 for how to handle default values for unrecognized extension properties or property parameters πΈ
4. Converting from jCal into iCalendar π
Converting jCal to iCalendar is basically the process from Section 3 played in reverse πͺ This section covers a few extra requirements for the conversion π
When converting component, property, and property parameter names, the names SHOULD be converted to uppercase. Even though iCalendar names are case insensitive, the common practice is to keep them all uppercase, following the actual definitions in [RFC5545] π
During conversion, JSON escaping MUST be unescaped. Afterwards, iCalendar escaping, as defined by [RFC5545] and [RFC6868], MUST be applied. Finally, long lines SHOULD be folded as described in [RFC5545], Section 3.1 π
Non-binary value types MUST NOT be base64 encoded π ββοΈ
When converting to iCalendar, the VALUE parameter MUST be added to properties whose default value type is unknown, but that do not have the jCal type identifier "unknown". The VALUE parameter MAY be omitted for properties using the default value type. The VALUE parameter MUST be omitted for properties that have the jCal type identifier "unknown" π«Ά
5. Handling Unrecognized Properties or Parameters π΅οΈββοΈ
In iCalendar, properties can have one or more value types as specified by their definition, and one of those values is defined as the default π― When a property uses its default value type, the "VALUE" property parameter doesn't need to be specified on the property. For example, the default value type for DTSTART is DATE-TIME, so VALUE=DATE-TIME doesn't need to be set as a property parameter. However, DTSTART also allows a DATE value, and if that's used, VALUE=DATE has to be set as a property parameter π
When new properties are defined or "X-" properties are used, an iCalendar to jCal converter might not recognize them and won't know what the appropriate default value types are. Even so, they still need to preserve the values π₯Ί A similar issue comes up with unrecognized property parameters π
In jCal, a new "unknown" property value type is introduced π Its purpose is to let unknown property values survive round-tripping between jCal and iCalendar. To avoid collisions, this specification reserves the UNKNOWN property value type in iCalendar. It MUST NOT be used in any iCalendar as specified by [RFC5545], or in any extensions to it. So the type is registered to the iCalendar Value Data Types registry in Section 7.1 π
5.1. Converting iCalendar into jCal πͺ
Any property that doesn't include a "VALUE" property parameter, and whose default value type is not known, MUST be converted to a primitive JSON string. The content of that string is the unprocessed value text. Also, the value type MUST be set to "unknown" π±
It's critical to use the type "unknown" when the default type isn't known, so please don't skip this π If this requirement is ignored and, for example, "text" is used instead, additional escaping may happen, and that breaks round-tripping of values π
Any unrecognized property parameter MUST be converted to a string value, with its content set to the property parameter value text, and treated as if it were a "TEXT" value π
5.2. Converting jCal into iCalendar π
In jCal, the value type is always explicitly specified. It gets converted to iCalendar using the iCalendar VALUE parameter, except in the following two cases:
- If the value type specified in jCal matches the default value type in iCalendar, the VALUE parameter MAY be omitted πΈ
- If the value type specified in jCal is set to "unknown", the VALUE parameter MUST NOT be specified. The value MUST be taken over into iCalendar without any processing π«Ά
5.3. Examples β¨
okay so here are four examples to make this click π first one is an unrecognized iCalendar property that uses a "DATE-TIME" value as its default, plus its jCal version π
iCalendar:
X-COMPLAINT-DEADLINE:20110512T120000Z
jCal:
["x-complaint-deadline", {}, "unknown", "20110512T120000Z"]
next is how to cope when the parser couldn't figure out the type π§ notice how the "unknown" value type doesn't get added to the iCalendar data, and escaping (apart from standard JSON string escaping) isn't processed π
jCal:
["x-coffee-data", {}, "unknown", "Stenophylla;Guinea\\,Africa"]
iCalendar:
X-COFFEE-DATA:Stenophylla;Guinea\,Africa
then we've got a jCal property where the iCalendar side uses an "INTEGER" value as its default, and the iCalendar version of it π
jCal:
["percent-complete", {}, "integer", 95]
iCalendar:
PERCENT-COMPLETE:95
and the last one is my fave π an unrecognized iCalendar property parameter (default value "FLOAT") sitting on a recognized property, with the jCal version of both the property and the parameter π
iCalendar:
DTSTART;X-SLACK=30.3;VALUE=DATE:20110512
jCal:
["dtstart", { "x-slack": "30.3" }, "date", "2011-05-12"]
6. Security Considerations π₯
okay bestie, this part is serious, so read it slowly π«Ά this spec is all about "translating" iCalendar data between two formats, the original text one and JSON. it's a one-to-one mapping, so all the semantic stuff (properties, parameters, and values) survives the trip π¦ it does not change what the underlying data means, and it doesn't add or remove any security considerations that already apply to that data π
JSON comes with its own inherent security risks, which are covered in Section 12 of [RFC7159] π JSON is considered a safe subset of JavaScript, sure, but a flaw in the parser handling JSON could still be a threat, and that doesn't happen with conventional iCalendar data. so be aware of that π
so a parser for JSON data used for jCal should be one that's aware of the security implications πΈ using JavaScript's eval() function is considered an unacceptable security risk, as described in Section 12 of [RFC7159], so no eval() energy here π« a native parser with full awareness of the JSON format should be preferred β¨
also, this new format is expected to get iCalendar data more widely disseminated, like into web applications and not just dedicated calendaring apps π
in every case, application developers have to follow the semantics of iCalendar as defined by [RFC5545] and any associated extensions, and all of the security considerations in Section 7 of [RFC5545], or in any associated extensions, still apply π
7. IANA Considerations π
this document defines a MIME media type for iCalendar in JSON data, and this media type SHOULD be used for transferring calendaring data in JSON π here's the registration, verbatim:
Type name: application
Subtype name: calendar+json
Required parameters: none
Optional parameters: "method", "component", and "optinfo" as defined
for the text/calendar media type in [RFC5545], Section 8.1.
Encoding considerations: Same as encoding considerations of
application/json as specified in [RFC7159], Section 11.
Security considerations: See Section 6.
Interoperability considerations: This media type provides an
alternative format for iCalendar data based on JSON.
Published specification: This specification.
Applications that use this media type: Applications that currently
make use of the text/calendar media type can use this as an
alternative. Similarly, applications that use the application/
json media type to transfer calendaring data can use this to
further specify the content.
Fragment identifier considerations: N/A
Additional information:
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person & email address to contact for further information:
calsify@ietf.org
Intended usage: COMMON
Restrictions on usage: There are no restrictions on where this media
type can be used.
Author: See the "Authors' Addresses" section of this document.
Change controller: IETF
7.1. UNKNOWN iCalendar Value Data Type π¦
IANA added this entry to the iCalendar Data Types registry, and it's giving reserved vibes π
Value name: UNKNOWN
Purpose: To allow preserving property values whose default value
type is not known during round-tripping between jCal and
iCalendar.
Format definition: N/A
Description: The UNKNOWN value data type is reserved for the
exclusive use of the jCal format. Its use is described in
Section 5 of this document.
Example: As this registration serves as a reservation of the UNKNOWN
type so that it is not used in iCalendar, there is no applicable
iCalendar example. Examples of its usage in jCal can be found in
this document.
IANA set the "Status" column for this entry to "Reserved - Do not use", and the "Reference" column points to Section 5 of this document π ββοΈ
8. Acknowledgments π«Ά
the authors want to shout out these amazing people for their valuable contributions: William Gill, Erwin Rehme, Dave Thewlis, Simon Perreault, Michael Angstadt, Peter Saint-Andre, Bert Greevenbosch, and Javier Godoy π and this spec started out as work from the XML-JSON technical committee of the Calendaring and Scheduling Consortium β¨
9. References π
9.1. Normative References
Here are the normative ones, the must-reads π
- [ISO.8601.2004]: International Organization for Standardization, "Data elements and interchange formats -- Information interchange -- Representation of dates and times", ISO 8601, December 2004,
http://www.iso.org/iso/catalogue_detail?csnumber=40874. - [RFC2119]: Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [RFC3986]: Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, January 2005.
- [RFC4648]: Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, October 2006.
- [RFC5234]: Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.
- [RFC5545]: Desruisseaux, B., "Internet Calendaring and Scheduling Core Object Specification (iCalendar)", RFC 5545, September 2009.
- [RFC6321]: Daboo, C., Douglass, M., and S. Lees, "xCal: The XML Format for iCalendar", RFC 6321, August 2011.
- [RFC6868]: Daboo, C., "Parameter Value Encoding in iCalendar and vCard", RFC 6868, February 2013.
- [RFC7159]: Bray, T., "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 7159, March 2014.
9.2. Informative References
And these ones are just for extra context π
- [calconnect-artifacts]: The Calendaring and Scheduling Consortium, "Code Artifacts and Schemas",
http://www.calconnect.org/artifacts.shtml.
Appendix A. ABNF Schema π§©
okay so this is an ABNF schema as per [RFC5234] for iCalendar in JSON π¦ any ABNF symbols that aren't described here come from [RFC7159] π the schema is non-normative, so it's just there for reference π
heads up, there are extra semantic restrictions, especially on which properties and sub-components each component can have β οΈ you'll find those details in this document and in [RFC5545] π«Ά
more schemas might be floating around on the Internet at [calconnect-artifacts] β¨
; A jCal object is a component with the component-name "vcalendar".
; Restrictions to which properties and sub-components may be
; specified are to be taken from [RFC5545].
jcalobject = component
; A jCal component consists of the name string, properties array, and
; component array
component = begin-array
DQUOTE component-name DQUOTE value-separator
properties-array value-separator
components-array
end-array
components-array = begin-array
[ component *(value-separator component) ]
end-array
; A jCal property consists of the name string, parameters object,
; type string, and one or more values as specified in this document.
property = begin-array
DQUOTE property-name DQUOTE value-separator
params-object value-separator
DQUOTE type-name DQUOTE
property-value *(value-separator property-value)
end-array
properties-array = begin-array
[ property *(value-separator property) ]
end-array
; Property values depend on the type-name. Aside from the value types
; mentioned here, extensions may make use of other JSON value types.
; The non-terminal symbol structured-prop-value covers the special
; cases for GEO and REQUEST-STATUS.
property-value = simple-prop-value / structured-prop-value
simple-prop-value = string / number / true / false
structured-prop-value =
begin-array
[ structured-element *(value-separator structured-element) ]
end-array
structured-element = simple-prop-value
; The jCal params-object is a JSON object that follows the semantic
; guidelines described in this document.
params-object = begin-object
[ params-member *(value-separator params-member) ]
end-object
params-member = DQUOTE param-name DQUOTE name-separator param-value
param-value = string / param-multi
param-multi = begin-array
[ string *(value-separator string) ]
end-array
; The type MUST be a valid type as described by this document. New
; value types can be added by extensions.
type-name = "binary" / "boolean" / "cal-address" / "date" /
"date-time" / "duration" / "float" / "integer" /
"period" / "recur" / "text" / "time" / "uri" /
"utc-offset" / x-type
; Component, property, parameter, and type names MUST be lowercase.
; Additional semantic restrictions apply as described by this
; document and [RFC5545].
component-name = lowercase-name
property-name = lowercase-name
param-name = lowercase-name
x-type = lowercase-name
lowercase-name = 1*(%x61-7A / DIGIT / "-")
; The following rules are defined in [RFC7159], as mentioned above:
; begin-array / end-array
; begin-object / end-object
; name-separator / value-separator
; string / number / true / false
Appendix B. Examples πΈ
this part has two examples of iCalendar objects with their jCal representation π
B.1. Example 1 π
B.1.1. iCalendar Data
BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:-//Example Inc.//Example Calendar//EN
VERSION:2.0
BEGIN:VEVENT
DTSTAMP:20080205T191224Z
DTSTART:20081006
SUMMARY:Planning meeting
UID:4088E990AD89CB3DBB484909
END:VEVENT
END:VCALENDAR
B.1.2. jCal Data π
Okay so this is the same calendar as B.1.1, just in jCal form π It's a JSON array, so each property is [name, params, type, value], and the vevent gets its own properties plus an empty list of nested components π§
["vcalendar",
[
["calscale", {}, "text", "GREGORIAN"],
["prodid", {}, "text", "-//Example Inc.//Example Calendar//EN"],
["version", {}, "text", "2.0"]
],
[
["vevent",
[
["dtstamp", {}, "date-time", "2008-02-05T19:12:24Z"],
["dtstart", {}, "date", "2008-10-06"],
["summary", {}, "text", "Planning meeting"],
["uid", {}, "text", "4088E990AD89CB3DBB484909"]
],
[]
]
]
]
B.2. Example 2 π¦
Now we're going full main character π This one has a whole timezone, a recurring event, and an exception, and it's giving everything you could want in a calendar π
B.2.1. iCalendar Data π
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//Example Client//EN
BEGIN:VTIMEZONE
LAST-MODIFIED:20040110T032845Z
TZID:US/Eastern
BEGIN:DAYLIGHT
DTSTART:20000404T020000
RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
TZNAME:EDT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
END:DAYLIGHT
BEGIN:STANDARD
DTSTART:20001026T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZNAME:EST
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTAMP:20060206T001121Z
DTSTART;TZID=US/Eastern:20060102T120000
DURATION:PT1H
RRULE:FREQ=DAILY;COUNT=5
RDATE;TZID=US/Eastern;VALUE=PERIOD:20060102T150000/PT2H
SUMMARY:Event #2
DESCRIPTION:We are having a meeting all this week at 12 pm fo
r one hour\, with an additional meeting on the first day 2 h
ours long.\nPlease bring your own lunch for the 12 pm meetin
gs.
UID:00959BC664CA650E933C892C@example.com
END:VEVENT
BEGIN:VEVENT
DTSTAMP:20060206T001121Z
DTSTART;TZID=US/Eastern:20060104T140000
DURATION:PT1H
RECURRENCE-ID;TZID=US/Eastern:20060104T120000
SUMMARY:Event #2 bis
UID:00959BC664CA650E933C892C@example.com
END:VEVENT
END:VCALENDAR
B.2.2. jCal Data β¨
Same story in jCal, and the timezone rules get their own nested components π The description is split up with string concatenation just so the lines stay short. Note that comments and string concatenation are not allowed in plain JSON π
["vcalendar",
[
["prodid", {}, "text", "-//Example Corp.//Example Client//EN"],
["version", {}, "text", "2.0"]
],
[
["vtimezone",
[
["last-modified", {}, "date-time", "2004-01-10T03:28:45Z"],
["tzid", {}, "text", "US/Eastern"]
],
[
["daylight",
[
["dtstart", {}, "date-time", "2000-04-04T02:00:00"],
["rrule",
{},
"recur",
{
"freq": "YEARLY",
"byday": "1SU",
"bymonth": 4
}
],
["tzname", {}, "text", "EDT"],
["tzoffsetfrom", {}, "utc-offset", "-05:00"],
["tzoffsetto", {}, "utc-offset", "-04:00"]
],
[]
],
["standard",
[
["dtstart", {}, "date-time", "2000-10-26T02:00:00"],
["rrule",
{},
"recur",
{
"freq": "YEARLY",
"byday": "1SU",
"bymonth": 10
}
],
["tzname", {}, "text", "EST"],
["tzoffsetfrom", {}, "utc-offset", "-04:00"],
["tzoffsetto", {}, "utc-offset", "-05:00"]
],
[]
]
]
]
],
["vevent",
[
["dtstamp", {}, "date-time", "2006-02-06T00:11:21Z"],
["dtstart",
{ "tzid": "US/Eastern" },
"date-time",
"2006-01-02T12:00:00"
],
["duration", {}, "duration", "PT1H"],
["rrule", {}, "recur", { "freq": "DAILY", "count": 5 } ],
["rdate",
{ "tzid": "US/Eastern" },
"period",
"2006-01-02T15:00:00/PT2H"
],
["summary", {}, "text", "Event #2"],
["description",
{},
"text",
// Note that comments and string concatenation are not
// allowed per the JSON specification and is used here only
// to avoid long lines.
"We are having a meeting all this week at 12 pm for one " +
"hour, with an additional meeting on the first day 2 " +
"hours long.\nPlease bring your own lunch for the 12 pm " +
"meetings."
],
["uid", {}, "text", "00959BC664CA650E933C892C@example.com"]
],
[]
],
["vevent",
[
["dtstamp", {}, "date-time", "2006-02-06T00:11:21Z"],
["dtstart",
{ "tzid": "US/Eastern" },
"date-time",
"2006-01-02T14:00:00"
],
["duration", {}, "duration", "PT1H"],
["recurrence-id",
{ "tzid": "US/Eastern" },
"date-time",
"2006-01-04T12:00:00"
],
["summary", {}, "text", "Event #2"],
["uid", {}, "text", "00959BC664CA650E933C892C@example.com"]
],
[]
]
]
Authors' Addresses π«Ά
Here are the people who wrote it, with their addresses, so you know exactly who to thank π
Philipp Kewisch
Mozilla Corporation
650 Castro Street, Suite 300
Mountain View, CA 94041
USA
EMail: mozilla@kewis.ch
URI: http://www.mozilla.org/
Cyrus Daboo
Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
USA
EMail: cyrus@daboo.name
URI: http://www.apple.com/
Mike Douglass
Rensselaer Polytechnic Institute
110 8th Street
Troy, NY 12180
USA
EMail: douglm@rpi.edu
URI: http://www.rpi.edu/
π¦ where this page comes from
- ietf: rfc7265 2014-05
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms