Preload TimeZone zones for thread safety.
This commit is contained in:
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.
|
||||
|
Loading…
Reference in New Issue
Block a user