def self.get_tzone(str)
return str if str.is_a?(::TZInfo::Timezone)
return nil if str == nil
return nil if str == '*'
ostr = str
str = :current if str == :local
return Time.zone.tzinfo if (
ENV['TZ'].nil? && str == :current &&
Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo)
)
str = ENV['TZ'] || Time.now.zone if str == :current
if str.is_a?(Numeric)
i = str.to_i
sn = i < 0 ? '-' : '+'; i = i.abs
hr = i / 3600; mn = i % 3600; sc = i % 60
str = (sc > 0 ? "%s%02d:%02d:%02d" : "%s%02d:%02d") % [ sn, hr, mn, sc ]
end
return nil if str.index('#')
z = (::TZInfo::Timezone.get(str) rescue nil)
return z if z
if str.match(/\A[A-Z0-9-]{3,6}\z/)
toff = Time.now.utc_offset
toff = nil if str != Time.now.zone
twin = Time.utc(Time.now.year, 1, 1)
tsum = Time.utc(Time.now.year, 7, 1)
z =
::TZInfo::Timezone.all.find do |tz|
pwin = tz.period_for_utc(twin)
psum = tz.period_for_utc(tsum)
if toff
(pwin.abbreviation.to_s == str && pwin.utc_offset == toff) ||
(psum.abbreviation.to_s == str && psum.utc_offset == toff)
else
pwin.abbreviation.to_s == str ||
psum.abbreviation.to_s == str
end
end
return z if z
end
return ::TZInfo::Timezone.get('Zulu') if %w[ Z ].include?(str)
tz = (@custom_tz_cache ||= {})[str]
return tz if tz
if m = str.match(/\A([+-][0-1][0-9]):?([0-5][0-9])\z/)
hr = m[1].to_i
mn = m[2].to_i
hr = nil if hr.abs > 11
hr = nil if mn > 59
mn = -mn if hr && hr < 0
return (
@custom_tz_cache[str] =
begin
tzi = TZInfo::TransitionDataTimezoneInfo.new(str)
tzi.offset(str, hr * 3600 + mn * 60, 0, str)
tzi.create_timezone
end
) if hr
end
z = ostr == :current && (::TZInfo::Timezone.get(ENV['TZ']) rescue nil)
return z if z
nil
end