Git Product home page Git Product logo

icalendar's Introduction

iCalendar -- Internet calendaring, Ruby style

Ruby Code Climate

http://github.com/icalendar/icalendar

Upgrade from 1.x

Better documentation is still to come, but in the meantime the changes needed to move from 1.x to 2.0 are summarized by the diff needed to update the README

DESCRIPTION

iCalendar is a Ruby library for dealing with iCalendar files in the iCalendar format defined by RFC-5545.

EXAMPLES

Creating calendars and events

require 'icalendar'

# Create a calendar with an event (standard method)
cal = Icalendar::Calendar.new
cal.event do |e|
  e.dtstart     = Icalendar::Values::Date.new('20050428')
  e.dtend       = Icalendar::Values::Date.new('20050429')
  e.summary     = "Meeting with the man."
  e.description = "Have a long lunch meeting and decide nothing..."
  e.ip_class    = "PRIVATE"
end

cal.publish

Or you can make events like this

event = Icalendar::Event.new
event.dtstart = DateTime.civil(2006, 6, 23, 8, 30)
event.summary = "A great event!"
cal.add_event(event)

event2 = cal.event  # This automatically adds the event to the calendar
event2.dtstart = DateTime.civil(2006, 6, 24, 8, 30)
event2.summary = "Another great event!"

Support for property parameters

params = {"altrep" => "http://my.language.net", "language" => "SPANISH"}

event = cal.event do |e|
  e.dtstart = Icalendar::Values::Date.new('20050428')
  e.dtend   = Icalendar::Values::Date.new('20050429')
  e.summary = Icalendar::Values::Text.new "This is a summary with params.", params
end
event.summary.ical_params #=> {'altrep' => 'http://my.language.net', 'language' => 'SPANISH'}

# or

event = cal.event do |e|
  e.dtstart = Icalendar::Values::Date.new('20050428')
  e.dtend   = Icalendar::Values::Date.new('20050429')
  e.summary = "This is a summary with params."
  e.summary.ical_params = params
end
event.summary.ical_params #=> {'altrep' => 'http://my.language.net', 'language' => 'SPANISH'}

Support for Dates or DateTimes

Sometimes we don't care if an event's start or end are Date or DateTime objects. For this, we can use DateOrDateTime.new(value). Calling .call on the returned DateOrDateTime will immediately return the underlying Date or DateTime object.

event = cal.event do |e|
  e.dtstart = Icalendar::Values::DateOrDateTime.new('20140924')
  e.dtend   = Icalendar::Values::DateOrDateTime.new('20140925').call
  e.summary = 'This is an all-day event, because DateOrDateTime will return Dates'
end

Support for URLs

For clients that can parse and display a URL associated with an event, it's possible to assign one.

event = cal.event do |e|
  e.url = 'https://example.com'
end

We can output the calendar as a string

cal_string = cal.to_ical
puts cal_string

ALARMS

Within an event

cal.event do |e|
  # ...other event properties
  e.alarm do |a|
    a.action          = "EMAIL"
    a.description     = "This is an event reminder" # email body (required)
    a.summary         = "Alarm notification"        # email subject (required)
    a.attendee        = %w(mailto:[email protected] mailto:[email protected]) # one or more email recipients (required)
    a.append_attendee "mailto:[email protected]"
    a.trigger         = "-PT15M" # 15 minutes before
    a.append_attach   Icalendar::Values::Uri.new("ftp://host.com/novo-procs/felizano.exe", "fmttype" => "application/binary") # email attachments (optional)
  end

  e.alarm do |a|
    a.action  = "DISPLAY" # This line isn't necessary, it's the default
    a.summary = "Alarm notification"
    a.trigger = "-P1DT0H0M0S" # 1 day before
  end

  e.alarm do |a|
    a.action        = "AUDIO"
    a.trigger       = "-PT15M"
    a.append_attach "Basso"
  end
end

Output

# BEGIN:VALARM
# ACTION:EMAIL
# ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-procs/felizano.exe
# TRIGGER:-PT15M
# SUMMARY:Alarm notification
# DESCRIPTION:This is an event reminder
# ATTENDEE:mailto:[email protected]
# ATTENDEE:mailto:[email protected]
# END:VALARM
#
# BEGIN:VALARM
# ACTION:DISPLAY
# TRIGGER:-P1DT0H0M0S
# SUMMARY:Alarm notification
# END:VALARM
#
# BEGIN:VALARM
# ACTION:AUDIO
# ATTACH;VALUE=URI:Basso
# TRIGGER:-PT15M
# END:VALARM

Checking for an Alarm

Calling the event.alarm method will create an alarm if one doesn't exist. To check if an event has an alarm use the has_alarm? method.

event.has_alarm?
# => false

event.alarm
# => #<Icalendar::Alarm ... >

event.has_alarm?
#=> true

TIMEZONES

cal = Icalendar::Calendar.new
cal.timezone do |t|
  t.tzid = "America/Chicago"

  t.daylight do |d|
    d.tzoffsetfrom = "-0600"
    d.tzoffsetto   = "-0500"
    d.tzname       = "CDT"
    d.dtstart      = "19700308T020000"
    d.rrule        = "FREQ=YEARLY;BYMONTH=3;BYDAY=2SU"
  end

  t.standard do |s|
    s.tzoffsetfrom = "-0500"
    s.tzoffsetto   = "-0600"
    s.tzname       = "CST"
    s.dtstart      = "19701101T020000"
    s.rrule        = "FREQ=YEARLY;BYMONTH=11;BYDAY=1SU"
  end
end

Output

# BEGIN:VTIMEZONE
# TZID:America/Chicago
# BEGIN:DAYLIGHT
# TZOFFSETFROM:-0600
# TZOFFSETTO:-0500
# TZNAME:CDT
# DTSTART:19700308T020000
# RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
# END:DAYLIGHT
# BEGIN:STANDARD
# TZOFFSETFROM:-0500
# TZOFFSETTO:-0600
# TZNAME:CST
# DTSTART:19701101T020000
# RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
# END:STANDARD
# END:VTIMEZONE

iCalendar has some basic support for creating VTIMEZONE blocks from timezone information pulled from tzinfo. You must require tzinfo support manually to take advantage.

iCalendar has been tested and works with tzinfo versions 0.3, 1.x, and 2.x. The tzinfo-data gem may also be required depending on your version of tzinfo and potentially your operating system.

Example

require 'icalendar/tzinfo'

cal = Icalendar::Calendar.new

event_start = DateTime.new 2008, 12, 29, 8, 0, 0
event_end = DateTime.new 2008, 12, 29, 11, 0, 0

tzid = "America/Chicago"
tz = TZInfo::Timezone.get tzid
timezone = tz.ical_timezone event_start
cal.add_timezone timezone

cal.event do |e|
  e.dtstart = Icalendar::Values::DateTime.new event_start, 'tzid' => tzid
  e.dtend   = Icalendar::Values::DateTime.new event_end, 'tzid' => tzid
  e.summary = "Meeting with the man."
  e.description = "Have a long lunch meeting and decide nothing..."
  e.organizer = "mailto:[email protected]"
  e.organizer = Icalendar::Values::CalAddress.new("mailto:[email protected]", cn: 'John Smith')
end

Parsing iCalendars

# Open a file or pass a string to the parser
cal_file = File.open("single_event.ics")

# Parser returns an array of calendars because a single file
# can have multiple calendars.
cals = Icalendar::Calendar.parse(cal_file)
cal = cals.first

# Now you can access the cal object in just the same way I created it
event = cal.events.first

puts "start date-time: #{event.dtstart}"
puts "start date-time timezone: #{event.dtstart.ical_params['tzid']}"
puts "summary: #{event.summary}"

You can also create a Parser instance directly, this can be used to enable strict parsing:

# Sometimes you want to strongly verify only rfc-approved properties are
# used
strict_parser = Icalendar::Parser.new(cal_file, true)
cal = strict_parser.parse

Parsing Components (e.g. Events)

# Open a file or pass a string to the parser
event_file = File.open("event.ics")

# Parser returns an array of events because a single file
# can have multiple events.
events = Icalendar::Event.parse(event_file)
event = events.first

puts "start date-time: #{event.dtstart}"
puts "start date-time timezone: #{event.dtstart.ical_params['tzid']}"
puts "summary: #{event.summary}"

Finders

Often times in web apps and other interactive applications you'll need to lookup items in a calendar to make changes or get details. Now you can find everything by the unique id automatically associated with all components.

cal = Calendar.new
10.times { cal.event } # Create 10 events with only default data.
some_event = cal.events[5] # Grab it from the array of events

# Use the uid as the key in your app
key = some_event.uid

# so later you can find it.
same_event = cal.find_event(key)

Examples

Check the unit tests for examples of most things you'll want to do, but please send me example code or let me know what's missing.

Download

The latest release version of this library can be found at

Installation

It's all about rubygems:

$ gem install icalendar

Testing

To run the tests:

$ bundle install
$ rake spec

License

This library is released under the same license as Ruby itself.

Support & Contributions

Please submit pull requests from a rebased topic branch and include tests for all bugs and features.

Contributor Code of Conduct

As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.

Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.

This Code of Conduct is adapted from the Contributor Covenant, version 1.1.0, available at http://contributor-covenant.org/version/1/1/0/

icalendar's People

Contributors

antoinelyset avatar bnjamin avatar bouzuya avatar bwalding avatar ericcf avatar grosser avatar gshutler avatar guillaumebriday avatar jakecraige avatar jnv avatar jopotts avatar kaoru avatar kaspth avatar markrickert avatar mcr avatar nielslaukens avatar pawelniewie avatar radar avatar rahearn avatar reiz avatar rikuson avatar rthbound avatar rubyredrick avatar sdague avatar seansfkelley avatar stefan-kolb avatar tcannonfodder avatar timcraft avatar tisdall avatar zerobearing2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

icalendar's Issues

Avoid outlook specific instructions

When I import an outlook exported calendar we have non stardard lines. Can we skip them?
Like:

X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INTENDEDSTATUS:FREE
X-MICROSOFT-DISALLOW-COUNTER:FALSE
X-MS-OLK-ALLOWEXTERNCHECK:TRUE
X-MS-OLK-AUTOSTARTCH

The last line throws an error with

`

<RuntimeError: Invalid iCalendar input line: X-MS-OLK-AUTOSTARTCH>

`

loses CN field when parsing attendees

Hi,

my organization's zimbra uses the CN field of ATTENDEE properties to store useful info, such as the phone number to call for a conf-call. An example is:

ATTENDEE;RSVP=TRUE;CN="Ligne : 01767123624, Organisateur : 81234569, Participant : 87411234";PARTSTAT=NEEDS-ACTION;CUTYPE=RESOURCE;ROLE=NON-PARTICIPANT:mailto:[email protected]

icalendar's parsing of this attendee results in an URI::MailTo object, with only the email address, while the information I really want is in the CN field. Could you pass the CN field in addition to the mailto field when creating the MailTo object, so that it becomes a header known from MailTo?

Thanks,

Lucas

event on iPhone not updating

When I open a new ical file that has the same UID of a previously added event it is not updating the date of the existing calendar event on my iPhone. It works correctly with the desktop email client but not on the iPhone. If I manually delete the event then open the ical file again it works. Any ideas what the issue could be?

NoMethodError: undefined method `to_ical' for "CDT":String

Hi,

I'm just trying the gem and I have an error with your timezone examples.
I've just tried this one :

cal = Icalendar::Calendar.new
cal.timezone do |t|
  t.tzid = "America/Chicago"

  t.daylight do |d|
    d.tzoffsetfrom = "-0600"
    d.tzoffsetto   = "-0500"
    d.tzname       = "CDT"
    d.dtstart      = "19700308T020000"
    d.rrule        = "FREQ=YEARLY;BYMONTH=3;BYDAY=2SU"
  end

  t.standard do |s|
    s.tzoffsetfrom = "-0500"
    s.tzoffsetto   = "-0600"
    s.tzname       = "CST"
    s.dtstart      = "19701101T020000"
    s.rrule        = "FREQ=YEARLY;BYMONTH=11;BYDAY=1SU"
  end
end

When I execute :

cal.to_ical

I got this error message :

=> #<NoMethodError: undefined method `to_ical' for "CDT":String>

Backtrace :

 [ 0] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:40:in `block (2 levels) in ical_properties'",
  [ 1] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:39:in `map'",
  [ 2] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:39:in `block in ical_properties'",
  [ 3] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:35:in `map'",
  [ 4] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:35:in `ical_properties'",
  [ 5] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:26:in `to_ical'",
  [ 6] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:63:in `block (2 levels) in ical_components'",
  [ 7] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:62:in `each'",
  [ 8] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:62:in `block in ical_components'",
  [ 9] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:60:in `each'",
  [10] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:60:in `ical_components'",
  [11] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:27:in `to_ical'",
  [12] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:63:in `block (2 levels) in ical_components'",
  [13] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:62:in `each'",
  [14] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:62:in `block in ical_components'",
  [15] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:60:in `each'",
  [16] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:60:in `ical_components'",
  [17] "/Users/lyset/.gem/ruby/1.9.3/gems/icalendar-2.1.0/lib/icalendar/component.rb:27:in `to_ical'"

As you can see :

Version : 2.1.0
Ruby Version : 1.9.3

I will digg a bit more tomorrow to see if I can come with a fix (or just use 1.0). Thanks in advance.

Time zone conversions

I need to be able to support importing calendars from both Outlook and Calendar in OSX. The Calendar app sends the dtstart and dtend already converted for time zone. Example:

outlook.ics

DTSTART:20130725T170000Z

calendar.ics

DTSTART;TZID=America/Chicago:20130725T120000

As you can see, both times are the same, but the one from OSX is already converted. Is there a way to detect the TZID on the individual datetime attributes or otherwise detect this difference? Maybe ideas for a patch?

Attendee parameters

There are a variety of other parameters that can be sent with the ATTENDEE property. The two most important being the CN (name) and the PARTSTAT (accepted, cancelled etc.). Currently, I only see one part that is possible with the current implementation and that is the mailto. Is this correct or is there a workaround that is non-obvious? If this isn't possible right now, then I'll be creating a pull req.

Can't get alarms to work

I'm currently working on a Rails 4 app and have integrated the icalendar gem into it for exporting Callouts as an ICS.
I'm then adding the ICS URL to Outlook as a calendar but reminders/alert aren't working or showing that it has been set.

This is the code I'm using. I've used many ways of doing it with no luck.

def generate_ical
    cal = Calendar.new

    @callouts.each do |callout|
      cal.event do
        dtstart       callout.date.strftime("%Y%m%dT%H%M%SZ")
        dtend         callout.date.advance(hours: 1).strftime("%Y%m%dT%H%M%SZ")
        summary       "Callout to #{callout.customer.to_s}"
        # description   "#{callout.info} -- #{callout.customer.full_address}"
        description   callout.info

        alarm do
          action        "DISPLAY"
          summary       "Alarm notification"
          trigger       "-PT15M"
        end

        alarm do
          action        "AUDIO"
          trigger       "-PT15M"
        end
      end
    end

    cal.publish

    cal.to_ical
  end

Would be great to see this resolved as I've been scratching my head for ages over this.
I've tried both Outlook 2010 and 2013 and they both show the reminder as "none".

Dealing with TIme.zone dates

I've come across an issue in my Rails 2.3 app where I had to convert my standard Time.zone dates to DateTime dates (i.e. with to_datetime). Not sure if this is a bug or just a requirement. If it's a requirement I don't mind submitting a pull request with the documentation change. I couldn't find where the dtstart etc... values are converted in this gem so I'm not sure how it's done :)

I should say that until converting the Time.zone type dates to DateTime's the gem was just rendering out the time without the date.

Rake version

Is the requirement to use a pre-10 version of rake to do with hoe or is it an icalendar thing? If the latter I'm happy to work on any patches that need doing as this gem seems to be exactly what I need.

avoid "Info: No TimeWithZone support"

Hiho, I installed icalendar through bundle install and want to use it in a commandline tool. But it prints this "Info: No TimeWithZone support" all the time.

Is there a way to avoid this info without installing ActiveSupport as well?

thank you

Incorrect syntax when adding attendee and organizer

Hi,
the add_attendee and organizer= methods are outputting incorrect ics syntaxes,

For the attendee there are two issues, the ":" after "ATTENDEE should be ";" according to the documentation of icalendar, and "" are mysteriously added before the ";"

if you write:
event.add_attendee "CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;CN=test;X-NUM-GUESTS=0:mailto:[email protected]"

you get:
ATTENDEE:CUTYPE=INDIVIDUAL;ROLE=REQ PARTICIPANT;PARTSTAT=TENTATIVE;CN=test ;
X-NUM-GUESTS=0:mailto:[email protected]

For the organizer I got the same kind of issue, the ":" after "ORGANIZER" should be ";"
ORGANIZER:CN=Vodeclic:mailto:[email protected]

For the moment I can only use some ugly and unsafe gsub to avoid these problems:
cal.to_ical.gsub("ORGANIZER:", "ORGANIZER;").gsub("ATTENDEE:", "ATTENDEE;").gsub(';', ';')

Could you please help me to understand what's wrong or fix this issue please ?

Thank you in advance for your help,

Best regards

superclass mismatch for class Event

Hi,

I have my own class Event and when I added:

require 'icalendar'
require 'date'
include Icalendar

to my own Event model,

I encountered "superclass mismatch for class Event"
irb(main):001:0> Event.new

Class:0x5be81a8: superclass mismatch for class Event

    from .../app/models/event.rb:5:in `<top (required)>'

What can I do about this? Thanks in advance.

Alarms triggers lose data

According to RFC-2445, an alarm is by default relative to the event (or todo) start time, but it may also be:

  • relative to the end time, eg:
    TRIGGER;RELATED=END:P5M
  • an absolute date-time eg:
    TRIGGER;VALUE=DATE-TIME:19980101T050000Z

http://www.kanzaki.com/docs/ical/trigger.html

In these cases, the parser strips out the extra parameters. In order words, anything between the semi-colon and colon is lost.

It would be nice to keep these to allow someone to parse these correctly.

Update README

README contents still reflect 1.x code. Update with examples for 2.x syntax

One test fails with ruby 1.9.3

Hi,
one of ical's test fails for me, here is the test output:

  1. Failure:
    test_property_parameters(TestComponent) [/home/bkabrda/rpmbuild/BUILDROOT/rubygem-icalendar-1.1.6-2.fc16.x86_64/usr/share/gems/gems/icalendar-1.1.6/test/test_parameter.rb:31]:
    <{"ALTREP"=>[""http://my.language.net""], "LANGUAGE"=>["SPANISH"]}> expected but was
    <{"ALTREP"=>[]}>.

ruby -v: ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]

Any ideas?
Thanks,
Bohuslav.

Escaping attendee and organizer CN values

If an attendee or organizer has a CN of Joe "the man" Tester and is set to an event then:

event = Event.new
event.add_attendee(attendee.email, {
  'PARTSTAT' => 'ACCEPTED',
  'CN' => attendee.name # Unescaped name
})

event.to_ical
# => ATTENDEE;PARTSTAT=ACCEPTED;CN=Joe "the man" Tester:[email protected]

The result is a CN that is considered invalid and will break most iCal parsers and validators. The correct way is to escape the reserved characters with a \. Therefore, the previous name would look like Joe \"the man\" Tester. The characters that need escaping are "", ";", ",", "\N", and "\n" according to the rfc. This is only true for TEXT value parameters.

Is there a way to implement this constraint internally with the icalendar gem currently? I'm looking through the code now and am missing it if it's there. I'm also evaluating if it could be possible to add this. It seems that there would need to be a way of detecting the parameter and then it's type whereas now the parameters are just passed through as plain ruby strings with no type checks or validations. Does anyone else have any thoughts or ideas about this?

Ruby 2.0 failling tests

There is 7 errors when launching spec with Ruby 2:

test_property_parameters(TestParameter):
RuntimeError: can't modify frozen Fixnum
    component.rb:231:in `sequence'
    lib/icalendar/parser.rb:180:in `parse_component'
    lib/icalendar/parser.rb:132:in `parse_component'
    lib/icalendar/parser.rb:102:in `parse'

Always a RuntimeError: can't modify frozen Fixnum

Not showing Accept/Decline/Tentative buttons with few mail clients.

I am sending ics file as attachment with email and it was opening good in Gmail.
However, i am facing issues with different mail clients.

I tried adding this property:
calendar.custom_property("METHOD", "REQUEST")

It was not showing Accept/Decline/Tentative buttons for Outlook, Yahoo mail clients.

Do i need to add any more properties to detect ?

Thanks in advance.

Custom Property support

Is custom properties supported when parsing a calendar?

For instance, I wrote up the details of my particular situation on StackOverflow.

I'm trying to parse a calendar that has custom fields like this:

X-TRUMBA-CUSTOMFIELD;NAME="Event Location";ID=10831;TYPE=SingleLine:Lower Level\, 
across from the Stars and Stripes Cafe

Would you be able to recommend how I should go about trying to parse something like this?

Thanks!

icalendar 1.1.3 fails test_block_creation(TestTimezone) [./test/component/test_timezone.rb:68

When running icalendar's tests I get the following failure:

Started
.........BEGIN:VCALENDAR
CALSCALE:GREGORIAN
PRODID:iCalendar-Ruby
VERSION:2.0
BEGIN:VEVENT
DTSTAMP:20100329T080931
SEQUENCE:0
SUMMARY;LANGUAGE=SPANISH;ALTREP="http://my.language.net":This is a test sum
mary.
UID:2010-03-29T08:09:31+02:00_414945979@graaff
END:VEVENT
END:VCALENDAR
[#<Icalendar::Calendar:0x7f026c0b6e20
@components=
{:events=>
[#<Icalendar::Event:0x7f026c0b4eb8
@components={},
@name="VEVENT",
@properties=
{"sequence"=>0,
"uid"=>"2010-03-29T08:09:31+02:00_414945979@graaff",
"dtstamp"=>#<DateTime: 212136610171/86400,0,2299161>,
"summary"=>"This is a test summary."}>]},
@name="VCALENDAR",
@properties=
{"version"=>"2.0", "calscale"=>"GREGORIAN", "prodid"=>"iCalendar-Ruby"}>]
.........nil 1997-09-03T16:30:00+00:00
....America/Chicago 1997-09-03T16:30:00+00:00
...UTC 1997-09-03T16:30:00+00:00
........F...
Finished in 0.172987 seconds.

  1. Failure:
    test_block_creation(TestTimezone) [./test/component/test_timezone.rb:68]:
    <"BEGIN:VTIMEZONE\r\nTZID:America/Chicago\r\nBEGIN:STANDARD\r\nDTSTART:19701101T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nTZNAME:CST\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0600\r\nEND:STANDARD\r\nBEGIN:DAYLIGHT\r\nDTSTART:19700308TO20000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU\r\nTZNAME:CDT\r\nTZOFFSETFROM:-0600\r\nTZOFFSETTO:-0500\r\nEND:DAYLIGHT\r\nEND:VTIMEZONE\r\n"> expected but was
    <"BEGIN:VTIMEZONE\r\nTZID:America/Chicago\r\nBEGIN:DAYLIGHT\r\nDTSTART:19700308TO20000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU\r\nTZNAME:CDT\r\nTZOFFSETFROM:-0600\r\nTZOFFSETTO:-0500\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nDTSTART:19701101T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU\r\nTZNAME:CST\r\nTZOFFSETFROM:-0500\r\nTZOFFSETTO:-0600\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\n">.

37 tests, 83 assertions, 1 failures, 0 errors

Marshal.dump fails

Marshal.dump fails when applied to Calendar objects with error can't dump hash with default proc (TypeError).

Here is an example that fails with the mentioned error:

require 'icalendar'

# Create a calendar with an event (standard method)
cal = Icalendar::Calendar.new
cal.event do |e|
  e.dtstart     = Icalendar::Values::Date.new('20050428')
  e.dtend       = Icalendar::Values::Date.new('20050429')
  e.summary     = "Meeting with the man."
  e.description = "Have a long lunch meeting and decide nothing..."
  e.ip_class    = "PRIVATE"
end

Marshal.dump(cal)

Marshalling worked fine with v. 1.5.

events with time on heroku not showing in Apple Calendar

I build the following feed with start times like so:

  e.start     = Time.zone.parse("#{date.to_s} #{time.hour}:#{time.min}").to_datetime

The event show up perfectly fine in Apple Calendar, if I use just the date

e.start = date

This is true locally as well as on heroku. As soon as I add the time component, I see the events showing up locally, but after deploying to heroku, the events with a time component vanish from Apple Calendar. However, I can see the events in the raw ics feed and the time looks correct:

DTSTART:20130412T120000

I also tried to use UTC instead of local time and I tried to set the dtstart attribute directly to a correct UTC string. In that instance, the string also shows up correctly in the ics feed, but the event vanishes from Apple Calendar:

DTSTART:20130412T100000Z

What am I missing? Are there any formatting errors that might happen to the feed on heroku, but not locally? Is it a bug? I compared the generated feed to working feeds (like from Stanford) and could not find any difference in the time part of the events (Stanford uses the UTC format).

Global timezone registry

Create a timezone registry to ensure that a printed calendar has a VTIMEZONE component for every TZID used in other components.

Time zones for events don't work

An icalendar event with time zone properly specified uses the the format as follows:

DTSTART;TZID=Australia/Perth:20130607T090000
DTEND;TZID=Australia/Perth:20130607T093000

Note the lower case.

This specifies an event that occurs on June 7, 2013 from 9 am until 9:30 am in WST.

However, the icalendar gem doesn't allow this format to be successfully produced. Specifying a tzid for the Icalendar::Event object has no effect. Even when a custom property is used as follows, the time zone is converted to upper case, rendering it useless.

event.custom_property("DTSTART;TZID=Australia/Perth", start_time.strftime("%Y%m%dT%H%M%S"))

I'll try to provide a patch for this over the coming days.

Add logging

Use logging library to enable applications to control logging output

How to create all-day events?

The documentation should include an example how to create an all-day event as this seems to have changed from the 1.x version. The following start/end is not recognized as several all-days events but maybe this is correct.

DTSTART:20140209T000000
DTEND:20140215T000000

Attachment params breaking change after 1.5.0

Consider the following code:

    cal = Calendar.new
      cal.event do
        dtstart DateTime.new(1997,5)
        dtend DateTime.new(3000,1)
        summary "Imported Contact"
        description "To import contact open attachment"
        attachment_params = {
           "ENCODING" => "BASE64", 
           "FMTYPE" => "text/directory", 
           "VALUE" => "BINARY",
           "X-APPLE-FILENAME" => “1234.vcf"
        }
        foo = "QkVHSU46VkNBUkQKVkVSU0lPTjozLjAKRk46Sm9obiBTbWl0aApBRFI7TEFCRUw9MTI"
        add_attachment foo, attachment_params
      end
    cal.to_ical

In version 1.5.0 it produces this:

"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nPRODID:
iCalendar-Ruby\r\nBEGIN:VEVENT\r\nATTACH;ENCODING=BASE64;FMTYPE=
text/directory;VALUE=BINARY;X-APPLE-FILENAME=\r\n 1234.vcf:QkVHS
U46VkNBUkQKVkVSU0lPTjozLjAKRk46Sm9obiBTbWl0aApBRFI7TEFCRUw9MT\r\
n I\r\nDESCRIPTION:To import contact open attachment\r\nDTEND:30
000101T000000\r\nDTSTAMP:20140403T180003\r\nDTSTART:19970501T000
000\r\nSEQUENCE:0\r\nSUMMARY:Imported Contact\r\nUID:2014-04-03T
18:00:03-07:00_149868479@localhost\r\nEND:VEVENT\r\nEND:VCALENDA
R\r\n"

In versions 1.5.1 and 1.5.2 it produces this:

"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nCALSCALE:GREGORIAN\r\nPRODID:
iCalendar-Ruby\r\nBEGIN:VEVENT\r\nATTACH:QkVHSU46VkNBUkQKVkVSU0l
PTjozLjAKRk46Sm9obiBTbWl0aApBRFI7TEFCRUw9MTI\r\nDESCRIPTION:To i
mport contact open attachment\r\nDTEND:30000101T000000\r\nDTSTAM
P:20140404T010252Z\r\nDTSTART:19970501T000000\r\nSEQUENCE:0\r\nS
UMMARY:Imported Contact\r\nUID:2014-04-03T18:02:52-07:00_5016404
17@localhost\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"

The attachment params do not seem to have come through.

SyntaxError for icalendar-1.5.0

I am using backlog-1.0.6 as a plugin of redmine-2.2.4, so it refs icalendar-1.5.0.

bundle install worked well, while rake failed with a SyntaxError ?

I am using ruby-1.8.7 and gem-1.8.15.

Error msg looks like below:

component.rb:206:in `generate_multi_setter': compile error (SyntaxError)
component.rb:201: undefined (?...) sequence: /^[^"].*(?<!\\),.*[^"]$/
component.rb:202: undefined (?...) sequence: /(?<!\\),/
        from /var/lib/gems/1.8/gems/icalendar-1.5.0/lib/icalendar/component.rb:244:in `ical_multi_property'
        from /var/lib/gems/1.8/gems/icalendar-1.5.0/lib/icalendar/component/event.rb:80
        from /var/lib/gems/1.8/gems/icalendar-1.5.0/lib/icalendar.rb:28:in `require'
        from /var/lib/gems/1.8/gems/icalendar-1.5.0/lib/icalendar.rb:28
        from /var/lib/gems/1.8/gems/bundler-1.3.5/lib/bundler/runtime.rb:72:in `require'
        from /var/lib/gems/1.8/gems/bundler-1.3.5/lib/bundler/runtime.rb:72:in `require'
        from /var/lib/gems/1.8/gems/bundler-1.3.5/lib/bundler/runtime.rb:70:in `each'
        from /var/lib/gems/1.8/gems/bundler-1.3.5/lib/bundler/runtime.rb:70:in `require'
        from /var/lib/gems/1.8/gems/bundler-1.3.5/lib/bundler/runtime.rb:59:in `each'
        from /var/lib/gems/1.8/gems/bundler-1.3.5/lib/bundler/runtime.rb:59:in `require'
        from /var/lib/gems/1.8/gems/bundler-1.3.5/lib/bundler.rb:132:in `require'
        from /data/redmine/config/application.rb:7
        from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
        from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `require'
        from /data/redmine/config/environment.rb:2
        from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
        from /usr/lib/ruby/vendor_ruby/1.8/rubygems/custom_require.rb:36:in `require'
        from config.ru:4
        from /var/lib/gems/1.8/gems/rack-1.4.5/lib/rack/builder.rb:51:in `instance_eval'
        from /var/lib/gems/1.8/gems/rack-1.4.5/lib/rack/builder.rb:51:in `initialize'
        from config.ru:1:in `new'
        from config.ru:1

ICS files created with Icalendar::Calendar.to_ical will not import into the Apple Calendar Program

I am creating simple single event ICS files using Icalendar.

The code is listed below. Here's the problem:

When I hit this link (http://<server>/teams/<id>/events/<id>.ics) I get a file with the correct encoding and correct filename. I can import this file into Google Calendar no problem. When I try to open it with Apple Calendar it says "Calendar can’t read this calendar file. No events have been added to your calendar." Now, here's the weird part: I can open this file in my text editor (Sublime Text), save the file without making any changes and then it imports without a hitch into Apple Calendar.

I've done a binary diff on the file and the only difference is that the last line of the file:

END:VCALENDAR

Ends with 0D0A in the file that works and simply 0A in the file that doesn't.

I've tried adding a "\n" to the string produced by to_ical but that actually had no affect at all.

Any ideas? Could this be a bug in the lib or perhaps in rails' handling of this content type?

Here's the helper code:

    def format_time_for_ical(time)
        time.strftime('%Y%m%dT%H%M00Z')
    end
    def render_event_in_icalendar(event, authentication_token = nil)
        calevt = Icalendar::Event.new
        calevt.start = format_time_for_ical event.start_time
        calevt.end = format_time_for_ical event.end_time
        calevt.created = calevt.timestamp = format_time_for_ical event.created_at
        calevt.last_modified = format_time_for_ical event.updated_at
        calevt.summary = event.title
        calevt.description = event.description
        calevt.location = event.location
        calevt.organizer = event.team.owner.email
        calevt.url = team_event_url event.team, event, :authentication_token => authentication_token
        calevt.uid = "playyon.com-#{event.id}"
        calevt
    end
    def render_icalendar(events, authentication_token = nil)
        cal = Icalendar::Calendar.new
        cal.prodid = "playyon.com"
        events.each do |event|
            cal.add render_event_in_icalendar(event, authentication_token)
        end
        cal.publish
        cal.to_ical
    end
    def render_icalendar_for_event(event, authentication_token = nil)
        render_icalendar([event], authentication_token)
    end

Here's the view code:

= render_icalendar_for_event(@event, @authentication_token)

Here's the controller code: (@event is set by a filter)

  # GET /team/events/1
  # GET /team/events/1.json
  def show
    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @event }
      format.ics do
        current_user.ensure_authentication_token
        @authentication_token = current_user.authentication_token
        response.headers['Content-Type'] = 'text/calendar; charset=UTF-8'
        response.headers['Content-Disposition'] = "attachment; filename=\"#{@event.team.name} - #{@event.title}.ics\""
      end
    end
  end

Parsing iCloud calendars doesn't work

When parsing an iCloud calendar, I get this error:

Icalendar::UnknownPropertyMethod: Unknown property type: uid

Originating from line 183 in parser.rb. I worked around this issue by ignoring the UID and ACKNOWLEDGED fields from the ics file in the parse_component method in parser.rb:

def parse_component(component = Calendar.new)
      # ... ommitted
        if name == "END"
          break
        # dirty fix for parsing iCloud calendars
        elsif name == "UID" || name == "ACKNOWLEDGED"
          next
        elsif name == "BEGIN" # New component
          # ... ommitted

I'd have implemented a proper fix if I could understand what exactly was going on here. Sorry about that.

Timezone support is broken for tzinfo 1.0.x / 1.1.0

Output of ➜ test git:(master) ruby test_tzinfo.rb

Loaded suite test_tzinfo
Started
EEEEE
Finished in 0.005385 seconds.

  1) Error:
test_daylight_offset(TestTZInfoExt):
NoMethodError: undefined method `offset_from' for #<TZInfo::TimezoneTransitionDefinition:0x00000001a4df48>
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:105:in `block in daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `tap'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:55:in `ical_timezone'
    test_tzinfo.rb:12:in `setup'

  2) Error:
test_dst_transition(TestTZInfoExt):
NoMethodError: undefined method `offset_from' for #<TZInfo::TimezoneTransitionDefinition:0x00000001a4df48>
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:105:in `block in daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `tap'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:55:in `ical_timezone'
    test_tzinfo.rb:12:in `setup'

  3) Error:
test_no_end_transition(TestTZInfoExt):
NoMethodError: undefined method `offset_from' for #<TZInfo::TimezoneTransitionDefinition:0x00000001a4df48>
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:105:in `block in daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `tap'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:55:in `ical_timezone'
    test_tzinfo.rb:12:in `setup'

  4) Error:
test_no_transition(TestTZInfoExt):
NoMethodError: undefined method `offset_from' for #<TZInfo::TimezoneTransitionDefinition:0x00000001a4df48>
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:105:in `block in daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `tap'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:55:in `ical_timezone'
    test_tzinfo.rb:12:in `setup'

  5) Error:
test_standard_offset(TestTZInfoExt):
NoMethodError: undefined method `offset_from' for #<TZInfo::TimezoneTransitionDefinition:0x00000001a4df48>
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:105:in `block in daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `tap'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:96:in `daylight'
    /home/mguentner/icalendar/icalendar/lib/icalendar/tzinfo.rb:55:in `ical_timezone'
    test_tzinfo.rb:12:in `setup'

5 tests, 0 assertions, 0 failures, 5 errors, 0 skips

Test run options: --seed 16226
*** LOCAL GEMS ***

atomic (1.1.14)
bundler (1.1.3)
gist (3.1.0)
icalendar (1.5.0)
rake (0.9.2.2)
rubygems-bundler (0.2.8)
rvm (1.11.3.3)
thread_safe (0.1.3)
timecop (0.7.0)
tzinfo (1.1.0)

When using tzinfo -v 0.3.38, the test suite finishes with 0 errors.

Parse & read ATTENDEE parameters?

When parsing a VEVENT response, I can access the mailto: value of the ATTENDEE property, but are the parameters (particularly PARTSTAT) parsed as well and if so, how can I access them from the Event object?

Validation

Continue current efforts to include ics validation on both parse and publish.

Please clarify license

Hello,

In your license is stated 'This library is released under the same license as Ruby itself.'. However, the license was changed recently from GPLv2+ or Ruby to BSD or Ruby. Does it means that icalendar is now triple licensed, e.g. GPLv2+ or Ruby or BSD? Could you please clarify it? Thank you.

Missing related-to propery for VALARM

I am parsing large calendars that sometimes contain the RELATED-TO proprerty for VALARM, however, the library fails:

/icalendar/parser.rb:184:in `parse_component': Unknown property type: add_related_to (Icalendar::UnknownPropertyMethod)

I've added:

ical_multiline_property :related_to, :related_to, :related_to

to lib/icalendar/compont/alarm.rb, but I'm still not sure of the singular/plural versions here, though it does parse now.

Bring up to date with RFC 5545

Is there any reason to maintain backward compatibility with RFC 2445? 5545 has been the official standard since 2009. I'm happy to help with the process.

UTC times not handled correctly

I have two different calendars with the same event.

http://www.meetup.com/LouisvilleHardwareStartups/events/ical/Louisville+Hardware+Startup+Meetup

BEGIN:VEVENT
DTSTAMP:20130724T014850Z
DTSTART;TZID=America/New_York:20130729T183000
DTEND;TZID=America/New_York:20130729T213000
STATUS:CONFIRMED
SUMMARY:Louisville Hardware Startup Inaugural Meetup!
DESCRIPTION:Louisville Hardware Startup Meetup\nMonday\, July 29 at 6:30 
 PM\n\nLouisville Hardwarians\, Join us for the inaugural Louisville Hard
 ware Startup Meetup\, July 29th\, 6:30pm\, at LVL1 Hackerspace!  We're l
 ocated at 814 E....\n\nDetails: http://www.meetup.com/LouisvilleHardware
 Startups/events/129917212/
CLASS:PUBLIC
CREATED:20130716T233116Z
GEO:38.24;-85.72
LOCATION:LVL1 - Louisville's Hackerspace (814 East Broadway (rear)\, (Par
 k in rear lot and enter from alley)\, Louisville\, KY 40204)
URL:http://www.meetup.com/LouisvilleHardwareStartups/events/129917212/
LAST-MODIFIED:20130716T233116Z
UID:[email protected]
END:VEVENT

Which dumps out as:

 [#<Icalendar::Event:0x000000014c94a0
       @components={},
       @name="VEVENT",
       @properties=
        {"sequence"=>0,
         "dtstamp"=>
          #<DateTime: 2013-07-24T01:41:53+00:00 ((2456498j,6113s,0n),+0s,2299161j)>,
         "uid"=>"[email protected]",
         "dtstart"=>
          #<DateTime: 2013-07-29T18:30:00+00:00 ((2456503j,66600s,0n),+0s,2299161j)>,
         "dtend"=>
          #<DateTime: 2013-07-29T21:30:00+00:00 ((2456503j,77400s,0n),+0s,2299161j)>,
         "status"=>"CONFIRMED",
         "summary"=>"Louisville Hardware Startup Inaugural Meetup!",
         "description"=>
          "Louisville Hardware Startup Meetup\nMonday, July 29 at 6:30 PM\n\nLouisville Hardwarians, Join us for the inaugural Louisville Hardware Startup Meetup, July 29th, 6:30pm, at LVL1 Hackerspace!  We're located at 814 E....\n\nDetails: http://www.meetup.com/LouisvilleHardwareStartups/events/129917212/",
         "ip_class"=>"PUBLIC",
         "created"=>
          #<DateTime: 2013-07-16T23:31:16+00:00 ((2456490j,84676s,0n),+0s,2299161j)>,
         "geo"=>
          #<Icalendar::Geo:0x0000000144b208
           @ical_params={},
           @lat=38.24,
           @long=-85.72>,
         "location"=>
          "LVL1 - Louisville's Hackerspace (814 East Broadway (rear), (Park in rear lot and enter from alley), Louisville, KY 40204)",
         "url"=>
          #<URI::HTTP:0x0000000141d970 URL:http://www.meetup.com/LouisvilleHardwareStartups/events/129917212/>,
         "last_modified"=>
          #<DateTime: 2013-07-16T23:31:16+00:00 ((2456490j,84676s,0n),+0s,2299161j)>}>]},

http://www.google.com/calendar/ical/1n5qvjga6i4t6lde35vq5dg8ds%40group.calendar.google.com/public/basic.ics

BEGIN:VEVENT
DTSTART:20130729T223000Z
DTEND:20130730T010000Z
DTSTAMP:20130724T014923Z
UID:[email protected]
CREATED:20130716T135854Z
DESCRIPTION:
LAST-MODIFIED:20130716T135854Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Inaugural Hardware Startup Meetup
TRANSP:OPAQUE
END:VEVENT

Which dumps out as:

      #<Icalendar::Event:0x00000001261168
       @components={},
       @name="VEVENT",
       @properties=
        {"sequence"=>0,
         "dtstamp"=>
          #<DateTime: 2013-07-24T01:41:53+00:00 ((2456498j,6113s,0n),+0s,2299161j)>,
         "uid"=>"[email protected]",
         "dtstart"=>
          #<DateTime: 2013-07-29T22:30:00+00:00 ((2456503j,81000s,0n),+0s,2299161j)>,
         "dtend"=>
          #<DateTime: 2013-07-30T01:00:00+00:00 ((2456504j,3600s,0n),+0s,2299161j)>,
         "created"=>
          #<DateTime: 2013-07-16T13:58:54+00:00 ((2456490j,50334s,0n),+0s,2299161j)>,
         "description"=>"",
         "last_modified"=>
          #<DateTime: 2013-07-16T13:58:54+00:00 ((2456490j,50334s,0n),+0s,2299161j)>,
         "location"=>"",
         "status"=>"CONFIRMED",
         "summary"=>"Inaugural Hardware Startup Meetup",
         "transp"=>"OPAQUE"}>,

The event should have a start time of 6:30pm EDT (UTC - 4 hours). I think both ICS files have correct start times, with Meetup using local time, but Google using UTC. I think that means the parsing of the Google time is incorrect.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.