Permalink
Browse files

when the time has to be calculated from the timezone then do so, othe…

…rwise just use the actual time (fix #57)
  • Loading branch information...
1 parent 9e11ccf commit ae1ed2c22e84dbfc5305f25548a1c38adc466e59 @travisjeffery committed Dec 27, 2012
Showing with 96 additions and 73 deletions.
  1. +4 −1 Gemfile
  2. +82 −71 lib/timecop/time_stack_item.rb
  3. +1 −1 lib/timecop/version.rb
  4. +9 −0 test/time_stack_item_test.rb
View
@@ -7,10 +7,13 @@ gemspec
group :development do
gem 'rake'
gem 'jeweler'
- gem 'active_support', :require => "active_support/all"
end
group :development, :test do
gem 'pry'
gem 'mocha', :require => false
+ gem 'active_support', :require => "active_support/all"
+ gem 'tzinfo'
+ gem 'i18n'
+ gem 'minitest-reporters'
end
@@ -1,91 +1,98 @@
-
class Timecop
- # A data class for carrying around "time movement" objects. Makes it easy to keep track of the time
- # movements on a simple stack.
- class TimeStackItem #:nodoc:
- attr_reader :mock_type
-
- def initialize(mock_type, *args)
- raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel, :scale].include?(mock_type)
- @scaling_factor = args.shift if mock_type == :scale
- @mock_type = mock_type
- @time = parse_time(*args)
- @time_was = Time.now_without_mock_time
- @travel_offset = compute_travel_offset
- @dst_adjustment = compute_dst_adjustment(@time)
- end
-
- def year
- time.year
- end
+ # A data class for carrying around "time movement" objects. Makes it easy to keep track of the time
+ # movements on a simple stack.
+ class TimeStackItem #:nodoc:
+ attr_reader :mock_type
+
+ def initialize(mock_type, *args)
+ raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel, :scale].include?(mock_type)
+ @scaling_factor = args.shift if mock_type == :scale
+ @mock_type = mock_type
+ @time = parse_time(*args)
+ @time_was = Time.now_without_mock_time
+ @travel_offset = compute_travel_offset
+ @dst_adjustment = compute_dst_adjustment(@time)
+ end
- def month
- time.month
- end
+ def year
+ time.year
+ end
- def day
- time.day
- end
+ def month
+ time.month
+ end
- def hour
- time.hour
- end
+ def day
+ time.day
+ end
- def min
- time.min
- end
+ def hour
+ time.hour
+ end
- def sec
- time.sec
- end
+ def min
+ time.min
+ end
- def utc_offset
- time.utc_offset
- end
+ def sec
+ time.sec
+ end
- def travel_offset
- @travel_offset
- end
+ def utc_offset
+ time.utc_offset
+ end
- def scaling_factor
- @scaling_factor
- end
+ def travel_offset
+ @travel_offset
+ end
- def time(time_klass = Time) #:nodoc:
- if travel_offset.nil?
- time_klass.at(@time)
- elsif scaling_factor.nil?
- time_klass.at(Time.now_without_mock_time + travel_offset)
- else
- time_klass.at(scaled_time)
+ def scaling_factor
+ @scaling_factor
end
- end
- def scaled_time
- (@time + (Time.now_without_mock_time - @time_was) * scaling_factor).to_f
- end
+ def time(time_klass = Time) #:nodoc:
+ actual_time = time_klass.at(@time)
@glebm

glebm Jan 4, 2013

This breaks for me with "can't convert ActiveSupport::TimeWithZone into Integer" (on jruby)
It appears to be calling :to_int internally. Weird.

@mikz

mikz Jan 8, 2013

I have similar error - TypeError: can't convert ActiveSupport::TimeWithZone into time on ree.

@greyblake

greyblake Jan 8, 2013

Opened an issue: #61

+ calculated_time = time_klass.at(@time.to_f)
- def date(date_klass = Date)
- date_klass.jd(time.__send__(:to_date).jd)
- end
+ if travel_offset.nil?
+ if times_are_equal_within_epsilon(actual_time, calculated_time, 1)
+ actual_time
+ else
+ calculated_time
+ end
+ elsif scaling_factor.nil?
+ time_klass.at(Time.now_without_mock_time + travel_offset)
+ else
+ time_klass.at(scaled_time)
+ end
+ end
- def datetime(datetime_klass = DateTime)
- our_offset = utc_offset + dst_adjustment
+ def scaled_time
+ (@time + (Time.now_without_mock_time - @time_was) * scaling_factor).to_f
+ end
+
+ def date(date_klass = Date)
+ date_klass.jd(time.__send__(:to_date).jd)
+ end
- if Float.method_defined?(:to_r)
- fractions_of_a_second = time.to_f % 1
- datetime_klass.new(year, month, day, hour, min, sec + fractions_of_a_second, utc_offset_to_rational(our_offset))
- else
+ def datetime(datetime_klass = DateTime)
our_offset = utc_offset + dst_adjustment
- datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(our_offset))
+
+ if Float.method_defined?(:to_r)
+ fractions_of_a_second = time.to_f % 1
+ datetime_klass.new(year, month, day, hour, min, sec + fractions_of_a_second, utc_offset_to_rational(our_offset))
+ else
+ our_offset = utc_offset + dst_adjustment
+ datetime_klass.new(year, month, day, hour, min, sec, utc_offset_to_rational(our_offset))
+ end
end
- end
- def dst_adjustment
- @dst_adjustment
- end
+ def dst_adjustment
+ @dst_adjustment
+ end
+
+ private
- private
def rational_to_utc_offset(rational)
((24.0 / rational.denominator) * rational.numerator) * (60 * 60)
end
@@ -139,5 +146,9 @@ def compute_travel_offset
return nil if mock_type == :freeze
time - Time.now_without_mock_time
end
- end
-end
+
+ def times_are_equal_within_epsilon t1, t2, epsilon_in_seconds
+ (t1 - t2).abs < epsilon_in_seconds
+ end
+ end
+ end
View
@@ -1,3 +1,3 @@
class Timecop
- VERSION = "0.5.6"
+ VERSION = "0.5.7"
end
@@ -183,6 +183,15 @@ def test_set_travel_offset_for_freeze
assert_equal nil, tsi.send(:travel_offset)
end
+ def test_timezones
+ require 'active_support/all'
+ Time.zone = "Europe/Zurich"
+ time = Time.zone.parse("2012-12-27T12:12:12+08:00")
+ Timecop.freeze(time) do |frozen_time|
+ assert_equal time, frozen_time
+ end
+ end
+
def test_set_scaling_factor_for_scale
t_now = Time.now
t = Time.local(2009, 10, 1, 0, 0, 30)

0 comments on commit ae1ed2c

Please sign in to comment.