icalendar / icalendar-recurrence

Easy recurrence expansion for iCalendar
MIT License
42 stars 27 forks source link

Recurrence-ID support #40

Open DanielHeath opened 1 month ago

DanielHeath commented 1 month ago

Currently, if a single item is overridden in the recurrence schedule, those overrides do not come through in 'overrides'.

See attached reproduction script:

require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "icalendar-recurrence", "~> 1.2"
  gem "icalendar"
  gem "activesupport"
  gem "byebug"
end

require "active_support"
require "active_support/core_ext"
require "icalendar/tzinfo"

ical_str = <<-ICAL
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:Jubilee Street
X-WR-TIMEZONE:Australia/Sydney
BEGIN:VTIMEZONE
TZID:Australia/Sydney
X-LIC-LOCATION:Australia/Sydney
BEGIN:STANDARD
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
TZNAME:GMT+10
DTSTART:19700405T030000
RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:+1000
TZOFFSETTO:+1100
TZNAME:GMT+11
DTSTART:19701004T020000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=Australia/Sydney:20241017T113000
DTEND;TZID=Australia/Sydney:20241017T120000
RRULE:FREQ=WEEKLY;BYDAY=TH
DTSTAMP:20241018T072558Z
UID:3rdks7fut0hekklh9oop1u4fhg@google.com
CREATED:20241018T053646Z
LAST-MODIFIED:20241018T053845Z
SEQUENCE:1
SUMMARY:Usual summary
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Australia/Sydney:20241024T113500
DTEND;TZID=Australia/Sydney:20241024T120000
DTSTAMP:20241018T072558Z
UID:3rdks7fut0hekklh9oop1u4fhg@google.com
RECURRENCE-ID;TZID=Australia/Sydney:20241024T113000
CREATED:20241018T053646Z
LAST-MODIFIED:20241018T053845Z
SEQUENCE:1
SUMMARY:Overridden summary
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR

ICAL

base_event, override = Icalendar::Calendar.parse(ical_str).sole.events

puts 'By ical'
puts base_event.summary
puts base_event.dtstart
puts base_event.dtend
puts override.summary
puts override.dtstart
puts override.dtend

occurence = base_event.occurrences_between(Date.parse("20 oct 2024"), Date.parse("30 oct 2024")).sole
puts 'By recurrence'
puts occurence.start_time
puts occurence.end_time

This prints

By ical
Usual summary
2024-10-17 11:30:00 +1100
2024-10-17 12:00:00 +1100
Overridden summary
2024-10-24 11:35:00 +1100
2024-10-24 12:00:00 +1100
By recurrence
2024-10-24 00:30:00 UTC
2024-10-24 00:30:00 UTC
rahearn commented 3 weeks ago

Thanks for your report. This is working as currently expected, since the occurrences_between only has access to the single event.

I'm open to PRs to expand how this works so that occurrences_between understands the context of the whole calendar.