Skip to content

Commit 4edbc92

Browse files
committed
Parse times including time zones from ical.
1 parent 43d1746 commit 4edbc92

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

lib/ice_cube/parsers/ical_parser.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ def self.schedule_from_ical(ical_string, options = {})
55
ical_string.each_line do |line|
66
(property, value) = line.split(':')
77
(property, tzid) = property.split(';')
8+
tz = _tz_from_tzid(tzid)
89
case property
910
when 'DTSTART'
10-
data[:start_time] = Time.parse(value)
11+
data[:start_time] = Time.parse(value).in_time_zone(tz)
1112
when 'DTEND'
12-
data[:end_time] = Time.parse(value)
13+
data[:end_time] = Time.parse(value).in_time_zone(tz)
1314
when 'EXDATE'
1415
data[:extimes] ||= []
15-
data[:extimes] += value.split(',').map{|v| Time.parse(v)}
16+
data[:extimes] += value.split(',').map do |v|
17+
Time.parse(value).in_time_zone(tz)
18+
end
1619
when 'DURATION'
1720
data[:duration] # FIXME
1821
when 'RRULE'
@@ -22,6 +25,14 @@ def self.schedule_from_ical(ical_string, options = {})
2225
Schedule.from_hash data
2326
end
2427

28+
def self._tz_from_tzid(tzid)
29+
time_zone_name = case tzid
30+
when /TZID=/ then tzid.split("=")[1]
31+
else "UTC"
32+
end
33+
ActiveSupport::TimeZone[time_zone_name]
34+
end
35+
2536
def self.rule_from_ical(ical)
2637
params = { validations: { } }
2738

spec/examples/from_ical_spec.rb

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,14 @@ module IceCube
102102
RRULE:FREQ=WEEKLY;BYDAY=TH;UNTIL=20130531T100000Z
103103
ICAL
104104

105-
ical_string_woth_multiple_exdates = <<-ICAL.gsub(/^\s*/, '')
105+
ical_string_with_time_zones = <<-ICAL.gsub(/^\s*/,'')
106+
DTSTART;TZID=America/Denver:20130731T143000
107+
DTEND:20130731T153000
108+
RRULE:FREQ=WEEKLY
109+
EXDATE;TZID=America/Chicago:20130823T143000
110+
ICAL
111+
112+
ical_string_with_multiple_exdates = <<-ICAL.gsub(/^\s*/, '')
106113
DTSTART;TZID=America/Denver:20130731T143000
107114
DTEND;TZID=America/Denver:20130731T153000
108115
RRULE:FREQ=WEEKLY;UNTIL=20140730T203000Z;BYDAY=MO,WE,FR
@@ -125,6 +132,20 @@ def sorted_ical(ical)
125132
it "loads an ICAL string" do
126133
expect(IceCube::Schedule.from_ical(ical_string)).to be_a(IceCube::Schedule)
127134
end
135+
describe "parsing time zones" do
136+
it "sets the time zone of the start time" do
137+
schedule = IceCube::Schedule.from_ical(ical_string_with_time_zones)
138+
expect(schedule.start_time.time_zone).to eq ActiveSupport::TimeZone.new("America/Denver")
139+
end
140+
it "sets the time zone of the end time to UTC if none provided" do
141+
schedule = IceCube::Schedule.from_ical(ical_string_with_time_zones)
142+
expect(schedule.end_time.time_zone).to eq ActiveSupport::TimeZone.new("UTC")
143+
end
144+
it "sets the time zone of the exception times" do
145+
schedule = IceCube::Schedule.from_ical(ical_string_with_time_zones)
146+
expect(schedule.exception_times[0].time_zone).to eq ActiveSupport::TimeZone.new("America/Chicago")
147+
end
148+
end
128149
end
129150

130151
describe "daily frequency" do
@@ -359,7 +380,7 @@ def sorted_ical(ical)
359380
end
360381

361382
it 'handles multiple EXDATE lines' do
362-
schedule = IceCube::Schedule.from_ical ical_string_woth_multiple_exdates
383+
schedule = IceCube::Schedule.from_ical ical_string_with_multiple_exdates
363384
schedule.exception_times.count.should == 3
364385
end
365386
end

0 commit comments

Comments
 (0)