diff options
-rw-r--r-- | activesupport/CHANGELOG | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/time/zones.rb | 11 | ||||
-rw-r--r-- | activesupport/lib/active_support/values/time_zone.rb | 9 | ||||
-rw-r--r-- | activesupport/test/core_ext/time_with_zone_test.rb | 28 | ||||
-rw-r--r-- | activesupport/test/time_zone_test.rb | 9 |
5 files changed, 55 insertions, 4 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index c74855f31f..27639c38a3 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Time.zone= accepts TZInfo::Timezone instances and Olson identifiers; wraps result in TimeZone instance [Geoff Buesing] + * TimeWithZone time conversions don't need to be wrapped in TimeOrDateTime, because TZInfo does this internally [Geoff Buesing] * TimeWithZone#usec returns 0 instead of error when DateTime is wrapped [Geoff Buesing] diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb index e7610d144f..3096427904 100644 --- a/activesupport/lib/active_support/core_ext/time/zones.rb +++ b/activesupport/lib/active_support/core_ext/time/zones.rb @@ -38,8 +38,15 @@ module ActiveSupport #:nodoc: private def get_zone(time_zone) - return time_zone if time_zone.nil? || time_zone.respond_to?(:period_for_local) - TimeZone[time_zone] + return time_zone if time_zone.nil? || time_zone.is_a?(TimeZone) + # lookup timezone based on identifier (unless we've been passed a TZInfo::Timezone) + unless time_zone.respond_to?(:period_for_local) + time_zone = TimeZone[time_zone] || TZInfo::Timezone.get(time_zone) rescue nil + end + # Return if a TimeZone instance, or wrap in a TimeZone instance if a TZInfo::Timezone + if time_zone + time_zone.is_a?(TimeZone) ? time_zone : TimeZone.create(time_zone.name, nil, time_zone) + end end end diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb index 91f0394472..9b9602432c 100644 --- a/activesupport/lib/active_support/values/time_zone.rb +++ b/activesupport/lib/active_support/values/time_zone.rb @@ -145,15 +145,20 @@ class TimeZone } include Comparable - attr_reader :name, :utc_offset + attr_reader :name # Create a new TimeZone object with the given name and offset. The # offset is the number of seconds that this time zone is offset from UTC # (GMT). Seconds were chosen as the offset unit because that is the unit that # Ruby uses to represent time zone offsets (see Time#utc_offset). - def initialize(name, utc_offset) + def initialize(name, utc_offset, tzinfo = nil) @name = name @utc_offset = utc_offset + @tzinfo = tzinfo + end + + def utc_offset + @utc_offset ||= tzinfo.current_period.utc_offset end # Returns the offset of this time zone as a formatted string, of the diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb index 5a645dc765..f20484666e 100644 --- a/activesupport/test/core_ext/time_with_zone_test.rb +++ b/activesupport/test/core_ext/time_with_zone_test.rb @@ -483,6 +483,34 @@ uses_tzinfo 'TimeWithZoneTest' do end end + def test_time_zone_setter_with_tzinfo_timezone_object_wraps_in_rails_time_zone + silence_warnings do # silence warnings raised by tzinfo gem + tzinfo = TZInfo::Timezone.get('America/New_York') + Time.zone = tzinfo + assert_kind_of TimeZone, Time.zone + assert_equal tzinfo, Time.zone.tzinfo + assert_equal 'America/New_York', Time.zone.name + assert_equal(-18_000, Time.zone.utc_offset) + end + end + + def test_time_zone_setter_with_tzinfo_timezone_identifier_does_lookup_and_wraps_in_rails_time_zone + silence_warnings do # silence warnings raised by tzinfo gem + Time.zone = 'America/New_York' + assert_kind_of TimeZone, Time.zone + assert_equal 'America/New_York', Time.zone.tzinfo.name + assert_equal 'America/New_York', Time.zone.name + assert_equal(-18_000, Time.zone.utc_offset) + end + end + + def test_time_zone_setter_with_non_identifying_argument_returns_nil + Time.zone = 'foo' + assert_equal nil, Time.zone + Time.zone = -15.hours + assert_equal nil, Time.zone + end + protected def with_env_tz(new_tz = 'US/Eastern') old_tz, ENV['TZ'] = ENV['TZ'], new_tz diff --git a/activesupport/test/time_zone_test.rb b/activesupport/test/time_zone_test.rb index 8dc71b5ba8..a87cbadc1c 100644 --- a/activesupport/test/time_zone_test.rb +++ b/activesupport/test/time_zone_test.rb @@ -192,6 +192,15 @@ class TimeZoneTest < Test::Unit::TestCase assert_equal Time.utc(1999,12,31,19), twz.time end end + + def test_utc_offset_lazy_loaded_from_tzinfo_when_not_passed_in_to_initialize + silence_warnings do # silence warnings raised by tzinfo gem + tzinfo = TZInfo::Timezone.get('America/New_York') + zone = TimeZone.create(tzinfo.name, nil, tzinfo) + assert_equal nil, zone.instance_variable_get('@utc_offset') + assert_equal(-18_000, zone.utc_offset) + end + end end def test_formatted_offset_positive |