Skip to content

Commit

Permalink
delegate unknown timezones to TZInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
spastorino committed Apr 2, 2010
1 parent de7925d commit 2c148cd
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
17 changes: 12 additions & 5 deletions activesupport/lib/active_support/values/time_zone.rb
Expand Up @@ -293,13 +293,15 @@ def period_for_local(time, dst=true)
end

def tzinfo
@tzinfo ||= find_tzinfo
@tzinfo ||= TimeZone.find_tzinfo(name)
end

# TODO: Preload instead of lazy load for thread safety
def find_tzinfo
def self.find_tzinfo(name)
require 'tzinfo' unless defined?(TZInfo)
::TZInfo::Timezone.get(MAPPING[name])
::TZInfo::Timezone.get(MAPPING[name] || name)
rescue TZInfo::InvalidTimezoneIdentifier
nil
end

unless const_defined?(:ZONES)
Expand Down Expand Up @@ -364,7 +366,6 @@ def find_tzinfo
end
ZONES.sort!
ZONES.freeze
ZONES_MAP.freeze

US_ZONES = ZONES.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
US_ZONES.freeze
Expand Down Expand Up @@ -395,7 +396,7 @@ def all
def [](arg)
case arg
when String
ZONES_MAP[arg]
ZONES_MAP[arg] ||= lookup(arg)
when Numeric, ActiveSupport::Duration
arg *= 3600 if arg.abs <= 13
all.find { |z| z.utc_offset == arg.to_i }
Expand All @@ -409,6 +410,12 @@ def [](arg)
def us_zones
US_ZONES
end

private

def lookup(name)
(tzinfo = find_tzinfo(name)) && create(tzinfo.name.freeze)
end
end
end
end
8 changes: 8 additions & 0 deletions activesupport/test/time_zone_test.rb
Expand Up @@ -73,6 +73,14 @@ def test_now_enforces_fall_dst_rules
end
end

def test_unknown_timezones_delegation_to_tzinfo
zone = ActiveSupport::TimeZone['America/Montevideo']
assert_equal ActiveSupport::TimeZone, zone.class
assert_equal zone.object_id, ActiveSupport::TimeZone['America/Montevideo'].object_id
assert_equal Time.utc(2010, 1, 31, 22), zone.utc_to_local(Time.utc(2010, 2)) # daylight saving offset -0200
assert_equal Time.utc(2010, 3, 31, 21), zone.utc_to_local(Time.utc(2010, 4)) # standard offset -0300
end

def test_today
Time.stubs(:now).returns(Time.utc(2000, 1, 1, 4, 59, 59)) # 1 sec before midnight Jan 1 EST
assert_equal Date.new(1999, 12, 31), ActiveSupport::TimeZone['Eastern Time (US & Canada)'].today
Expand Down

0 comments on commit 2c148cd

Please sign in to comment.