The ical.js parser uses the design data available via ICAL.design to decide if the received data is semantically correct. It contains information about components, properties, property parameters and property values. There is specific design data for iCalendar, vCard 3 and vCard 4 which is used based on the component type or the passed design set.

ical.js解析器使用ICAL.design来判断接收到的数据,包含组件、属性、属性参数和属性值,语义是否正确。基于组件类型,支持识别iCalendar,vCard 3和vCard 4等类型,也可以传入其他的设计集合。

Not all aspects of the design data you see in design.js are actually enforced, a strict mode parser or validator is conceivable in the future.


注册属性数据(Registering property data)

If a new property is added for which the property name is not set in the design data, the default type unknown will be set in the jCal array as the type. While this is not incorrect and works well when converting from jCal to iCalendar by fully ommitting the VALUE parameter, in many cases you will want to register an explicit type for the property.


The iCalendar specification works with implicit value and parameter types, but allows explicitly mentioning the value data type through the VALUE parameter. jCal on the other hand explicitly mentions the value type in its array structure. During conversion from iCalendar to jCal, some assumptions have to be made if the value data type is not explicitly mentioned. This is mostly the case for X-Properties and additionally registered IANA properties.


While the iCalendar specification assumes that unknown values should be of the TEXT type, this doesn’t work in practice. If an extension to iCalendar has registered a property with the default type being PERIOD while also allowing multiple values, round-tripping between iCalendar and jCal will cause extra escaping of the comma character used to separate the values (FOO:bar,baz becomes FOO:bar\,baz).


To solve this, jCal has introduced the “unknown” type. It is used for all properties the parser doesn’t know about and keeps the value as it is. Lets say you have your own X-Property that uses multiple values and you want to retrieve them separately, or there is a new IANA property from an extension that has not been added to the ical.js design data. In the latter case, please file an issue to make sure it will be included in the future.


You can make sure your property is understood by adding information to the design set for the type of component you are working with:


// iCalendar: X-MY-PROPERTY:foo
//      jCal: ["x-my-property", {}, "text", "foo"]
ICAL.design.icalendar.property["x-my-property"] = {
  defaultType: "text", // [required] The default type from ICAL.design.value
  allowedTypes: ["period", "text"], // [optional] Valid value types this property can have (currently unused)
  detectType: function(value) { ... } // [optional] A function called to determine which type the value is

// iCalendar: X-MY-MULTIVAL:foo,bar,baz
//      jCal: ["x-my-multival", {}, "text", "foo", "bar", "baz"]
ICAL.design.icalendar.property["x-my-multival"] = {
  defaultType: "text", // [required] The default type from ICAL.design.value
  multiValue: "," // [optional] This property takes multiple, comma-separated values
                  //              and turns each of them into a jCal value.

// iCalendar: X-MY-STRUCTUREDVAL:foo;bar;baz
//      jCal: ["x-my-structuredval", {}, "text", [ "foo", "bar", "baz" ] ]
ICAL.design.icalendar.property["x-my-structuredval"] = {
  defaultType: "text", // [required] The default type from ICAL.design.value
  structuredValue: ";" // [optional] This property takes multiple, semicolon-separated values
                       //              and turns them into a single jCal value.

注册参数值类型(Registering parameter value types)

A parameter doesn’t have an explicit value type, but can be parsed in various ways. If you have your own parameters that need a different format, you can do it the following way:


//      jCal: ["summary", { "myenumparam": "FOO" }, "text", "value"]
ICAL.design.icalendar.param["myenumparam"] = {
  values: [ "FOO", "BAR" ],  // [optional] An array of valid values for this parameter
  allowXName: true, // If true, X-Parameters are also allowed
  allowIanaToken: true // If true, other IANA tokens are also allowed

// iCalendar: SUMMARY;MYTYPEDPARAM=user@example.com,user2@example.com:value
//      jCal: ["summary", { "mytypedparam": ["user@example.com", "user2@example.com" ] }, "text", "value" ]
ICAL.design.icalendar.param["mytypedparam"] = {
  valueType: "cal-address", // If set, the parameter must use this value type as a format
  multiValue: "," // The parameter can consist of multiple values itself, which will be an array

// iCalendar: SUMMARY;MYMULTIPARAM="FOO","BAR":value
//      jCal: ["summary", { "mymultiparam": ["FOO", "BAR"] }, "text", "value"]
ICAL.design.icalendar.param["mymultiparam"] = {
  valueType: "text", // If set, the parameter must use this value type as a format
  multiValue: ",", // The parameter can consist of multiple values itself, which will be an array
  multiValueSeparateDQuote: true // If true, double quotes enclose (multi-)values instead of the whole property.

注册值类型(Registering data value types)

Registering a new data value type is rather unlikely, this is usually the result of a new RFC defining a value type. Data value types are things like “text”, “recur”, “cal-address”. If this does happen, please file an issue. Here is the code to register a value type:


ICAL.design.icalendar.value["newvalue"] = { ... };

The object passed may optionally contain the following functions and properties:

  • decorate and undecorate: Functions to augment the way the value is returned (i.e. as ICAL.Duration)
  • fromICAL and toICAL: Functions to modify the way the value is formatted between iCalendar and jCal
  • values: An array of valid values for this value type (currently unused)
  • matches: A regular expression the value type must match (currently unused)


  • decorateundecorate:用于增加新的返回方式(比如:ICAL.Duration)
  • fromICALtoICAL:用于在iCalendar和jCal之间修改返回值类型
  • values:包含一组有效的值类型的数组(现在已废弃)
  • matches:值类型必须匹配的正则表达式(现在已废弃)

The functions are further described in the following sections.


在iCalendar和jCal之间转换数据(Conversion between iCalendar and jCal values)

Property value design data contains two functions called fromICAL and toICAL, which are used to convert property values between iCalendar and jCal. The type used depends on the value data type in jCal. Here are a few examples:


ICAL.design.icalendar.value['date-time'].fromICAL("20140102T030405"); // "2014-01-02T03:04:05"
ICAL.design.icalendar.value['date-time'].toICAL("2014-01-02T03:04:05"); // "20140102T030405"

ICAL.design.icalendar.value['recur'].fromICAL("FREQ=WEEKLY;COUNT=2"); // { freq: "WEEKLY", count: 2 }
ICAL.design.icalendar.value['recur'].toICAL({ freq: "WEEKLY", count: 2 }); // "FREQ=WEEKLY;COUNT=2"

包装值(Decorating Values)

Property value design data also contains two functions called decorate and undecorate. These are used on the next layer to take jCal data and turn it into a rich object that provides more methods to process the data value. These functions do not take raw iCalendar values, which are different especially for dates and recurrence. Examples:


var icalTime = ICAL.design.icalendar.value['date-time'].decorate("2014-01-02T03:04:05"); // Returns an ICAL.Time object
ICAL.design.icalendar.value['date-time'].undecorate(icalTime); // Returns "2014-01-02T03:04:05"

var icalRecur = ICAL.design.icalendar.value['recur'].decorate({ freq: "WEEKLY", count: 2 }); // Returns an ICAL.Recur object
ICAL.design.icalendar.value['recur'].undecorate(icalRecur); // Returns { freq: "WEEKLY", count: 2 }