Preload TimeZone zones for thread safety.

This commit is contained in:
Joshua Peek 2008-05-04 21:53:07 -05:00
parent 36662ed08e
commit a40223d36d

@ -1,4 +1,5 @@
class TimeZone
unless const_defined?(:MAPPING)
# Keys are Rails TimeZone names, values are TZInfo identifiers
MAPPING = {
"International Date Line West" => "Pacific/Midway",
@ -143,7 +144,9 @@ class TimeZone
"Auckland" => "Pacific/Auckland",
"Wellington" => "Pacific/Auckland",
"Nuku'alofa" => "Pacific/Tongatapu"
}
}.each { |name, zone| name.freeze; zone.freeze }
MAPPING.freeze
end
include Comparable
attr_reader :name
@ -249,29 +252,14 @@ def period_for_local(time, dst=true)
tzinfo.period_for_local(time, dst)
end
# TODO: Preload instead of lazy load for thread safety
def tzinfo
@tzinfo ||= TZInfo::Timezone.get(MAPPING[name])
end
@@zones = nil
class << self
alias_method :create, :new
# Return a TimeZone instance with the given name, or +nil+ if no
# such TimeZone instance exists. (This exists to support the use of
# this class with the #composed_of macro.)
def new(name)
self[name]
end
# Return an array of all TimeZone objects. There are multiple
# TimeZone objects per time zone, in many cases, to make it easier
# for users to find their own time zone.
def all
unless @@zones
@@zones = []
@@zones_map = {}
unless const_defined?(:ZONES)
ZONES = []
ZONES_MAP = {}
[[-39_600, "International Date Line West", "Midway Island", "Samoa" ],
[-36_000, "Hawaii" ],
[-32_400, "Alaska" ],
@ -322,14 +310,32 @@ def all
[ 46_800, "Nuku'alofa" ]].
each do |offset, *places|
places.each do |place|
zone = create(place, offset)
@@zones << zone
@@zones_map[place] = zone
place.freeze
zone = new(place, offset)
ZONES << zone
ZONES_MAP[place] = zone
end
end
@@zones.sort!
ZONES.sort!
ZONES.freeze
ZONES_MAP.freeze
end
@@zones
class << self
alias_method :create, :new
# Return a TimeZone instance with the given name, or +nil+ if no
# such TimeZone instance exists. (This exists to support the use of
# this class with the #composed_of macro.)
def new(name)
self[name]
end
# Return an array of all TimeZone objects. There are multiple
# TimeZone objects per time zone, in many cases, to make it easier
# for users to find their own time zone.
def all
ZONES
end
# Locate a specific time zone object. If the argument is a string, it
@ -340,8 +346,7 @@ def all
def [](arg)
case arg
when String
all # force the zones to be loaded
@@zones_map[arg]
ZONES_MAP[arg]
when Numeric, ActiveSupport::Duration
arg *= 3600 if arg.abs <= 13
all.find { |z| z.utc_offset == arg.to_i }
@ -352,7 +357,7 @@ def [](arg)
# A regular expression that matches the names of all time zones in
# the USA.
US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/
US_ZONES = /US|Arizona|Indiana|Hawaii|Alaska/.freeze
# A convenience method for returning a collection of TimeZone objects
# for time zones in the USA.