Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #245 from avit/issues/245

Fix `occurs_on?` misses when time is near midnight
  • Loading branch information...
commit a79d4988ff87e1b826bb8e8aea027ad800cef11a 2 parents dafa3f2 + 41ff84a
@avit avit authored
View
32 lib/ice_cube/time_util.rb
@@ -24,6 +24,18 @@ def self.now(reference=Time.now)
match_zone(Time.at(Time.now.to_i), reference)
end
+ def self.build_in_zone(args, reference)
+ if reference.respond_to?(:time_zone)
+ reference.time_zone.local(*args)
+ elsif reference.utc?
+ Time.utc(*args)
+ elsif reference.zone
+ Time.local(*args)
+ else
+ Time.new(*args << reference.utc_offset)
+ end
+ end
+
def self.match_zone(time, reference)
return unless time = ensure_time(time)
if reference.respond_to? :time_zone
@@ -96,25 +108,13 @@ def self.restore_deserialized_offset(time, orig_offset_str)
end
# Get the beginning of a date
- def self.beginning_of_date(date, reference=nil)
- args = [date.year, date.month, date.day, 0, 0, 0]
- reference ||= Time.local(*args)
- if reference.respond_to?(:time_zone) && reference.time_zone
- reference.time_zone.local(*args)
- else
- match_zone(Time.new(*args << reference.utc_offset), reference)
- end
+ def self.beginning_of_date(date, reference=Time.now)
+ build_in_zone([date.year, date.month, date.day, 0, 0, 0], reference)
end
# Get the end of a date
- def self.end_of_date(date, reference=nil)
- args = [date.year, date.month, date.day, 23, 59, 59]
- reference ||= Time.local(*args)
- if reference.respond_to?(:time_zone) && reference.time_zone
- reference.time_zone.local(*args)
- else
- match_zone(Time.new(*args << reference.utc_offset), reference)
- end
+ def self.end_of_date(date, reference=Time.now)
+ build_in_zone([date.year, date.month, date.day, 23, 59, 59], reference)
end
# Convert a symbol to a numeric month
View
8 spec/examples/schedule_spec.rb
@@ -713,6 +713,14 @@
include_examples :occurs_on?
end
+ context 'across DST' do
+ let(:start_time) { Time.local(2010, 3, 2, 0, 0, 0) }
+ before { schedule.add_recurrence_rule(IceCube::Rule.monthly) }
+ it 'determines local midnight with time change' do
+ schedule.occurs_on?(Date.new(2010, 7, 2)).should be_true
+ end
+ end
+
it 'should be true for multiple rtimes' do
schedule = IceCube::Schedule.new(Time.local(2010, 7, 10, 16))
schedule.add_recurrence_time(Time.local(2010, 7, 11, 16))
View
41 spec/examples/time_util_spec.rb
@@ -3,6 +3,47 @@
module IceCube
describe TimeUtil do
+ describe :beginning_of_date do
+
+ let(:utc_time) { Time.utc(2014, 7, 8, 12, 34, 56) }
+ let(:dst_time) { Time.local(2014, 7, 8, 12, 34, 56) }
+ let(:std_time) { Time.local(2014, 1, 1, 12, 34, 56) }
+
+ it "returns 00:00:00 crossing into DST" do
+ time = TimeUtil.beginning_of_date(dst_time.to_date, std_time)
+ dst_diff = dst_time.utc_offset - std_time.utc_offset
+ expect([time.hour, time.min, time.sec]).to eq [0, 0, 0]
+ expect(time.utc_offset - std_time.utc_offset).to eq dst_diff
+ end
+
+ it "returns 00:00:00 crossing out of DST" do
+ time = TimeUtil.beginning_of_date(std_time.to_date, dst_time)
+ dst_diff = std_time.utc_offset - dst_time.utc_offset
+ expect([time.hour, time.min, time.sec]).to eq [0, 0, 0]
+ expect(time.utc_offset - dst_time.utc_offset).to eq dst_diff
+ end
+
+ it "returns 00:00:00 from UTC for local time" do
+ time = TimeUtil.beginning_of_date(utc_time.to_date, dst_time)
+ expect([time.hour, time.min, time.sec]).to eq [0, 0, 0]
+ expect(time.utc_offset).to eq (dst_time.utc_offset)
+ end
+
+ it "returns 00:00:00 from local time for UTC" do
+ time = TimeUtil.beginning_of_date(dst_time.to_date, utc_time)
+ expect([time.hour, time.min, time.sec]).to eq [0, 0, 0]
+ expect(time.utc?).to eq true
+ end
+
+ it "returns 00:00:00 from local time for nonlocal time" do
+ time = TimeUtil.beginning_of_date(dst_time.to_date, std_time.getlocal(7200))
+ zone_diff = dst_time.utc_offset - 7200
+ expect([time.hour, time.min, time.sec]).to eq [0, 0, 0]
+ expect(time.utc_offset).to eq 7200
+ end
+
+ end
+
describe :wday_to_sym do
it 'converts 0..6 to weekday symbols' do
TimeUtil.wday_to_sym(1).should == :monday
Please sign in to comment.
Something went wrong with that request. Please try again.