icalendar / icalendar

icalendar.rb main repository

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

icalendar can't handle timezones coming from Apple's iCloud .ical files

darrylo opened this issue · comments

.ical calendars can be downloaded from Apple's iCloud, and icalendar somehow can't handle the timezone infomration contained within them. For example, despite the ical data for DTSTART being:

DTSTART;TZID=America/Los_Angeles:20231025T163000

icalendar treats this as being in the UTC timezone.

Sample (redacted) .ics file: raw.txt

Test ruby script to show the bug:

require 'icalendar'

cals = Icalendar::Calendar.parse(File.open("raw.txt"))

first = cals.first
first.events.each { |e|
  #pp e
  print "dtstart = ", e.dtstart, "\n"
}

Running the script produces the incorrect timezone:

dtstart = 2023-10-25T16:30:00+00:00

I'm getting dtstart = 2023-10-25 16:30:00 -0700. Which version of icalendar are you using?

It's whatever version is installed via gem install icalendar:

icalendar (2.10.0)

Edit: installed within the past few days.

Edit 2: weird, I can still reproduce it from the icalendar git. I'm using:

$ ruby --version
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-cygwin]

Let me try a different version of ruby.

Edit 3: OK, this is under windows, and I've tried two other windows versions of ruby, and the issue persists. I've also tried icalendar git as well as 2.10.0 and 2.9.0 installed via gem. An ancient ruby using icalendar 2.9.0 on an ancient linux box works, and so there appears to be something weird with either windows ruby or my environment. I'll keep on poking around.

OK, after much pain involving multiple versions of ruby, multiple versions of icalendar, two different windows boxes, and two different linux boxes, the problem is this:

icalender does not work in a basic ruby installation

For the one case where icalendar did work, I coincidentally also happened to have the ActiveSupport gem installed. This allowed "Plan A" to be used in icalendar/lib/icalendar/values/helper/time_with_zone.rb. Without that (or plans B or C triggering), Plan D was used which completely AND SILENTLY ignored the time zone.

Plan D should probably be replaced by fugly unmentionables involving ::TZInfo::Timezone.get() and sacrifices of aged roadkill.

So, the workaround is to install the activesupport gem.

Gah.

@darrylo thanks for tracking this down. I'll see if we can't improve this somewhat. I think we hadn't done the TZInfo plan D route before because it's an optional dependency, but it's probably time to upgrade that to a runtime dependency so we can be more accurate. I'm also going to dig into why plan b didn't work for your example file.

@darrylo if you're able to test the linked PR on windows, I'd appreciate it. I'm going to leave the PR open for a couple of days and test the branch out in a real app before merging.