mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #20625 from Envek/add_country_zones_method
Add ActiveSupport::TimeZone.country_zones helper
This commit is contained in:
commit
a0dcc95cd8
5 changed files with 57 additions and 11 deletions
|
@ -268,10 +268,11 @@ module ActionView
|
|||
# for more information.)
|
||||
#
|
||||
# You can also supply an array of ActiveSupport::TimeZone objects
|
||||
# as +priority_zones+, so that they will be listed above the rest of the
|
||||
# (long) list. (You can use ActiveSupport::TimeZone.us_zones as a convenience
|
||||
# for obtaining a list of the US time zones, or a Regexp to select the zones
|
||||
# of your choice)
|
||||
# as +priority_zones+ so that they will be listed above the rest of the
|
||||
# (long) list. You can use ActiveSupport::TimeZone.us_zones for a list
|
||||
# of US time zones, ActiveSupport::TimeZone.country_zones(country_code)
|
||||
# for another country's time zones, or a Regexp to select the zones of
|
||||
# your choice.
|
||||
#
|
||||
# Finally, this method supports a <tt>:default</tt> option, which selects
|
||||
# a default ActiveSupport::TimeZone if the object's time zone is +nil+.
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
* `ActiveSupport::TimeZone.country_zones(country_code)` looks up the
|
||||
country's time zones by its two-letter ISO3166 country code, e.g.
|
||||
|
||||
>> ActiveSupport::TimeZone.country_zones(:jp).map(&:to_s)
|
||||
=> ["(GMT+09:00) Osaka"]
|
||||
|
||||
>> ActiveSupport::TimeZone.country_zones(:uy).map(&:to_s)
|
||||
=> ["(GMT-03:00) Montevideo"]
|
||||
|
||||
*Andrey Novikov*
|
||||
|
||||
* `Array#sum` compat with Ruby 2.4's native method.
|
||||
|
||||
Ruby 2.4 introduces `Array#sum`, but it only supports numeric elements,
|
||||
|
|
|
@ -184,6 +184,7 @@ module ActiveSupport
|
|||
UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.tr(':', '')
|
||||
|
||||
@lazy_zones_map = Concurrent::Map.new
|
||||
@country_zones = Concurrent::Map.new
|
||||
|
||||
class << self
|
||||
# Assumes self represents an offset from UTC in seconds (as returned from
|
||||
|
@ -242,7 +243,18 @@ module ActiveSupport
|
|||
# A convenience method for returning a collection of TimeZone objects
|
||||
# for time zones in the USA.
|
||||
def us_zones
|
||||
@us_zones ||= all.find_all { |z| z.name =~ /US|Arizona|Indiana|Hawaii|Alaska/ }
|
||||
country_zones(:us)
|
||||
end
|
||||
|
||||
# A convenience method for returning a collection of TimeZone objects
|
||||
# for time zones in the country specified by its ISO 3166-1 Alpha2 code.
|
||||
def country_zones(country_code)
|
||||
code = country_code.to_s.upcase
|
||||
@country_zones[code] ||=
|
||||
TZInfo::Country.get(code).zone_identifiers.map do |tz_id|
|
||||
name = MAPPING.key(tz_id)
|
||||
name && self[name]
|
||||
end.compact.sort!
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -491,6 +491,11 @@ class TimeZoneTest < ActiveSupport::TestCase
|
|||
assert !ActiveSupport::TimeZone.us_zones.include?(ActiveSupport::TimeZone["Kuala Lumpur"])
|
||||
end
|
||||
|
||||
def test_country_zones
|
||||
assert ActiveSupport::TimeZone.country_zones("ru").include?(ActiveSupport::TimeZone["Moscow"])
|
||||
assert !ActiveSupport::TimeZone.country_zones(:ru).include?(ActiveSupport::TimeZone["Kuala Lumpur"])
|
||||
end
|
||||
|
||||
def test_to_yaml
|
||||
assert_equal("--- !ruby/object:ActiveSupport::TimeZone\nname: Pacific/Honolulu\n", ActiveSupport::TimeZone["Hawaii"].to_yaml)
|
||||
assert_equal("--- !ruby/object:ActiveSupport::TimeZone\nname: Europe/London\n", ActiveSupport::TimeZone["Europe/London"].to_yaml)
|
||||
|
|
|
@ -10,29 +10,46 @@ task about: :environment do
|
|||
end
|
||||
|
||||
namespace :time do
|
||||
desc 'List all time zones, list by two-letter country code (`rake time:zones[US]`), or list by UTC offset (`rake time:zones[-8]`)'
|
||||
task :zones, :country_or_offset do |t, args|
|
||||
zones, offset = ActiveSupport::TimeZone.all, nil
|
||||
|
||||
if country_or_offset = args[:country_or_offset]
|
||||
begin
|
||||
zones = ActiveSupport::TimeZone.country_zones(country_or_offset)
|
||||
rescue TZInfo::InvalidCountryCode
|
||||
offset = country_or_offset
|
||||
end
|
||||
end
|
||||
|
||||
build_time_zone_list zones, offset
|
||||
end
|
||||
|
||||
namespace :zones do
|
||||
desc 'Displays all time zones, also available: time:zones:us, time:zones:local -- filter with OFFSET parameter, e.g., OFFSET=-6'
|
||||
# desc 'Displays all time zones, also available: time:zones:us, time:zones:local -- filter with OFFSET parameter, e.g., OFFSET=-6'
|
||||
task :all do
|
||||
build_time_zone_list(:all)
|
||||
build_time_zone_list ActiveSupport::TimeZone.all
|
||||
end
|
||||
|
||||
# desc 'Displays names of US time zones recognized by the Rails TimeZone class, grouped by offset. Results can be filtered with optional OFFSET parameter, e.g., OFFSET=-6'
|
||||
task :us do
|
||||
build_time_zone_list(:us_zones)
|
||||
build_time_zone_list ActiveSupport::TimeZone.us_zones
|
||||
end
|
||||
|
||||
# desc 'Displays names of time zones recognized by the Rails TimeZone class with the same offset as the system local time'
|
||||
task :local do
|
||||
require 'active_support'
|
||||
require 'active_support/time'
|
||||
|
||||
jan_offset = Time.now.beginning_of_year.utc_offset
|
||||
jul_offset = Time.now.beginning_of_year.change(month: 7).utc_offset
|
||||
offset = jan_offset < jul_offset ? jan_offset : jul_offset
|
||||
build_time_zone_list(:all, offset)
|
||||
|
||||
build_time_zone_list(ActiveSupport::TimeZone.all, offset)
|
||||
end
|
||||
|
||||
# to find UTC -06:00 zones, OFFSET can be set to either -6, -6:00 or 21600
|
||||
def build_time_zone_list(method, offset = ENV['OFFSET'])
|
||||
def build_time_zone_list(zones, offset = ENV['OFFSET'])
|
||||
require 'active_support'
|
||||
require 'active_support/time'
|
||||
if offset
|
||||
|
@ -47,7 +64,7 @@ namespace :time do
|
|||
end
|
||||
end
|
||||
previous_offset = nil
|
||||
ActiveSupport::TimeZone.__send__(method).each do |zone|
|
||||
zones.each do |zone|
|
||||
if offset.nil? || offset == zone.utc_offset
|
||||
puts "\n* UTC #{zone.formatted_offset} *" unless zone.utc_offset == previous_offset
|
||||
puts zone.name
|
||||
|
|
Loading…
Reference in a new issue