I''m on vacation far from computers right now, will comment when I get
back, ~sept 24.
Thanks for your interest in vpim.
In summary, I think vpim should deal not with built-in time and
datetime class, they inherite the insufficient timezone support of the
C libraries. They should do all manipulations and returns with
something that knows timezones.
If you are interested in implementing this, I''d be happy to give you
suggestions, and I''ve some hacked together code that might help do
something "good enough".
Sam
On Fri, Sep 5, 2008 at 1:39 AM, Rick DeNatale <rick.denatale at gmail.com>
wrote:> This is a follow-up to the thread ending with:
> http://rubyforge.org/pipermail/vpim-talk/2008/000120.html
>
> I too am in search of some ruby parser for icalendar which properly handles
> timezones on the datetimes in the icalendar RFC.
>
> As I understand it there are actually three types of times.
>
> 1) UTC times with a string form of yyyymmddThhmmssZ
> note the trailing Z indicates zulu time aka utc.
>
> 2) Local times with a string form of TZID=ttttttt:yyyymmddThhmmss
> where ttttt is a variable length timezone id ''defined''
in a timezone
> component in the containing calendar.
> A little experimentation with both Google calendar, and iCal.app for the
> Mac indicates that they at least seem to use
> timezone ids which are known to the TZInfo gem, but there''s no
guarantee.
>
> 3) Floating times with a string form of 20080715T010000
> note there is no timezone either. According to the RFC these are to
> presented to the user as if they were in whatever timezone the user is.
> An example of a floating time might be midnight between New Years eve
> and New Years day.
>
> I''ve tried a little experiment to compare how both the vpim and
icalendar
> gems handle such time specifications. Here''s my code:
>
> require ''rubygems''
> require ''icalendar''
> require ''date''
>
> require ''vpim''
>
> icalendar_events = []
> vpim_events = []
>
> File.open("/Users/rick/Testing.ics") do | ical_file |
> calendar = Icalendar::Parser.new(ical_file).parse.first
> icalendar_events = calendar.events.to_a
> end
> File.open("/Users/rick/Testing.ics") do | ical_file |
> calendar = Vpim::Icalendar.decode(ical_file).first
> vpim_events = calendar.events.to_a
> end
>
> icalendar_events.zip(vpim_events).each do |ic, vp |
> puts "Processing event #{vp.summary}"
> puts " icalendar dtstart: #{ic.dtstart} datetime"
> puts " vpim dtstart:
#{DateTime.parse(vp.dtstart.to_s)}"
> puts " #{vp.dtstart}"
> puts
> puts " icalendar dtend: #{ic.dtend} #{ic.dtend.class}"
> puts " vpim dtend:
#{DateTime.parse(vp.dtend.to_s)}"
> puts " #{vp.dtend}"
> puts
> puts
> end
>
> And here''s an edited icalendar file exported from ical.app
(I''ve stripped
> out some attributes to keep it short and added some blank lines to separate
> events, feel free to ask for the full file)
>
> BEGIN:VCALENDAR
> VERSION:2.0
> BEGIN:VTIMEZONE
> TZID:America/Chicago
> BEGIN:DAYLIGHT
> TZOFFSETFROM:-0600
> TZOFFSETTO:-0500
> DTSTART:20070311T020000
> RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
> TZNAME:CDT
> END:DAYLIGHT
> BEGIN:STANDARD
> TZOFFSETFROM:-0500
> TZOFFSETTO:-0600
> DTSTART:20071104T020000
> RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
> TZNAME:CST
> END:STANDARD
> END:VTIMEZONE
> BEGIN:VTIMEZONE
> TZID:US/Eastern
> BEGIN:DAYLIGHT
> TZOFFSETFROM:-0500
> TZOFFSETTO:-0400
> DTSTART:20070311T020000
> RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
> TZNAME:EDT
> END:DAYLIGHT
> BEGIN:STANDARD
> TZOFFSETFROM:-0400
> TZOFFSETTO:-0500
> DTSTART:20071104T020000
> RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
> TZNAME:EST
> END:STANDARD
> END:VTIMEZONE
>
> BEGIN:VEVENT
> SUMMARY:In Eastern 7/22/2008 00:00-01:00
> DTSTART;TZID=US/Eastern:20080722T000000
> DTEND;TZID=US/Eastern:20080722T010000
> END:VEVENT
>
> BEGIN:VEVENT
> SUMMARY:In Chicago 7/8/2008 00:00-01:00
> DTSTART;TZID=America/Chicago:20080708T000000
> DTEND;TZID=America/Chicago:20080708T010000
> END:VEVENT
>
> BEGIN:VEVENT
> SUMMARY:Floating 7/15/2008 00:00-01:00
> DTSTART:20080715T000000
> DTEND:20080715T010000
> END:VEVENT
>
> BEGIN:VEVENT
> SUMMARY:UTC 7/01/2008 00:00-01:00
> DTSTART:20080701T000000Z
> DTEND:20080701T010000Z
> END:VEVENT
> END:VCALENDAR
>
> And here''s the output from the program:
>
> Processing event In Eastern 7/22/2008 00:00-01:00
> icalendar dtstart: 2008-07-22T00:00:00+00:00 datetime
> vpim dtstart: 2008-07-22T00:00:00-04:00
> Tue Jul 22 00:00:00 -0400 2008
>
> icalendar dtend: 2008-07-22T01:00:00+00:00 DateTime
> vpim dtend: 2008-07-22T01:00:00-04:00
> Tue Jul 22 01:00:00 -0400 2008
>
>
> Processing event In Chicago 7/8/2008 00:00-01:00
> icalendar dtstart: 2008-07-08T00:00:00+00:00 datetime
> vpim dtstart: 2008-07-08T00:00:00-04:00
> Tue Jul 08 00:00:00 -0400 2008
>
> icalendar dtend: 2008-07-08T01:00:00+00:00 DateTime
> vpim dtend: 2008-07-08T01:00:00-04:00
> Tue Jul 08 01:00:00 -0400 2008
>
>
> Processing event Floating 7/15/2008 00:00-01:00
> icalendar dtstart: 2008-07-15T00:00:00+00:00 datetime
> vpim dtstart: 2008-07-15T00:00:00-04:00
> Tue Jul 15 00:00:00 -0400 2008
>
> icalendar dtend: 2008-07-15T01:00:00+00:00 DateTime
> vpim dtend: 2008-07-15T01:00:00-04:00
> Tue Jul 15 01:00:00 -0400 2008
>
>
> Processing event UTC 7/01/2008 00:00-01:00
> icalendar dtstart: 2008-07-01T00:00:00+00:00 datetime
> vpim dtstart: 2008-07-01T00:00:00+00:00
> Tue Jul 01 00:00:00 UTC 2008
>
> icalendar dtend: 2008-07-01T01:00:00+00:00 DateTime
> vpim dtend: 2008-07-01T01:00:00+00:00
> Tue Jul 01 01:00:00 UTC 2008
>
> I set up the summaries to indicate the timezone/float status of each event
> and the start and end times as displayed to the user in iCal.app.
>
> Note that the icalendar gem just seems to ignore any timezone information,
> it justs returns a UTC time which is not adjusted from the true time when
> the timezone is,
> vpim recognizes the Z and returns a UTC time, but if no Z is there it seems
> to always give the time as the local (again unadjusted) time. There is no
> recognition of floating times.
>
>
> I''m not sure how the API should work, barring backwards
compatibility,
> attributes like dtstart/dtend etc should probably return an object which
> contains both a time and an indication of the timezone or its absence in
the
> case of a floating time.
>
> An alternative might be additional parameters, dtstart_with_timezone ...
> although this seems messy.
>
> Ideas, comments?
>
> --
> Rick DeNatale
>
> My blog on Ruby
> http://talklikeaduck.denhaven2.com/
>
> _______________________________________________
> Vpim-talk mailing list
> Vpim-talk at rubyforge.org
> http://rubyforge.org/mailman/listinfo/vpim-talk
>