Skip to content

Commit 79b4f84

Browse files
barelyknownTybot204
authored andcommitted
Parse time zones when creating schedules from ICAL; fix DST test bug ice-cube-ruby#295
1 parent da878a8 commit 79b4f84

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

lib/ice_cube/parsers/ical_parser.rb

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ def self.schedule_from_ical(ical_string, options = {})
77
(property, tzid) = property.split(';')
88
case property
99
when 'DTSTART'
10-
data[:start_time] = Time.parse(value)
10+
data[:start_time] = _parse_in_tzid(value, tzid)
1111
when 'DTEND'
12-
data[:end_time] = Time.parse(value)
12+
data[:end_time] = _parse_in_tzid(value, tzid)
1313
when 'EXDATE'
1414
data[:extimes] ||= []
15-
data[:extimes] += value.split(',').map{|v| Time.parse(v)}
15+
data[:extimes] += value.split(',').map do |v|
16+
_parse_in_tzid(v, tzid)
17+
end
1618
when 'DURATION'
1719
data[:duration] # FIXME
1820
when 'RRULE'
@@ -23,6 +25,14 @@ def self.schedule_from_ical(ical_string, options = {})
2325
Schedule.from_hash data
2426
end
2527

28+
def self._parse_in_tzid(value, tzid)
29+
t = Time.parse(value)
30+
if tzid
31+
t = t.in_time_zone(ActiveSupport::TimeZone[tzid.split("=")[1]])
32+
end
33+
t
34+
end
35+
2636
def self.rule_from_ical(ical)
2737
raise ArgumentError, 'empty ical rule' if ical.nil?
2838

spec/examples/from_ical_spec.rb

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,19 @@ module IceCube
9494

9595
end
9696

97-
describe Schedule, 'from_ical' do
97+
describe Schedule, 'from_ical', system_time_zone: "America/Chicago" do
9898

9999
ical_string = <<-ICAL.gsub(/^\s*/, '')
100100
DTSTART:20130314T201500Z
101101
DTEND:20130314T201545Z
102102
RRULE:FREQ=WEEKLY;BYDAY=TH;UNTIL=20130531T100000Z
103+
ICAL
104+
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
103110
ICAL
104111

105112
ical_string_with_multiple_exdates = <<-ICAL.gsub(/^\s*/, '')
@@ -130,6 +137,20 @@ def sorted_ical(ical)
130137
it "loads an ICAL string" do
131138
expect(IceCube::Schedule.from_ical(ical_string)).to be_a(IceCube::Schedule)
132139
end
140+
describe "parsing time zones" do
141+
it "sets the time zone of the start time" do
142+
schedule = IceCube::Schedule.from_ical(ical_string_with_time_zones)
143+
expect(schedule.start_time.time_zone).to eq ActiveSupport::TimeZone.new("America/Denver")
144+
end
145+
it "uses the system time if a time zone is not explicity provided" do
146+
schedule = IceCube::Schedule.from_ical(ical_string_with_time_zones)
147+
expect(schedule.end_time).not_to respond_to :time_zone
148+
end
149+
it "sets the time zone of the exception times" do
150+
schedule = IceCube::Schedule.from_ical(ical_string_with_time_zones)
151+
expect(schedule.exception_times[0].time_zone).to eq ActiveSupport::TimeZone.new("America/Chicago")
152+
end
153+
end
133154
end
134155

135156
describe "daily frequency" do
@@ -240,7 +261,6 @@ def sorted_ical(ical)
240261
describe 'monthly frequency' do
241262
it 'matches simple monthly' do
242263
start_time = Time.now
243-
244264
schedule = IceCube::Schedule.new(start_time)
245265
schedule.add_recurrence_rule(IceCube::Rule.monthly)
246266

spec/examples/hourly_rule_spec.rb

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,15 @@ module IceCube
3939
end
4040

4141
it 'should not skip times in DST end hour' do
42-
schedule = Schedule.new(t0 = Time.local(2013, 11, 3, 0, 0, 0))
42+
tz = ActiveSupport::TimeZone["America/Vancouver"]
43+
schedule = Schedule.new(t0 = tz.local(2013, 11, 3, 0, 0, 0))
4344
schedule.add_recurrence_rule Rule.hourly
44-
expect(schedule.first(4)).to eq([
45-
Time.local(2013, 11, 3, 0, 0, 0), # -0700
46-
Time.local(2013, 11, 3, 1, 0, 0) - ONE_HOUR, # -0700
47-
Time.local(2013, 11, 3, 1, 0, 0), # -0800
48-
Time.local(2013, 11, 3, 2, 0, 0), # -0800
49-
])
45+
expect(schedule.first(4)).to eq [
46+
tz.local(2013, 11, 3, 0, 0, 0), # -0700
47+
tz.local(2013, 11, 3, 1, 0, 0), # -0700
48+
tz.local(2013, 11, 3, 2, 0, 0) - ONE_HOUR, # -0800
49+
tz.local(2013, 11, 3, 2, 0, 0), # -0800
50+
]
5051
end
5152

5253
end

0 commit comments

Comments
 (0)