Last active
April 11, 2024 01:59
-
-
Save rkallensee/8897719ce2771d5bfeaf7939fc2459d4 to your computer and use it in GitHub Desktop.
Script to convert datetimes in an icalendar ics file to local time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'https://rubygems.org' | |
gem 'icalendar' | |
gem 'activesupport' | |
# gem 'pry' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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