Skip to content
Crystal Shard for parsing and generating info in line with iCalendar Specifications.
Crystal Makefile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


A Crystal library for parsing and generating calendar data with the iCalendar Specification.

DO NOT USE. Still a work in progress, many changes to come.


Add this to your application's shard.yml:

    github: HCLarsen/


require "iCal"


The method will read an ICS stream either from a local file, or a remote address. To read a local file, pass in a string of the local filename and path.

filename = File.join(File.dirname(__FILE__), "files", "FIFA_World_Cup_2018.ics")
calendar =
calendar.class  #=> Calendar

In the case of a remote stream, pass in a URI object with the address of the stream.

address = ""
uri = URI.parse(address)
calendar =  #=> #<IcalParser::Calendar:0x10868a5c0>
calendar.class  #=> Calendar

In most cases, an iCalendar stream will only contain one calendar object. However, the specification does allow for multiple calendar objects to be sequentially grouped in a single stream. If you are reading such a stream, the method will only return the first calendar object. If you are working with a stream that may have multiple calendar objects, it's best to use the ICSStream#read_calendars method instead to get an array of Calendar objects.

filename = File.join(File.dirname(__FILE__), "files", "FIFA_World_Cup_2018.ics")
calendars = ICSStream.read_calendars(filename)  #=> [#<IcalParser::Calendar:0x10e733100]
calendars.class  #=> Array(Calendar)

Calendar Object & Components

The Calendar class serves as a container for both the calendar properties and the calendar components. The standard calendar components, EVENT, TODO and so forth are accessed as arrays from the calendar object.       #=> [#<IcalParser::Event:0x102776f20...] #=> #<IcalParser::Event:0x102776f20>

For both the calendar object and calendar components, standard properties are accessed directly by the name of the property. These methods have names that correspond directly to the name of the property in the RFC5545 specification, with two exceptions. The first being the CLASS property, which is referred to as classification, to avoid conflicting with the Object#class method. The second is any property that may occur more than once in the component, in which case the accessor is the pluralized version of the property name.

# After parsing this event:
# DTSTAMP:19970901T130000Z
# DTSTART:19970903T163000Z
# DTEND:19970903T190000Z
# SUMMARY:Annual Employee Review

event.summary         #=> "Annual Employee Review"
event.classification  #=> "PRIVATE"
event.class           #=> IcalParser::Event
event.categories      #=> ["BUSINESS", "HUMAN RESOURCES"]

Non-standard and IANA properties are accessed by hash notation.

# After these lines are parsed:

event["DRESSCODE"]  #=> "CASUAL"
event["NON-SMOKING"]  #=> True


Where possible, property values are returned as the corresponding Crystal core data type. TEXT values are returned as Strings; Date, Time and Date-Times are returned as Time, Integer is returned as Int32, and so forth.

For values that don't have a corresponding Crystal core class, those types are provided by this module. These include CalAddress, PeriodOfTime, Duration and Recur.


  1. Fork it ( )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request


  • HCLarsen Chris Larsen - creator, maintainer
You can’t perform that action at this time.