idnits 2.17.1 draft-jenkins-jscalendar-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (September 18, 2017) is 2405 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 1956 -- Looks like a reference, but probably isn't: '2' on line 1958 ** Obsolete normative reference: RFC 5988 (Obsoleted by RFC 8288) ** Obsolete normative reference: RFC 7159 (Obsoleted by RFC 8259) Summary: 2 errors (**), 0 flaws (~~), 1 warning (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 JSON data formats for iCalendar N. Jenkins 3 Internet-Draft R. Stepanek 4 Intended status: Standards Track FastMail 5 Expires: March 22, 2018 September 18, 2017 7 JSCalendar: A JSON representation of calendar data 8 draft-jenkins-jscalendar-01 10 Abstract 12 This specification defines a JSON representation of calendar data 13 that can be used for storage and data exchange in a calendaring and 14 scheduling environment. It aims to be an alternative to the widely 15 deployed iCalendar data format and to be unambiguous, extendable and 16 simple to process. 18 Status of This Memo 20 This Internet-Draft is submitted in full conformance with the 21 provisions of BCP 78 and BCP 79. 23 Internet-Drafts are working documents of the Internet Engineering 24 Task Force (IETF). Note that other groups may also distribute 25 working documents as Internet-Drafts. The list of current Internet- 26 Drafts is at https://datatracker.ietf.org/drafts/current/. 28 Internet-Drafts are draft documents valid for a maximum of six months 29 and may be updated, replaced, or obsoleted by other documents at any 30 time. It is inappropriate to use Internet-Drafts as reference 31 material or to cite them other than as "work in progress." 33 This Internet-Draft will expire on March 22, 2018. 35 Copyright Notice 37 Copyright (c) 2017 IETF Trust and the persons identified as the 38 document authors. All rights reserved. 40 This document is subject to BCP 78 and the IETF Trust's Legal 41 Provisions Relating to IETF Documents 42 (https://trustee.ietf.org/license-info) in effect on the date of 43 publication of this document. Please review these documents 44 carefully, as they describe your rights and restrictions with respect 45 to this document. Code Components extracted from this document must 46 include Simplified BSD License text as described in Section 4.e of 47 the Trust Legal Provisions and are provided without warranty as 48 described in the Simplified BSD License. 50 Table of Contents 52 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 53 1.1. Relation to the iCalendar format . . . . . . . . . . . . 4 54 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 4 55 2. Structure of JSCalendar objects . . . . . . . . . . . . . . . 5 56 2.1. Type signatures . . . . . . . . . . . . . . . . . . . . . 5 57 2.2. Data Types . . . . . . . . . . . . . . . . . . . . . . . 5 58 2.2.1. UTCDate . . . . . . . . . . . . . . . . . . . . . . . 5 59 2.2.2. LocalDate . . . . . . . . . . . . . . . . . . . . . . 6 60 2.2.3. Duration . . . . . . . . . . . . . . . . . . . . . . 6 61 2.2.4. PatchObject . . . . . . . . . . . . . . . . . . . . . 6 62 2.2.5. Normalisation and equivalence . . . . . . . . . . . . 7 63 2.3. Custom property extensions and values . . . . . . . . . . 8 64 3. JSCalendar properties . . . . . . . . . . . . . . . . . . . . 8 65 3.1. Metadata properties . . . . . . . . . . . . . . . . . . . 8 66 3.1.1. @type . . . . . . . . . . . . . . . . . . . . . . . . 8 67 3.1.2. uid . . . . . . . . . . . . . . . . . . . . . . . . . 8 68 3.1.3. relatedTo . . . . . . . . . . . . . . . . . . . . . . 9 69 3.1.4. prodId . . . . . . . . . . . . . . . . . . . . . . . 9 70 3.1.5. created . . . . . . . . . . . . . . . . . . . . . . . 10 71 3.1.6. updated . . . . . . . . . . . . . . . . . . . . . . . 10 72 3.1.7. sequence . . . . . . . . . . . . . . . . . . . . . . 10 73 3.1.8. method . . . . . . . . . . . . . . . . . . . . . . . 10 74 3.2. Time, duration and recurrence properties . . . . . . . . 10 75 3.2.1. recurrenceRule . . . . . . . . . . . . . . . . . . . 10 76 3.2.2. recurrenceOverrides . . . . . . . . . . . . . . . . . 12 77 3.3. What and where properties . . . . . . . . . . . . . . . . 13 78 3.3.1. title . . . . . . . . . . . . . . . . . . . . . . . . 13 79 3.3.2. description . . . . . . . . . . . . . . . . . . . . . 13 80 3.3.3. locations . . . . . . . . . . . . . . . . . . . . . . 13 81 3.3.4. links . . . . . . . . . . . . . . . . . . . . . . . . 15 82 3.3.5. locale . . . . . . . . . . . . . . . . . . . . . . . 16 83 3.3.6. localizations . . . . . . . . . . . . . . . . . . . . 16 84 3.3.7. keywords . . . . . . . . . . . . . . . . . . . . . . 17 85 3.3.8. categories . . . . . . . . . . . . . . . . . . . . . 17 86 3.3.9. color . . . . . . . . . . . . . . . . . . . . . . . . 17 87 3.4. Sharing and scheduling properties . . . . . . . . . . . . 18 88 3.4.1. priority . . . . . . . . . . . . . . . . . . . . . . 18 89 3.4.2. freeBusyStatus . . . . . . . . . . . . . . . . . . . 18 90 3.4.3. privacy . . . . . . . . . . . . . . . . . . . . . . . 18 91 3.4.4. replyTo . . . . . . . . . . . . . . . . . . . . . . . 19 92 3.4.5. participants . . . . . . . . . . . . . . . . . . . . 20 93 3.5. Alerts properties . . . . . . . . . . . . . . . . . . . . 23 94 3.5.1. useDefaultAlerts . . . . . . . . . . . . . . . . . . 23 95 3.5.2. alerts . . . . . . . . . . . . . . . . . . . . . . . 23 96 4. JSCalendar objects . . . . . . . . . . . . . . . . . . . . . 25 97 4.1. JSEvent . . . . . . . . . . . . . . . . . . . . . . . . . 25 98 4.1.1. start . . . . . . . . . . . . . . . . . . . . . . . . 25 99 4.1.2. timeZone . . . . . . . . . . . . . . . . . . . . . . 26 100 4.1.3. duration . . . . . . . . . . . . . . . . . . . . . . 26 101 4.1.4. isAllDay . . . . . . . . . . . . . . . . . . . . . . 26 102 4.1.5. status . . . . . . . . . . . . . . . . . . . . . . . 26 103 4.2. JSTask . . . . . . . . . . . . . . . . . . . . . . . . . 27 104 4.2.1. due . . . . . . . . . . . . . . . . . . . . . . . . . 27 105 4.2.2. start . . . . . . . . . . . . . . . . . . . . . . . . 27 106 4.2.3. timeZone . . . . . . . . . . . . . . . . . . . . . . 27 107 4.2.4. estimatedDuration . . . . . . . . . . . . . . . . . . 27 108 4.2.5. completed . . . . . . . . . . . . . . . . . . . . . . 28 109 4.2.6. isAllDay . . . . . . . . . . . . . . . . . . . . . . 28 110 4.2.7. progress . . . . . . . . . . . . . . . . . . . . . . 28 111 4.2.8. status . . . . . . . . . . . . . . . . . . . . . . . 29 112 4.3. JSGroup . . . . . . . . . . . . . . . . . . . . . . . . . 29 113 4.3.1. entries . . . . . . . . . . . . . . . . . . . . . . . 30 114 4.3.2. source . . . . . . . . . . . . . . . . . . . . . . . 30 115 5. Conversion from and to iCalendar . . . . . . . . . . . . . . 30 116 5.1. JSEvent . . . . . . . . . . . . . . . . . . . . . . . . . 30 117 5.2. JSTask . . . . . . . . . . . . . . . . . . . . . . . . . 31 118 5.3. JSGroup . . . . . . . . . . . . . . . . . . . . . . . . . 32 119 5.4. Common properties . . . . . . . . . . . . . . . . . . . . 33 120 5.5. Locations and participants . . . . . . . . . . . . . . . 35 121 5.6. Unknown properties . . . . . . . . . . . . . . . . . . . 37 122 6. JSCalendar object examples . . . . . . . . . . . . . . . . . 37 123 6.1. Simple JSEvent . . . . . . . . . . . . . . . . . . . . . 37 124 6.2. Recurring JSEvent with exception . . . . . . . . . . . . 38 125 7. Security Considerations . . . . . . . . . . . . . . . . . . . 40 126 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40 127 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 40 128 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 40 129 10.1. Normative References . . . . . . . . . . . . . . . . . . 40 130 10.2. Informative References . . . . . . . . . . . . . . . . . 42 131 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 42 132 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 43 134 1. Introduction 136 This document defines a JSON-based format to exchange event and task 137 objects, or groups of such objects, in electronic calendar 138 applications and systems. It uses a data model that aims to be 139 unambiguous, extendable and simple to process. 141 The key design considerations for this format are as follows: 143 o The attributes of the calendar entry represented must be described 144 as a simple key-value pair, reducing complexity of its 145 representation. 147 o The data format should avoid all ambiguities, making it difficult 148 to make mistakes during implementation and increasing 149 interoperability. 151 o Most of the initial set of attributes should be taken from the 152 iCalendar data format ([RFC5545], also see Section 1.1), but a 153 conversion between the data formats is not guaranteed to be 154 completed without losing semantic meaning. 156 o Extensions, such as new properties and components, MUST NOT lead 157 to requiring an update to this document. 159 JSON is a text-based data interchange format as specified in 160 [RFC7493]. The I-JSON format defined in [RFC7493] is a strict subset 161 of this, adding restrictions to avoid potentially confusing scenarios 162 (for example, it mandates that an object MUST NOT have two properties 163 with the same key). Using JSON mostly is a pragmatic choice: its 164 widespread use helps to speed up JSCalendar adoption and a wide range 165 of production-ready JSON implementations allows to decrease 166 interoperability issues. 168 1.1. Relation to the iCalendar format 170 The iCalendar data format [RFC5545], a widely deployed interchange 171 format for calendaring and scheduling data, has served calendaring 172 vendors for a long while, but contains some ambiguities and pitfalls 173 that can not be overcome without backwards incompatible changes. 175 For example, iCalendar defines various formats for local times, UTC 176 time and dates, which confuses new users. Other sources for errors 177 are the requirement for custom timezone definitions within a single 178 calendar component, as well as the iCalendar format itself; the 179 latter causing interoperability issues due to misuse of CR LF 180 terminated strings, line continuations and subtle differences between 181 iCalendar parsers. Lastly, up until recently the iCalendar format 182 did not allow to express the difference between two calendar 183 components, which results in verbose exchanges during scheduling. 185 Some of these issues were addressed by the jCal [RFC7265] format, 186 which is a direct mapping between iCalendar and JSON. However, it 187 did not attempt to extend or update iCalendar semantics. 189 1.2. Notational Conventions 191 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 192 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 193 document are to be interpreted as described in [RFC2119]. 195 The underlying format used for this specification is JSON. 196 Consequently, the terms "object" and "array" as well as the four 197 primitive types (strings, numbers, booleans, and null) are to be 198 interpreted as described in Section 1 of[RFC7159]. 200 Some examples in this document contain "partial" JSON documents used 201 for illustrative purposes. In these examples, three periods "..." 202 are used to indicate a portion of the document that has been removed 203 for compactness. 205 2. Structure of JSCalendar objects 207 A JSCalendar object is a JSON object, which MUST be valid I-JSON (a 208 stricter subset of JSON), as specified in [RFC7159]. Property names 209 and values are case-sensitive. 211 The object has a collection of properties, as specified in the 212 following sections. Unless otherwise specified, all properties are 213 optional; omitted properties MUST be treated identically to if that 214 property had the value of "null", unless otherwise specified. 216 2.1. Type signatures 218 Types signatures are given for all JSON objects in this document. 219 The following conventions are used: 221 o "Boolean|String": The value is either a JSON "Boolean" value, or a 222 JSON "String" value. 224 o "Foo": Any name that is not a native JSON type means an object for 225 which the properties (and their types) are defined elsewhere 226 within this document. 228 o "Foo[]": An array of objects of type "Foo". 230 o "String[Foo]": A JSON "Object" being used as a map (associative 231 array), where all the values are of type "Foo". 233 2.2. Data Types 235 In addition to the standard JSON data types, the following data types 236 are used in this specification: 238 2.2.1. UTCDate 240 This is a string in [RFC3339] "date-time" format, with the further 241 restrictions that any letters MUST be in upper-case, the time 242 component MUST be included and the time MUST be in UTC. Fractional 243 second values MUST NOT be included unless non-zero and MUST NOT have 244 trailing zeros, to ensure there is only a single representation for 245 each date-time. 247 For example "2010-10-10T10:10:10.003Z" is OK, but 248 "2010-10-10T10:10:10.000Z" is invalid and MUST be encoded as 249 "2010-10-10T10:10:10Z". 251 In common notation, it should be of the form "YYYY-MM-DDTHH:MM:SSZ". 253 2.2.2. LocalDate 255 This is a date-time string _with no time zone/offset information_. 256 It is otherwise in the same format as UTCDate: "YYYY-MM-DDTHH:MM:SS". 257 The time zone to associate the LocalDate with comes from an 258 associated property, or if no time zone is associated it defines 259 _floating time_. Floating date-times represents all such points in 260 time that are represented on all time-lines with the same calendar 261 day and clock time. 263 2.2.3. Duration 265 A duration is represented by a subset of ISO8601 duration format, as 266 specified by the following ABNF: 268 dur-secfrac = "." 1*DIGIT 269 dur-second = 1*DIGIT [dur-secfrac] "S" 270 dur-minute = 1*DIGIT "M" [dur-second] 271 dur-hour = 1*DIGIT "H" [dur-minute] 272 dur-time = "T" (dur-hour / dur-minute / dur-second) 273 dur-day = 1*DIGIT "D" 275 duration = "P" (dur-day [dur-time] / dur-time) 277 In addition, the duration MUST NOT include fractional second values 278 unless the fraction is non-zero. A zero duration MUST be represented 279 as "P0D". 281 2.2.4. PatchObject 283 A *PatchObject* is of type "String[*|null]", and represents an 284 unordered set of patches on a JSON object. The keys are a path in a 285 subset of [RFC6901] JSON pointer format, with an implicit leading "/" 286 (i.e. prefix each key with "/" before applying the JSON pointer 287 evaluation algorithm). 289 The pointer MUST NOT reference inside an array (i.e. you MUST NOT 290 insert/delete from an array; the array MUST be replaced in its 291 entirety instead). Any patch with a key that attempts to do this 292 MUST be ignored. 294 When evaluating a path, all parts prior to the last (i.e. the value 295 after the final slash) MUST exist for the patch to be valid. If not, 296 the patch MUST be ignored. 298 There MUST NOT be two patches in the PatchObject where the pointer of 299 one is the prefix of the pointer of the other, e.g. "alerts/1/offset" 300 and "alerts". The result in this case is undefined. 302 The value associated with each pointer is either: 304 o "null": Remove the property from the patched object. If not 305 present in the parent, this a no-op. 307 o Anything else: The value to replace the inherited property on the 308 patch object with (if present) or add to the property (if not 309 present). 311 2.2.5. Normalisation and equivalence 313 JSCalendar aims at providing unambiguous definitions for value types 314 and properties, but does not define a general normalisation or 315 equivalence method for JSCalendar objects. This is because the 316 notion of equivalence might range from byte-level equivalence to 317 semantic equivalence, depending on the respective use case. 319 For example, the CalDAV protocol [RFC4791] requires octet equivalence 320 of the encoded calendar object to determine ETag equivalence. In 321 addition: 323 o Custom JSCalendar properties may contain arbitrary JSON values, 324 including arrays. However, equivalence of arrays might or might 325 not depend on the order of elements, depending on the respective 326 property definition. 328 o Several JSCalendar property values are defined as URIs and MIME 329 types, but normalisation of these types is inherently protocol and 330 scheme-specific ([RFC3986]), depending on the use-case of the 331 equivalence definition. 333 Considering this, the definition of equivalence and normalisation is 334 left to client and server implementations and to be negotiated by a 335 calendar exchange protocol or defined by another RFC. 337 2.3. Custom property extensions and values 339 Vendors MAY add additional properties to the calendar object to 340 support their custom features. The names of these properties MUST be 341 prefixed with a domain name controlled by the vendor to avoid 342 conflict, e.g. "fastmail.com/customprop". 344 Some JSCalendar properties allow vendor-specific value extensions. 345 If so, vendor specific values MUST be prefixed with a domain name 346 controlled by the vendor, e.g. "fastmail.com/customrel", unless 347 otherwise noted. 349 3. JSCalendar properties 351 JSCalendar objects share a set of common properties, but might only 352 support a subset of them. Refer to the respective object type 353 definitions (Section 4) for which common properties they support. 355 3.1. Metadata properties 357 3.1.1. @type 359 Type: "String" 361 Specifies the type which this object represents. This MUST be one of 362 the following values, registered in a future RFC, or a vendor- 363 specific value: 365 o "jsevent": a JSCalendar event (Section 4.1). 367 o "jstask": a JSCalendar task (Section 4.2). 369 o "jsgroup": a JSCalendar group (Section 4.3). 371 A valid JSCalendar object MUST include this property. 373 3.1.2. uid 375 Type: "String" 377 A globally unique identifier, used to associate the object as the 378 same across different systems, calendars and views. Note that all 379 JSCalendar objects share the same id space, so there MUST NOT be two 380 JSCalendar objects of different type with the same uid. [RFC4122] 381 describes a range of established algorithms to generate universally 382 unique identifiers (UUID), and is recommended to use. 384 A valid JSCalendar object MUST include this property. 386 3.1.3. relatedTo 388 Type: "String[Relation]|null" 390 Relates the object to other JSCalendar objects. This is represented 391 as a map of the uid of the related object to information about the 392 relation. 394 A *Relation* object has the following properties: 396 o *relation*: "String[]" Describes how the linked object is related 397 to this object. 399 The strings in the array MUST each be at most one of the following 400 values, registered in a future RFC, or a vendor-specific value: 402 * "first": The linked object is the first in the series this 403 object is part of. 405 * "next": The linked object is the next in the series this object 406 is part of. 408 * "child": The linked object is a subpart of this object. 410 * "parent": This object is part of the overall linked object. 412 If an object is split to make a "this and future" change to a 413 recurrence, the original object MUST be truncated to end at the 414 previous occurrence before this split, and a new object created to 415 represent all the objects after the split. 417 A "relation=["next"]" relatedTo property MUST be set on the original 418 object with the uid of the new object. A "relation=["first"]" 419 relatedTo property with the UID of the first object in the series 420 MUST be set on the new object. Clients can then follow these UIDs to 421 get the complete set of objects if the user wishes to modify them all 422 at once. 424 3.1.4. prodId 426 Type: "String|null" 428 The identifier for the product that created the JSCalendar object. 430 The vendor of the implementation SHOULD ensure that this is a 431 globally unique identifier, using some technique such as an FPI 432 value, as defined in [ISO.9070.1991]. 434 This property SHOULD NOT be used to alter the interpretation of an 435 JSCalendar object beyond the semantics specified in this document. 436 For example, it is not to be used to further the understanding of 437 non-standard properties. 439 3.1.5. created 441 Type: "UTCDate|null" 443 The date and time this object was initially created. 445 3.1.6. updated 447 Type: "UTCDate" 449 The date and time the data in this object was last modified. 451 3.1.7. sequence 453 Type: "Number" (Defaults to "0" if omitted) 455 Initially zero, this MUST be a non-negative integer that is 456 monotonically incremented each time a change is made to the object. 458 3.1.8. method 460 Type: "String|null" 462 The iTIP ([RFC5546]) method, in lower-case. Used for scheduling. 464 3.2. Time, duration and recurrence properties 466 3.2.1. recurrenceRule 468 Type: "Recurrence" 470 Defines a recurrence rule (repeating pattern) for recurring calendar 471 objects. 473 A *Recurrence* object is a JSON object mapping of a RECUR value type 474 in iCalendar, see [RFC5545] and[RFC7529]. Objects recur by applying 475 the recurrence rule (and *recurrenceOverrides*) to the *start* date/ 476 time. A JSTask (Section 4.2) without a *start* recurs by its *due* 477 date/time, if defined. 479 A Recurrence object has the following properties: 481 o *frequency*: "String" This MUST be one of the following values: 483 * "yearly" 485 * "monthly" 487 * "weekly" 489 * "daily" 491 * "hourly" 493 * "minutely" 495 * "secondly" 497 To convert from iCalendar, simply lower-case the FREQ part. 499 o *interval*: "Number"(optional, defaults to "1") The INTERVAL part 500 from iCal. If included, it MUST be an integer "x >= 1". 502 o *rscale*: "String"(optional, defaults to ""gregorian"") The RSCALE 503 part from iCalendar RSCALE [RFC7529], converted to lower-case. 505 o *skip*: "String"(optional, defaults to ""omit"") The SKIP part 506 from iCalendar RSCALE [RFC7529], converted to lower-case. 508 o *firstDayOfWeek*: "String"(optional, defaults to ""mo"") The WKST 509 part from iCalendar, represented as a lower-case abbreviated two- 510 letter English day of the week. If included, it MUST be one of 511 the following values: ""mo"|"tu"|"we"|"th"|"fr"|"sa"|"su"". 513 o *byDay*: "NDay[]"(optional) An *NDay* object has the following 514 properties: 516 * *day*: "String" The day-of-the-week part of the BYDAY value in 517 iCalendar, lower-cased. MUST be one of the following values: 518 ""mo"|"tu"|"we"|"th"|"fr"|"sa"|"su"". 520 * *nthOfPeriod*: "Number"(optional) If present, rather than 521 representing every Friday (for example), it represents only a 522 specific instance within the period (month for monthly 523 recurrences, year for yearly recurrences). Must be a non-zero 524 integer, negative integers means nth-last of period. This is 525 the ""+1"" or ""-3" " etc. prefix from the BYDAY values in 526 iCal. 528 o *byDate*: "Number[]"(optional) The BYMONTHDAY part from iCalendar. 529 The array MUST have at least one entry if included. 531 o *byMonth*: "String[]"(optional) The BYMONTH part from iCalendar. 532 Each entry is a string representation of a number, starting from 533 "1" for the first month in the calendar (e.g. ""1" " means 534 ""January"" with Gregorian calendar), with an optional ""L"" 535 suffix (see [RFC7529]) for leap months (this MUST be upper-case, 536 e.g. ""3L""). The array MUST have at least one entry if included. 538 o *byYearDay*: "Number[]"(optional) The BYYEARDAY part from 539 iCalendar. The array MUST have at least one entry if included. 541 o *byWeekNo*: "Number[]"(optional) The BYWEEKNO part from iCalendar. 542 The array MUST have at least one entry if included. 544 o *byHour*: "Number[]"(optional) The BYHOUR part from iCalendar. 545 The array MUST have at least one entry if included. 547 o *byMinute*: "Number[]"(optional) The BYMINUTE part from iCalendar. 548 The array MUST have at least one entry if included. 550 o *bySecond*: "Number[]"(optional) The BYSECOND part from iCalendar. 551 The array MUST have at least one entry if included. 553 o *count*: "Number"(optional) The COUNT part from iCalendar. This 554 MUST NOT be included if an *until* property is specified. 556 o *until*: "LocalDate"(optional) The UNTIL part from iCalendar. 557 This MUST NOT be included if a *count* property is specified. 558 Note, as in iCalendar, this date is presumed to be in the timezone 559 specified in *timeZone*. It is not a UTC time. 561 3.2.2. recurrenceOverrides 563 Type: "LocalDate[PatchObject|null]|null" 565 The object is a map of the Recurrence-Id (i.e. the date-time of the 566 start of the occurrence) to either "null", to indicate the occurrence 567 should be deleted, or an object of patches to apply to the generated 568 occurrence object. 570 If the Recurrence-Id does not match an expanded start date from a 571 recurrence rule, it is to be treated as an additional occurrence 572 (like an RDATE from iCalendar). The patch object may often be empty 573 in this case. 575 By default, an occurrence inherits all properties from the main event 576 except the start (or due) date-time, which is shifted to the new 577 start time. However, individual properties of the occurrence can be 578 modified by a patch, or multiple patches. 580 A pointer in the PatchObject MUST NOT start with one of the following 581 prefixes; any patch with such a key MUST be ignored: 583 o uid 585 o relatedTo 587 o prodId 589 o method 591 o isAllDay 593 o recurrenceRule 595 o recurrenceOverrides 597 o replyTo 599 3.3. What and where properties 601 3.3.1. title 603 Type: "String" (Defaults to the empty string if omitted) 605 A short summary of the object. 607 3.3.2. description 609 Type: "String" (Defaults to the empty string if omitted) 611 A longer form description of the object. This is plain text, but a 612 client SHOULD attempt to hyperlink URLs when displaying it. 614 3.3.3. locations 616 Type: "String[Location]|null" 618 A map of of location id to Location objects, representing locations 619 associated with the object. A location id may be any string and need 620 only be unique to this object, although a UUID is a practical choice. 622 A *Location* object has the following properties. All properties are 623 optional, but every Location object MUST have at least one property: 625 o *name*: "String" The human-readable name of the location. 627 o *description*: "String" Human-readable instructions for accessing 628 this location. This may be an address, set of directions, door 629 access code, etc. 631 o *rel*: "String" The relation type of this location to the 632 JSCalendar object. 634 This MUST be either one of the following values, registered in a 635 future RFC, or a vendor-specific value. Any value the client or 636 server doesn't understand should be treated the same as "unknown". 638 * "start": The JSCalendar object starts at this location. 640 * "end": The JSCalendar object ends at this location. 642 * "virtual": This is not a physical location (e.g. this location 643 is an online chat room where people will meet). 645 * "unknown": The relation of this location to the event is 646 unknown. 648 o *features*: "String[]|null" The features supported by this 649 location. 651 The strings in the array MUST each be either one of the following 652 values, registered in a future RFC, or a vendor-specific value. 653 Any value the client or server doesn't understand should be 654 ignored, but preserved. 656 The features supported by locations with rel-type "virtual" are: 658 * "audio": audio conferencing 660 * "chat": chat or instant messaging 662 * "screen": screen sharing 664 * "video": video conferencing 666 * any vendor-prefixed custom value 668 o *timeZone*: "String" A time zone for this location. 670 If omitted, the *timeZone* from the JSCalendar object MUST be 671 presumed when a time zone is needed in relation to this location. 673 o *coordinates*: "String" An [RFC5870] "geo:" URI for the location. 675 o *uri*: "String" A URI that represents how to connect to this 676 location. 678 This may be a telephone number (represented as 679 "tel:+1-555-555-555") for a teleconference, a web address for 680 online chat, or a custom URI for something like Skype (e.g. 681 "skype:username"). 683 o *linkIds*: "String[]|null" A list of ids for links to alternate 684 representations of this location. 686 For example, an alternative representation could be in vCard 687 format. If a given value does not correspond to any link id in 688 the links property of the instance, this MUST be ignored. 690 3.3.4. links 692 Type: "String[Link]|null" 694 A map of of link id to Link objects, representing external resources 695 associated with the object. A link id may be any string and need 696 only be unique to this object, although the href or a UUID are 697 practical choices. 699 A *Link* object has the following properties: 701 o *href*: "String" A URI from which the resource may be fetched. 703 This MAY be a "data:" URL, but it is recommended that the file be 704 hosted on a server to avoid embedding arbitrary large data in 705 JSCalendar object instances. 707 o *type*: "String|null"(optional, defaults to "null") The content- 708 type [RFC6838] of the resource, if known. 710 o *size*: "Number|null"(optional, defaults to "null") The size, in 711 bytes, of the resource when fully decoded (i.e. the number of 712 bytes in the file the user would download), if known. 714 o *rel*: "String"(optional, defaults to "related") Identifies the 715 relation of the linked resource to the object. The value MUST be 716 a registered relation type (see[RFC5988]). 718 The features supported by locations with rel-type "virtual" are: 720 Links with a rel of "enclosure" SHOULD be considered by the client 721 as attachments for download. 723 Links with a rel of "describedby" SHOULD be considered by the 724 client to be an alternate representation of the description, for 725 example an HTML page describing the object. 727 Links with a rel of "icon" SHOULD be considered by the client to 728 be an image that it MAY use when presenting the calendar data to a 729 user. The properties object of this link MAY include a display 730 property indicating the intended purpose of this image. If 731 included, the value MUST be either one of the following values, 732 registered in a future RFC, or a vendor-specific value. 734 * "badge": an image inline with the title of the object 736 * "graphic": a full image replacement for the object itself 738 * "fullsize": an image that is used to enhance the object 740 * "thumbnail": a smaller variant of "fullsize " to be used when 741 space for the image is constrained 743 o *title*: "String|null"(optional, defaults to "null") A human- 744 readable description of the resource. 746 o *properties*: "String[String|null]|null"(optional, defaults to 747 "null") Extra metadata stored by a client about a link. 749 The keys are as defined in this document, as defined in a future 750 RFC, or URIs that should be owned by the client author to avoid 751 conflicts. 753 3.3.5. locale 755 Type: "String|null" 757 The [RFC5646] language tag that best describes the locale used for 758 the event, if known. 760 3.3.6. localizations 762 Type: "String[PatchObject]|null" 764 A map of [RFC5646] language tag to a patch object which localises the 765 event into that locale. 767 See the description of PatchObject (Section 2.2.4) for the structure 768 of the PatchObject. The patches are applied to the top-level object. 769 In addition to all the restrictions on patches specified there, the 770 pointer also MUST NOT start with one of the following prefixes; any 771 patch with a such a key MUST be ignored: 773 o sequence 775 o localization 777 o start 779 o timeZone 781 o duration 783 o status 785 o freeBusyStatus 787 o participants 789 o useDefaultAlerts 791 3.3.7. keywords 793 Type: "String[]|null" 795 A list of keywords or tags related to the object. The values are 796 free-form and do not have to follow any particular structure. 798 3.3.8. categories 800 Type: "String[]|null" 802 Specifies the categories related to the calendar object. Array 803 values MUST be URIs. In contrast to keywords (Section 3.3.7), 804 categories typically are structured. 806 For example, a vendor owning the domain "example.com" might define 807 the categories "http://example.com/categories/sports/american- 808 football"" and "http://example.com/categories/music/r-b". 810 3.3.9. color 812 Type: "String" 814 Specifies a color clients MAY use when displaying this event. The 815 value is a case-insensitive color name taken from the CSS3 set of 816 names, defined in Section 4.3 of W3C.REC-css3-color-20110607 [1] or a 817 CSS3 RGB color hex value. It is not intended that clients 818 necessarily use the exact RGB value, but rather that they find a 819 suitable color that works in the given UA context. 821 3.4. Sharing and scheduling properties 823 3.4.1. priority 825 Type: "Number"(defaults to "0" if omitted) 827 Specifies a priority for the event. This may be used as part of 828 scheduling systems to help resolve conflicts for a time period. 830 The priority is specified as an integer in the range 0 to 9. A value 831 of 0 specifies an undefined priority. A value of 1 is the highest 832 priority. A value of 2 is the second highest priority. Subsequent 833 numbers specify a decreasing ordinal priority. A value of 9 is the 834 lowest priority. Other integer values are reserved for future use. 836 3.4.2. freeBusyStatus 838 Type: "String"(defaults to "busy" if omitted) 840 Specifies how this property should be treated when calculating free- 841 busy state. The value MUST be one of: 843 o ""free"": The object should be ignored when calculating whether 844 the user is busy. 846 o ""busy"": The object should be included when calculating whether 847 the user is busy. 849 3.4.3. privacy 851 Type: "String"(defaults to "public" if omitted) 853 Calendar objects are normally collected together and may be shared 854 with other users. The privacy property allows the object owner to 855 indicate that it should not be shared, or should only have the time 856 information shared but the details withheld. 858 As JSCalendar is simply a data model, enforcement of the restrictions 859 indicated by this property are up to the implementations. 861 This property MUST NOT affect the information sent to scheduled 862 participants; it is only interpreted when the object is shared as 863 part of a shared calendar. 865 The value MUST be either one of the following values, registered in a 866 future RFC, or a vendor-specific value. Vendor specific values MUST 867 be prefixed with a domain name controlled by the vendor, e.g. 868 "fastmail.com/topsecret". Any value the client or server doesn't 869 understand should be preserved but treated as equivalent to 870 "private". 872 o "public": The full details of the object are visible to those whom 873 the object's calendar is shared with. 875 o "private": The details of the object are hidden; only the basic 876 time and metadata is shared. Implementations MUST ensure the 877 following properties are stripped when the object is accessed by a 878 sharee: 880 * title 882 * description 884 * locations 886 * links 888 * locale 890 * localizations 892 * participants 894 * replyTo 896 In addition, any patches in "recurrenceOverrides" whose key is 897 prefixed with one of the above properties MUST be stripped. 899 o "secret": The object is hidden completely (as though it did not 900 exist) when the calendar is shared. 902 3.4.4. replyTo 904 Type: "String[String]|null" 906 Represents methods by which a participant may RSVP to the organizer 907 of the calendar object. The keys in the property value are the 908 available methods. The value is a URI to use that method. Future 909 methods may be defined in future specifications; a calendar client 910 MUST just ignore any method it does not understand. 912 The following methods are defined: 914 o "imip": The organizer accepts an iMIP [RFC6047] response. The 915 value MUST be a "mailto:" URI. 917 o "web": There is a web page where the user may submit an RSVP using 918 their browser. The value MUST be an "http:" or "https:" URI. 920 3.4.5. participants 922 Type: "String[Participant]|null" 924 A map of participant id to a participant describing their 925 participation in the calendar object. A participant id may be any 926 string and need only be unique to this event; the email address of 927 the participant is a good choice. 929 A *Participant* object has the following properties. Properties are 930 mandatory unless marked otherwise: 932 o *name*: "String" The display name of the participant (e.g. "Joe 933 Bloggs"). 935 o *email*: "String" The email address for the participant. 937 o *kind*: "String"(optional, defaults to "unknown") What kind of 938 entity this participant is. 940 This MUST be either one of the following values, registered in a 941 future RFC, or a vendor-specific value. Any value the client or 942 server doesn't understand should be treated the same as "unknown". 944 * "individual": a single person 946 * "group": a collection of people invited as a whole 948 * "resource": a non-human resource, e.g. a projector 950 * "location": a physical location involved in the event that 951 needs to be scheduled, e.g. a conference room. 953 * "unknown": no information is available about the kind of this 954 participant. 956 o *roles*: "String[]" A list of roles that this participant fulfils. 958 At least one value MUST be specified for the participant. This 959 MUST be either one of the following values, registered in a future 960 RFC, or a vendor-specific value. Any value the client or server 961 doesn't understand should be preserved but ignored. 963 * "owner": The participant is an organizer of the event, and 964 allowed to make alterations to any part of the event. 966 * "attendee": The participant is an attendee of the event. 968 * "chair": The participant is in charge of the event when it 969 occurs. 971 o *locationId|null*: "String"(optional, defaults to "null") The 972 location at which this participant is expected to be attending. 974 If the value does not correspond to any location id in the 975 locations property of the instance, this MUST be treated the same 976 as if the participant's locationId were specified as null. 978 o *rsvpResponse*: "String"(optional, defaults to "needs-action") The 979 RSVP response, if any, of this participant. 981 The value MUST be either one of the following values, registered 982 in a future RFC, or a vendor-specific value: 984 * "needs-action": No status yet set by the participant. 986 * "accepted": The participant will attend. 988 * "declined": The participant may attend. 990 * "tentative": The participant will not attend. 992 o *participation*: "String"(optional, defaults to "required") The 993 required attendance of this participant. 995 The value MUST be either one of the following values, registered 996 in a future RFC, or a vendor-specific value. Any value the client 997 or server doesn't understand should be treated the same as 998 "required". 1000 * "non-participant": Indicates a participant who is copied for 1001 information purposes only. 1003 * "optional": Indicates a participant whose participation is 1004 optional. 1006 * "required": Indicates a participant whose participation is 1007 required. 1009 o *rsvpWanted*: "Boolean"(optional, defaults to "false") If true, 1010 the organizer is expecting the participant to notify them of their 1011 status. 1013 o *scheduleSequence*: "Number"(optional, defaults to "0") The 1014 sequence number of the last response from the participant. If 1015 defined, this MUST be a non-negative integer. 1017 This can be used to determine whether the partcipant has sent a 1018 new RSVP following significant changes to the event, and to 1019 determine if future responses are responding to a current or older 1020 view of the data. 1022 o *scheduleUpdated*: "UTCDate|null"(optional, defaults to "null") 1023 The *updated* property of the last iMIP response from the 1024 participant. 1026 This can be compared to the *updated* timestamp in future iMIP 1027 responses to determine if the response is older or newer than the 1028 current data. 1030 o *invitedBy*: "String|null"(optional, defaults to "null") The 1031 participant id of the participant who invited this one, if known. 1033 o *delegatedTo*: "String[]|null"(optional, defaults to "null") A 1034 list of participant ids of participants that this participant has 1035 delegated their participation to. This MUST be omitted if none 1036 (rather than an empty array). 1038 o *delegatedFrom*: "String[]|null"(optional, defaults to "null") A 1039 list of participant ids that this participant is acting as a 1040 delegate for. This MUST be omitted if none (rather than an empty 1041 array). 1043 o *memberOf*: "String[]|null"(optional, defaults to "null") A list 1044 of group addresses that were invited to this calendar object, 1045 which caused this participant to be invited due to their 1046 membership of the group(s). This MUST be omitted if none (rather 1047 than an empty array). 1049 o *linkIds*: "String[]|null"(optional, defaults to "null") Links to 1050 more information about this participant, for example in vCard 1051 format. If a given value does not correspond to any link id in 1052 the links property of the instance, this id MUST be ignored. This 1053 MUST be omitted if none (rather than an empty array). 1055 3.5. Alerts properties 1057 3.5.1. useDefaultAlerts 1059 Type: "Boolean" (defaults to "false" if omitted) 1061 If "true", use the user's default alerts for this event and ignore 1062 the Section 3.5.2 property. Fetching user defaults is dependent on 1063 the API from which this JSCalendar object is being fetched, and is 1064 not defined in this specification. 1066 3.5.2. alerts 1068 Type: "String[Alert]|null" 1070 A map of of alert id to Alert objects, representing alerts/reminders 1071 to display or send the user for this calendar object. An alert id 1072 may be any string and need only be unique to this calendar object, 1073 although a UUID is a practical choice. 1075 An *Alert* Object has the following properties: 1077 o *relativeTo*: "String" (optional, defaults to "before-start") 1078 Specifies where the offset is relative to for the alarm to 1079 trigger. The value MUST be one of: 1081 * "before-start" 1083 * "after-start" 1085 * "before-end" 1087 * "after-end" 1089 o *offset*: "Duration" The offset from the start and end/due of the 1090 calendar object to fire the alert. If the calendar object does 1091 not define a time zone, the user's default time zone SHOULD be 1092 used when determining the offset, if known. Otherwise, the time 1093 zone to use is implementation specific. 1095 o *action*: "DisplayAction|EmailAction|UnknownAction" 1097 Describes how to alert the user. 1099 A *DisplayAction* means a message (which is service dependent, but 1100 SHOULD include the title and start or due time of the calendar 1101 object) SHOULD be shown to the user on any client connected to 1102 this account at the specified time. How this message is formatted 1103 (and any sound or other method of drawing the user's attention) is 1104 client specific. It has the following properties: 1106 * *type*: "String" The value MUST be "display". 1108 * *acknowledged*: "UTCDate|null " (optional) 1110 When the user has permanently dismissed the alert the client 1111 MUST set this to the current time in UTC. Other clients which 1112 sync this property can then automatically dismiss or suppress 1113 duplicate alerts (alerts with the same alert id that triggered 1114 on or before this date-time). 1116 For a recurring event, the *acknowledged* property of the 1117 parent event MUST be updated, unless the alert is already 1118 overridden in *recurrenceOverrides*. 1120 * *snoozed*: "UTCDate|null" (optional) 1122 If the user temporarily dismisses the alert, this is the UTC 1123 date-time after which it should be reshown. Clients displaying 1124 this alert SHOULD hide it if the snoozed property is updated to 1125 a time in the future. When that time is reached, the alert 1126 SHOULD be reshown unless acknowledged is now after the original 1127 trigger time. 1129 Setting this property on an instance of a recurring event MUST 1130 update the alarm on the master event, unless the respective 1131 instance already is defined in "recurrenceOverrides". It MUST 1132 NOT generate an override for the sole use of snoozing an alarm. 1134 * *audioLinkId*: "String|null " (optional) 1136 The id of a link in the Section 3.3.4 property. If the linked 1137 file is of an audio type understood by the client, the client 1138 SHOULD play this audio when triggering the alert. 1140 An *EmailAction* means an email SHOULD be sent as specified in the 1141 object at the specified time. It has the following properties: 1143 * *type*: "String" The value MUST be "email". 1145 * *to*: "Emailer[]" An array of name/email objects to send the 1146 alert to. 1148 An *Emailer* object has the following properties: 1150 + name: String The name of the recipient. If not known, 1151 clients SHOULD use the empty string. 1153 + email: String The email address of the recipient. 1155 * *subject*: "String" (optional) The subject to use for the 1156 email. If omitted, this is implementation specific, but the 1157 server SHOULD try to choose an appropriate subject (such as 1158 "Event Summary: starting in 5 min"). 1160 * *textBody*: "String" (optional) The plain-text body to use for 1161 the email. If omitted, the body of the email is implementation 1162 specific, but the server SHOULD include all pertinent details 1163 about the event, such as summary, location and start time. 1165 An *UnknownAction* object is an object that contains a _type _ 1166 property whose value is not "email" or "string", plus zero or more 1167 other properties. This is for compatibility with client 1168 extensions and future RFCs. The client or server SHOULD NOT 1169 trigger any type of alert for action types they do not understand, 1170 but MUST preserve them. 1172 4. JSCalendar objects 1174 4.1. JSEvent 1176 MIME type: "application/calendar+json;type=jsevent" 1178 A JSEvent represents a scheduled amount of time on a calendar, 1179 typically a meeting, appointment, reminder or anniversary. Multiple 1180 participants may partake in the event at multiple locations. 1182 A JSEvent @type (Section 3.1.1) property value MUST be "jsevent". 1184 In addition to the common JSCalendar object properties (Section 3) a 1185 JSEvent has the following properties: 1187 4.1.1. start 1189 Type: "LocalDate" e.g. "2015-09-02T00:00:00" 1191 The date/time the event would start in the event's time zone. 1193 A valid JSEvent MUST include this property. 1195 4.1.2. timeZone 1197 Type: "String|null" 1199 The IANA Time Zone Database [2] name for the time zone the event is 1200 scheduled in, or "null" for floating time. If omitted, this MUST be 1201 presumed to be "null" (i.e. floating time). 1203 4.1.3. duration 1205 Type: "Duration", e.g. "P2DT3H" (Defaults to "P0D" if omitted) 1207 The zero or positive duration of the event in absolute time (i.e. in 1208 UTC time; ignoring DST shifts). To get the end date in the event 1209 time zone, convert start into UTC, then add the duration, then 1210 convert the result into the appropriate time zone. 1212 A JSEvent MAY be end in a different timezone (e.g. a plane flight 1213 crossing timezones). In this case, the JSEvent MUST specify the end 1214 timezone in a *location* property value that defines its *rel* to be 1215 "end" and the end timezone in its *timeZone* property. 1217 4.1.4. isAllDay 1219 Type: "Boolean" (optional, defaults to "false") 1221 Specifies if the event an all day event, such as a birthday or public 1222 holiday. 1224 If *isAllDay* is true, then the following restrictions apply: 1226 o the *start* property MUST have a time component of "T00:00:00". 1228 o the *duration* property MUST only include a day component. 1230 Note that all-day events MAY be bound to a specific time zone, as 1231 defined by the *timeZone* property. 1233 4.1.5. status 1235 Type: "String" 1237 The scheduling status (Section 3.4) of a JSEvent defaults to 1238 "confirmed" if omitted. 1240 If set, it MUST be one of: 1242 o "confirmed": Indicates the event is definite. 1244 o "cancelled": Indicates the event is cancelled. 1246 o "tentative": Indicates the event is tentative. 1248 4.2. JSTask 1250 MIME type: "application/calendar+json;type=jstask" 1252 A JSTask represents an action-item, assignment, to-do or work item . 1254 A JSTask @type (Section 3.1.1) property value MUST be "jstask". 1256 A JSTask may start and be due at certain points in time, may take 1257 some estimated time to complete and may recur; none of which is 1258 required. This notably differs from JSEvent (Section 4.1) which is 1259 required to start at a certain point in time and typically takes some 1260 non-zero duration to complete. 1262 In addition to the common JSCalendar object properties (Section 3) a 1263 JSTask has the following properties: 1265 4.2.1. due 1267 Type: "LocalDate|null" e.g. "2015-09-02T00:00:00" 1269 The date/time the task is due in the task's time zone. 1271 4.2.2. start 1273 Type: "LocalDate|null" e.g. "2015-09-02T00:00:00" 1275 The date/time the task should start in the task's time zone. 1277 4.2.3. timeZone 1279 Type: "String|null" 1281 The IANA Time Zone Database name for the time zone the task is 1282 scheduled in, or "null" for floating time. If omitted, this MUST be 1283 presumed to be "null" (i.e. floating time). 1285 4.2.4. estimatedDuration 1287 Type: "Duration|null", e.g. "P2DT3H" 1289 Specifies the estimated positive duration of time the task takes to 1290 complete. 1292 If the *start* and *due* properties are set, the estimated duration 1293 SHOULD be less than or equal to the time interval between these 1294 properties. 1296 4.2.5. completed 1298 Type: "UTCDate|null", e.g. "2016-06-13T12:00:00Z" 1300 Specifies the date/time the task was completed. 1302 If the task is recurring and has future instances, a client may want 1303 to denote a specific task recurrence as completed but leave other 1304 instances as uncompleted. One way to achieve this is by overriding 1305 the completed property in the task recurrence overrides 1306 (Section 3.2.2). However, this could produce a long list of 1307 completion times for regularly recurring tasks. An alternative 1308 approach is to split the JSTask into a current, single instance of 1309 JSTask with this instance completion time and a future recurring 1310 instance. Also see the definition of the relatedTo (Section 3.1.3) 1311 property Section 3.1.3 on splitting. 1313 4.2.6. isAllDay 1315 Type: "Boolean" (optional, defaults to "false") 1317 Specifies if the task is an all day task. 1319 If *isAllDay* is true, then the following restrictions apply: 1321 o the *start* and *due* properties MUST have a time component of 1322 "T00:00:00". 1324 o the *duration* and *estimatedDuration* properties MUST only 1325 include a day component. 1327 Note that all-day tasks MAY be bound to a specific time zone, as 1328 defined by the *timeZone* property. 1330 4.2.7. progress 1332 In addition to the common properties of a *Participant* object 1333 (Section 3.4.5), a Participant within a JSTask supports the following 1334 property: 1336 o *progress*: "ParticipantProgress|null" The progress of the 1337 participant for this task, if known. 1339 A *ParticipantProgress* object has the following properties: 1341 o *status*: "String" Describes the completion status of the 1342 participant's progress. 1344 The value MUST be at most one of the following values, registered 1345 in a future RFC, or a vendor-specific value: 1347 * "completed": The participant completed her part of the task. 1349 * "in-process": The participant is in process of completing her 1350 part of the task. 1352 o *timestamp*: "UTCDate" Describes the latest time when the 1353 participant updated her progress. 1355 4.2.8. status 1357 Type: "String" 1359 The scheduling status (Section 3.4) of a JSTask defaults to "needs- 1360 action" if omitted. 1362 If set, it MUST be one of: 1364 o "needs-action": Indicates the task needs action. 1366 o "completed": Indicates the task is completed. If this value is 1367 set, then the timestamp in the "completed" property 1368 (Section 4.2.5) MUST NOT be null. 1370 o "in-process": Indicates the task is in process. 1372 o "cancelled": Indicates the task is cancelled. 1374 4.3. JSGroup 1376 MIME type: "application/calendar+json;type=jsgroup" 1378 A JSGroup is a collection of JSEvent (Section 4.1) and JSTask 1379 (Section 4.2) objects. Typically, objects are grouped by topic (e.g. 1380 by keywords) or calendar membership. 1382 Its @type (Section 3.1.1) property value MUST be "jsgroup". 1384 JSGroup supports the following JSCalendar properties (Section 3): 1386 o @type 1388 o uid 1389 o created 1391 o updated 1393 o categories 1395 o keywords 1397 o name 1399 o description 1401 o color 1403 o links 1405 as well as the following JSGroup-specific properties: 1407 4.3.1. entries 1409 Type: "(JSTask|JSEvent)[]|null" 1411 A list of group members. The list MAY contain multiple object types 1412 and implementations MUST ignore entries of unknown type. The 1413 property value MUST either be "null" or the list MUST NOT be empty. 1415 4.3.2. source 1417 Type: "String|null" (optional, default is "null") 1419 The source from which updated versions of this group may be retrieved 1420 from. If the value is not "null", it MUST be a URI. 1422 5. Conversion from and to iCalendar 1424 This section specifies which JSCalendar properties can be mapped from 1425 and to iCalendar format. Implementations SHOULD follow these 1426 conversion guidelines. Still, JSCalendar does not restrict itself to 1427 iCalendar and conversion between these two formats MAY be lossy. 1429 5.1. JSEvent 1431 The iCalendar counterpart to *JSEvent* is the VEVENT component type 1432 [RFC5545]. A VEVENT component that is a direct child of a VCALENDAR 1433 component is equivalent to a standalone JSEvent. A VEVENT component 1434 *within* a VEVENT maps to the entries of the JSEvent 1435 *recurrenceOverrides* property (see Section 3.2.2). 1437 +----------+--------------------------------------------------------+ 1438 | Property | iCalendar counterpart | 1439 +----------+--------------------------------------------------------+ 1440 | isAllDay | True, if the type of the DTSTART property in iCalendar | 1441 | | is DATE. When translating from JSCalendar the | 1442 | | iCalendar DTSTART property is of DATE value type, if | 1443 | | the *isAllDay* property is set to true and the | 1444 | | *timeZone* property is null. | 1445 | | | 1446 | start | Corresponds to the DTSTART property in iCalendar. Note | 1447 | | that time zone information is stored separately in | 1448 | | JSEvent. | 1449 | | | 1450 | timeZone | Corresponds to the TZID part of the DTSTART property | 1451 | | in iCalendar. If the event has a different end time | 1452 | | zone to start time zone, this should be added as a | 1453 | | JSCalendar *location* with just a *timeZone* property | 1454 | | and "rel="end"". | 1455 | | | 1456 | duration | Corresponds to the DURATION or DSTART+DTEND properties | 1457 | | in iCalendar. | 1458 +----------+--------------------------------------------------------+ 1460 Table 1: Translation between JSEvent and iCalendar 1462 5.2. JSTask 1464 The iCalendar counterpart to *JSTask* is the VTODO component type 1465 [RFC5545]. A VTODO component that is a direct child of a VCALENDAR 1466 component is equivalent to a standalone JSTask. A VTODO component 1467 *within* a master VTODO maps to the entries of the JSTask 1468 *recurrenceOverrides* property (see Section 3.2.2). 1470 +-------------------+-----------------------------------------------+ 1471 | Property | iCalendar counterpart | 1472 +-------------------+-----------------------------------------------+ 1473 | isAllDay | True, if the type of the DTSTART property in | 1474 | | iCalendar is DATE. When translating from | 1475 | | JSCalendar the iCalendar DTSTART property is | 1476 | | of DATE value type, if the *isAllDay* | 1477 | | property is set to true and the *timeZone* | 1478 | | property is null. | 1479 | | | 1480 | due | Corresponds to the DUE and DTSTART+DURATION | 1481 | | properties in iCalendar. When mapping | 1482 | | iCalendar VTODOs with DTSTART+DURATION, the | 1483 | | due date is the result of adding DURATION to | 1484 | | DTSTART in the DTSTART timezone. | 1485 | | | 1486 | start | Corresponds to the DTSTART property in | 1487 | | iCalendar. | 1488 | | | 1489 | timeZone | Corresponds to the TZID part of the | 1490 | | DTSTART/DUE properties in iCalendar. If the | 1491 | | task has a different end time zone to start | 1492 | | or due time zone, this should be added as a | 1493 | | JSCalendar *location* with just a *timeZone* | 1494 | | property and "rel="end"". | 1495 | | | 1496 | estimatedDuration | Corresponds to the ESTIMATED-DURATION | 1497 | | iCalendar property. *NON-STANDARD*: this | 1498 | | property is currently non-standard, see | 1499 | | [draft-apthorp-ical-tasks]. | 1500 | | | 1501 | completed | Maps to the COMPLETED iCalendar property. | 1502 | | | 1503 | progress | Corresponds to the PARTSTAT and COMPLETED | 1504 | | properties in iCalendar. | 1505 +-------------------+-----------------------------------------------+ 1507 Table 2: Translation between JSTask and iCalendar 1509 5.3. JSGroup 1511 A JSGroup converts to a iCalendar VCALENDAR containing VEVENT or 1512 VTODO components. 1514 +----------+--------------------------------------------------------+ 1515 | Property | iCalendar counterpart | 1516 +----------+--------------------------------------------------------+ 1517 | entries | The VEVENT and VTODO components within a top-level | 1518 | | VCALENDAR component. | 1519 | | | 1520 | source | Corresponds to the SOURCE property in iCalendar. | 1521 +----------+--------------------------------------------------------+ 1523 Table 3: Translation between JSGroup and iCalendar 1525 5.4. Common properties 1527 +---------------------+---------------------------------------------+ 1528 | Property | iCalendar counterpart | 1529 +---------------------+---------------------------------------------+ 1530 | alerts | An *Alert* corresponds to the VALARM | 1531 | | component in iCalendar, where the *action* | 1532 | | is determined by the iCalendar ACTION | 1533 | | property value (e.g., a "DISPLAY" property | 1534 | | indicates that the JSCalendar Alert action | 1535 | | is a *DisplayAction* and similarly an | 1536 | | iCalendar "EMAIL" value for *EmailAction* | 1537 | | action). The *relativeTo* and *offset* | 1538 | | properties corresponds to the iCalendar | 1539 | | TRIGGER property. *NON-STANDARD*: The | 1540 | | iCalendar properties for JSCalendar Alert | 1541 | | actions are non-standard, see | 1542 | | [draft-daboo-valarm-extensions]. | 1543 | | | 1544 | categories | Corresponds to the STRUCTURED-CATEGORY | 1545 | | property in iCalendar, see. *NON- | 1546 | | STANDARD*: this property is currently non- | 1547 | | standard, see | 1548 | | [draft-ietf-calext-ical-relations]. | 1549 | | | 1550 | created | Corresponds to the CREATED property in | 1551 | | iCalendar. | 1552 | | | 1553 | description | Corresponds to the DESCRIPTION property in | 1554 | | iCalendar. | 1555 | | | 1556 | freeBusyStatus | Corresponds to the TRANSP property in | 1557 | | iCalendar. | 1558 | | | 1559 | keywords | Corresponds to the COLOR property in | 1560 | | iCalendar, as specified in [RFC7986]. | 1561 | | | 1562 | links | Corresponds to the ATTACH ([RFC5545]) and | 1563 | | IMAGE iCalendar properties ([RFC7986]). | 1564 | | | 1565 | locale | Corresponds to the LANGUAGE parameter in | 1566 | | iCalendar, which is added to individual | 1567 | | properties. When converting from | 1568 | | iCalendar, one language must be picked as | 1569 | | the main locale for the object, and all | 1570 | | properties in other languages moved to the | 1571 | | localizations JSEvent property. | 1572 | | | 1573 | localizations | Corresponds to the LANGUAGE parameter in | 1574 | | iCalendar, which is added to individual | 1575 | | properties. When converting from | 1576 | | iCalendar, one language must be picked as | 1577 | | the main locale for the object, and all | 1578 | | properties in other languages moved to the | 1579 | | localizations JSEvent property. | 1580 | | | 1581 | locations | See Section 5.5. | 1582 | | | 1583 | method | Corresponds to the METHOD property in | 1584 | | iCalendar. | 1585 | | | 1586 | participants | See Section 5.5. | 1587 | | | 1588 | priority | Corresponds to the PRIORITY property in | 1589 | | iCalendar. | 1590 | | | 1591 | privacy | Corresponds to the CLASS property in | 1592 | | iCalendar. | 1593 | | | 1594 | prodId | Corresponds to the PRODID property in | 1595 | | iCalendar. | 1596 | | | 1597 | recurrenceOverrides | Corresponds to the RDATE and EXDATE | 1598 | | properties in iCalendar, plus VEVENT (for | 1599 | | JSEvent) or VTODO (for JSTask) instances | 1600 | | with a Recurrence-Id. | 1601 | | | 1602 | recurrenceRule | Corresponds to the RRULE property in | 1603 | | iCalendar. See the property definition at | 1604 | | section Section 3.2.1 how to map a RRULE | 1605 | | value. | 1606 | | | 1607 | relatedTo | Corresponds to the RELATED-TO property in | 1608 | | iCalendar. | 1609 | | | 1610 | replyTo | A *replyTo* property of type "imip" | 1611 | | corresponds to the email address of the | 1612 | | ORGANIZER property in iCalendar. There is | 1613 | | no iCalendar representation for the "web" | 1614 | | type. | 1615 | | | 1616 | sequence | Corresponds to the SEQUENCE property in | 1617 | | iCalendar. | 1618 | | | 1619 | status | Corresponds to the STATUS property in | 1620 | | iCalendar (converted to lower-case). | 1621 | | | 1622 | title | Corresponds to the SUMMARY property in | 1623 | | iCalendar. | 1624 | | | 1625 | uid | Corresponds to the UID property in | 1626 | | iCalendar. | 1627 | | | 1628 | updated | Corresponds to the DTSTAMP and LAST- | 1629 | | MODIFIED properties in iCalendar. (These | 1630 | | are only different in the iTIP case, and | 1631 | | the difference is not actually useful.) | 1632 +---------------------+---------------------------------------------+ 1634 Table 4: Translation between JSCalendar and iCalendar 1636 5.5. Locations and participants 1638 Both JSCalendar participants and locations have counterparts in 1639 iCalendar but provide richer representation. 1641 The following table outlines translation of JSCalendar participants. 1642 Where iCalendar has distinct properties for ORGANIZER and ATTENDEE, 1643 these are merged in JSCalendar into the Participant object type. 1645 +------------------+------------------------------------------------+ 1646 | Property | iCalendar counterpart | 1647 +------------------+------------------------------------------------+ 1648 | name | the CN parameter | 1649 | | | 1650 | kind | the CUTYPE parameter | 1651 | | | 1652 | rsvpResponse | the PARTSTAT parameter | 1653 | | | 1654 | role | the ORGANIZER and ATTENDEE property name | 1655 | | | 1656 | participation | the ROLE parameter | 1657 | | | 1658 | locationId | the JSCalendar identifier of a mapped | 1659 | | CONFERENCE property that has the MODERATOR | 1660 | | feature defined in its FEATURE parameter | 1661 | | values. If multiple such CONFERENCE properties | 1662 | | are defined in iCalendar, then the one with | 1663 | | the most interactive features is chosen (VIDEO | 1664 | | over AUDIO over CHAT over anything else). | 1665 | | | 1666 | rsvpWanted | the RSVP parameter | 1667 | | | 1668 | delegatedTo | the DELEGATED-TO parameter | 1669 | | | 1670 | delegatedFrom | the DELEGATED-FROM parameter | 1671 | | | 1672 | memberOf | the MEMBER parameter | 1673 | | | 1674 | scheduleSequence | the SEQUENCE property of the participant's | 1675 | | latest iMIP message | 1676 | | | 1677 | scheduleUpdated | the DTSTAMP property of the participant's | 1678 | | latest iMIP message | 1679 +------------------+------------------------------------------------+ 1681 Table 5: Translation of Participant between JSCalendar and iCalendar 1683 For JSCalendar locations, the iCalendar counterparts are the 1684 [RFC5545] LOCATION and the extended iCalendar [RFC7986] CONFERENCE 1685 properties. 1687 An iCalendar LOCATION property becomes a JSCalendar Location with 1688 just a description property. CONFERENCE property values in iCalendar 1689 map to locations with *rel* type "virtual". The location *feature* 1690 property value corresponds to the extended iCalendar FEATURE property 1691 parameter values defined in [RFC7986]. Both iCalendar PHONE and 1692 AUDIO features map to the "audio" feature and the FEED parameter 1693 value is omitted. See the mapping for *locationId* in Table 5 on how 1694 to map CONFERENCE properties that contain the MODERATOR feature. 1696 5.6. Unknown properties 1698 Both JSCalendar and iCalendar calendar objects may contain properties 1699 that are not expressible in the other format. This specification 1700 does not mandate how to preserve these properties. Instead, it 1701 leaves negotiation on how to treat unknown properties to client and 1702 server implementations and their protocol used to exchange calendar 1703 objects. 1705 Two notable options to represent and preserve arbitrary iCalendar 1706 object properties in JSCalendar are: 1708 o *JCal*: Define iCalendar properties in JCal format ([RFC7265]) in 1709 a vendor-specific property of the JCalendar object. The JCal- 1710 formatted value may either only contain iCalendar properties that 1711 were not mapped to JSCalendar properties, or contain the complete 1712 iCalendar object representation. 1714 o *Alternate link*: Define an alternate link (Section 3.3.4) value 1715 pointing to the iCalendar representation of the JSCalendar object. 1716 E.g. the alternative representation of a VEVENT would be 1717 represented as a link with rel "alternate" and type "text/ 1718 calendar;component=VEVENT". 1720 6. JSCalendar object examples 1722 The following examples illustrate several aspects of the JSCalendar 1723 data model and format. 1725 6.1. Simple JSEvent 1727 This JSEvent object represents a one-time event taking place on 1728 September 28 at 4pm, UTC for one hour. 1730 { 1731 "@type": "jsevent", 1732 "uid": "2a358cee-6489-4f14-a57f-c104db4dc357", 1733 "updated": "2016-09-14T13:24:34Z", 1734 "title": "Squash", 1735 "description": "", 1736 "start": "2016-09-28T16:00:00", 1737 "timeZone": "Etc/UTC", 1738 "duration": "PT1H", 1739 "recurrenceRule": null, 1740 "recurrenceOverrides": null, 1741 "freeBusyStatus": "free", 1742 "replyTo": null, 1743 "participants": null, 1744 "alerts": null, 1745 "links": null, 1746 "locations": null, 1747 "locale": "en", 1748 "localizations": null, 1749 } 1751 Since properties can be omitted if their default value is used, this 1752 can be simplified to: 1754 { 1755 "@type": "jsevent", 1756 "uid": "2a358cee-6489-4f14-a57f-c104db4dc357", 1757 "updated": "2016-09-14T13:24:34Z", 1758 "title": "Squash", 1759 "start": "2016-09-28T16:00:00", 1760 "timeZone": "Etc/UTC", 1761 "duration": "PT1H", 1762 "locale": "en" 1763 } 1765 6.2. Recurring JSEvent with exception 1767 This JSEvent object represents a recurring event, taking place the 1768 first time on January 1, 2016 at 1pm in Vienna, Europe. It recurs 1769 monthly, but does not occur on February 1, 2016. In addition to the 1770 regular recurrences it also occurs on December 5, 2016 at 5pm, Vienna 1771 time. On May 1, it takes place at another location and lasts for two 1772 hours, in contrast to the regular one-hour duration. 1774 { 1775 "@type": "jsevent", 1776 "uid": "89eee195-600b-423b-b3a6-52b3a420e556", 1777 "title": "Tennis", 1778 "locations": { 1779 "loc1" : { 1780 "description" : "Joe's Tennis Plaza, Court #1" 1781 } 1782 }, 1783 "isAllDay": false, 1784 "start": "2016-01-01T13:00:00", 1785 "timeZone": "Europe/Vienna", 1786 "duration": "PT1H", 1787 "recurrenceRule": { 1788 "frequency": "monthly", 1789 }, 1790 "recurrenceOverrides": { 1791 "2016-02-01T13:00:00": null, 1792 "2016-05-01T13:00:00": { 1793 "duration": "PT2H", 1794 "locations": { 1795 "loc2": { 1796 "description": "Tennis Fritz&Mayer, Ltd." 1797 } 1798 }, 1799 "2016-12-05T17:00:00": {}, 1800 } 1801 } 1802 } 1804 Note that the recurrenceOverride on May 1 overrides the complete 1805 location object. If the event should occur at *both* locations, the 1806 PatchObject would be defined as follows: 1808 { 1809 [...] 1810 "recurrenceOverrides": { 1811 [...] 1812 "2016-05-01T13:00:00": { 1813 "duration": "PT2H", 1814 "locations/loc2": { 1815 "description": "Tennis Fritz&Mayer, Ltd." 1816 } 1817 } 1818 } 1820 7. Security Considerations 1822 The use of JSON as a format does have its own inherent security risks 1823 as discussed in Section 12 of [RFC7159]. Even though JSON is 1824 considered a safe subset of JavaScript, it should be kept in mind 1825 that a flaw in the parser processing JSON could still impose a 1826 threat, which doesn't arise with conventional iCalendar data. 1828 With this in mind, a parser for JSON data aware of the security 1829 implications should be used for the format described in this 1830 document. For example, the use of JavaScript's "eval()" function is 1831 considered an unacceptable security risk, as described in Section 12 1832 of[RFC7159]. A native parser with full awareness of the JSON format 1833 should be preferred. 1835 8. IANA Considerations 1837 This document amends the "application/calendar" MIME media type 1838 defined in [RFC7265]. 1840 New optional parameter: "type" with value being one of "jsevent", 1841 "jstask", "jsgroup". The parameter MUST NOT occur more than once. 1843 9. Acknowledgments 1845 The author would like to thank the following for their valuable 1846 contributions: (TODO:names). This specification originated from the 1847 work of the API technical committee of CalConnect, the Calendaring 1848 and Scheduling Consortium. 1850 10. References 1852 10.1. Normative References 1854 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1855 Requirement Levels", BCP 14, RFC 2119, 1856 DOI 10.17487/RFC2119, March 1997, 1857 . 1859 [RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: 1860 Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, 1861 . 1863 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 1864 Resource Identifier (URI): Generic Syntax", STD 66, 1865 RFC 3986, DOI 10.17487/RFC3986, January 2005, 1866 . 1868 [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally 1869 Unique IDentifier (UUID) URN Namespace", RFC 4122, 1870 DOI 10.17487/RFC4122, July 2005, 1871 . 1873 [RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault, 1874 "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791, 1875 DOI 10.17487/RFC4791, March 2007, 1876 . 1878 [RFC5545] Desruisseaux, B., Ed., "Internet Calendaring and 1879 Scheduling Core Object Specification (iCalendar)", 1880 RFC 5545, DOI 10.17487/RFC5545, September 2009, 1881 . 1883 [RFC5546] Daboo, C., Ed., "iCalendar Transport-Independent 1884 Interoperability Protocol (iTIP)", RFC 5546, 1885 DOI 10.17487/RFC5546, December 2009, 1886 . 1888 [RFC5646] Phillips, A., Ed. and M. Davis, Ed., "Tags for Identifying 1889 Languages", BCP 47, RFC 5646, DOI 10.17487/RFC5646, 1890 September 2009, . 1892 [RFC5870] Mayrhofer, A. and C. Spanring, "A Uniform Resource 1893 Identifier for Geographic Locations ('geo' URI)", 1894 RFC 5870, DOI 10.17487/RFC5870, June 2010, 1895 . 1897 [RFC5988] Nottingham, M., "Web Linking", RFC 5988, 1898 DOI 10.17487/RFC5988, October 2010, 1899 . 1901 [RFC6047] Melnikov, A., Ed., "iCalendar Message-Based 1902 Interoperability Protocol (iMIP)", RFC 6047, 1903 DOI 10.17487/RFC6047, December 2010, 1904 . 1906 [RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type 1907 Specifications and Registration Procedures", BCP 13, 1908 RFC 6838, DOI 10.17487/RFC6838, January 2013, 1909 . 1911 [RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., 1912 "JavaScript Object Notation (JSON) Pointer", RFC 6901, 1913 DOI 10.17487/RFC6901, April 2013, 1914 . 1916 [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 1917 Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 1918 2014, . 1920 [RFC7265] Kewisch, P., Daboo, C., and M. Douglass, "jCal: The JSON 1921 Format for iCalendar", RFC 7265, DOI 10.17487/RFC7265, May 1922 2014, . 1924 [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, 1925 DOI 10.17487/RFC7493, March 2015, 1926 . 1928 [RFC7529] Daboo, C. and G. Yakushev, "Non-Gregorian Recurrence Rules 1929 in the Internet Calendaring and Scheduling Core Object 1930 Specification (iCalendar)", RFC 7529, 1931 DOI 10.17487/RFC7529, May 2015, 1932 . 1934 [RFC7986] Daboo, C., "New Properties for iCalendar", RFC 7986, 1935 DOI 10.17487/RFC7986, October 2016, 1936 . 1938 10.2. Informative References 1940 [draft-apthorp-ical-tasks] 1941 "Task Extensions to iCalendar", 1942 . 1944 [draft-daboo-valarm-extensions] 1945 "VALARM Extensions for iCalendar", 1946 . 1949 [draft-ietf-calext-ical-relations] 1950 "Support for iCalendar Relationships", 1951 . 1954 10.3. URIs 1956 [1] https://www.w3.org/TR/2011/REC-css3-color-20110607/#svg-color 1958 [2] http://www.iana.org/time-zones 1960 Authors' Addresses 1962 Neil Jenkins 1963 FastMail 1964 PO Box 234 1965 Collins St West 1966 Melbourne VIC 8007 1967 Australia 1969 Email: neilj@fastmailteam.com 1970 URI: https://www.fastmail.com 1972 Robert Stepanek 1973 FastMail 1974 PO Box 234 1975 Collins St West 1976 Melbourne VIC 8007 1977 Australia 1979 Email: rsto@fastmailteam.com 1980 URI: https://www.fastmail.com