Skip to content

Instantly share code, notes, and snippets.

@rkallensee
Last active April 11, 2024 01:59
Show Gist options
  • Save rkallensee/8897719ce2771d5bfeaf7939fc2459d4 to your computer and use it in GitHub Desktop.
Save rkallensee/8897719ce2771d5bfeaf7939fc2459d4 to your computer and use it in GitHub Desktop.
Script to convert datetimes in an icalendar ics file to local time
source 'https://rubygems.org'
gem 'icalendar'
gem 'activesupport'
# gem 'pry'
# This (very quick&dirty) script parses an ics file and converts all datetimes to the given local timezone.
# Practical use-case is to prepare an ics file exported from Google Calendar (with a mix
# of UTC and local times) and prepare it for importing it to Nextcloud Calendar.
# configure here
input_filename = 'google_calendar.ics'
output_filename = 'google_calendar_converted.ics'
local_tzid = 'Europe/Berlin'
require 'bundler'
Bundler.require
cal_file = File.open(input_filename)
# Parser returns an array of calendars because a single file can have multiple calendars.
cals = Icalendar::Calendar.parse(cal_file)
cal = cals.first
# binding.pry
local_time_zone = ActiveSupport::TimeZone.new(local_tzid)
def convert_ical_datetime_to_timezone(datetime, timezone)
Icalendar::Values::DateTime.new(datetime.in_time_zone(timezone), {'tzid' => timezone.tzinfo.name})
end
def need_to_convert_timezone?(datetime, local_time_zone)
datetime.is_a?(Icalendar::Values::DateTime) && datetime.time_zone.name != local_time_zone.tzinfo.name
end
potential_date_time_attrs = %i[dtstart dtend dtstamp created last_modified]
cal.events.each do |event|
potential_date_time_attrs.each do |date_time_attr|
if need_to_convert_timezone?(event.send(date_time_attr), local_time_zone)
event.send("#{date_time_attr}=".to_sym, convert_ical_datetime_to_timezone(event.send(date_time_attr), local_time_zone))
end
end
end
File.write(output_filename, cal.to_ical)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment