diff --git a/lib/ice_cube/schedule.rb b/lib/ice_cube/schedule.rb index 9f930cb3..6da570c9 100644 --- a/lib/ice_cube/schedule.rb +++ b/lib/ice_cube/schedule.rb @@ -456,7 +456,12 @@ def next_time(time, closing_time) end break unless min_time next (time = min_time + 1) if exception_time?(min_time) - break Occurrence.new(min_time, min_time + duration) + + e_time = min_time + duration + # Make sure to add the timezone difference, in case we span tz zones (offsets) + # majority of cases this will be 0, but when we span tz zones, we need to account for it + e_time += TimeUtil.zone_offset_delta(min_time, e_time) + break Occurrence.new(min_time, e_time) end end diff --git a/lib/ice_cube/time_util.rb b/lib/ice_cube/time_util.rb index ff43399e..e36093a5 100644 --- a/lib/ice_cube/time_util.rb +++ b/lib/ice_cube/time_util.rb @@ -268,6 +268,17 @@ def self.subsec(time) end end + # Returns the timezone delta (seconds) between 2 times. + # - For times in the same timezone this will return 0. + # - For times than span offsets (think Daylight Savings time to Standard Time) + # this number will be positive or negative, depening if you "spring foward" or "fall back". + # - The order of arguments is important, in 99% of use cases t0 is a date *before* t1 (aka time only moves foward). + # - For "fall back" this will be positive, aka we gained time (usually an hour, 3600) + # - For "spring foward" this will be negative, aka we lost time (usually an hour, -3600) + def self.zone_offset_delta(t0, t1) + t0.utc_offset - t1.utc_offset + end + # A utility class for safely moving time around class TimeWrapper