Return all mappings for a timezone id in `country_zones`

Some timezones like `Europe/London` have multiple mappings in
`ActiveSupport::TimeZone::MAPPING` so return all of them instead
of the first one found by using `Hash#value`. e.g:

  # Before
  ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh"]

  # After
  ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh", "London"]

Fixes #31668.
This commit is contained in:
Andrew White 2018-02-19 10:24:13 +00:00
parent f712ef27c5
commit 2d95956e8b
3 changed files with 31 additions and 2 deletions

View File

@ -1,5 +1,21 @@
## Rails 6.0.0.alpha (Unreleased) ##
* Return all mappings for a timezone identifier in `country_zones`
Some timezones like `Europe/London` have multiple mappings in
`ActiveSupport::TimeZone::MAPPING` so return all of them instead
of the first one found by using `Hash#value`. e.g:
# Before
ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh"]
# After
ActiveSupport::TimeZone.country_zones("GB") # => ["Edinburgh", "London"]
Fixes #31668.
*Andrew White*
* `String#truncate_bytes` to truncate a string to a maximum bytesize without
breaking multibyte characters or grapheme clusters like 👩‍👩‍👦‍👦.

View File

@ -267,11 +267,14 @@ module ActiveSupport
country = TZInfo::Country.get(code)
country.zone_identifiers.map do |tz_id|
if MAPPING.value?(tz_id)
self[MAPPING.key(tz_id)]
MAPPING.inject([]) do |memo, (key, value)|
memo << self[key] if value == tz_id
memo
end
else
create(tz_id, nil, TZInfo::Timezone.new(tz_id))
end
end.sort!
end.flatten(1).sort!
end
def zones_map

View File

@ -756,6 +756,16 @@ class TimeZoneTest < ActiveSupport::TestCase
assert_not_includes ActiveSupport::TimeZone.country_zones(:ru), ActiveSupport::TimeZone["Kuala Lumpur"]
end
def test_country_zones_with_and_without_mappings
assert_includes ActiveSupport::TimeZone.country_zones("au"), ActiveSupport::TimeZone["Adelaide"]
assert_includes ActiveSupport::TimeZone.country_zones("au"), ActiveSupport::TimeZone["Australia/Lord_Howe"]
end
def test_country_zones_with_multiple_mappings
assert_includes ActiveSupport::TimeZone.country_zones("gb"), ActiveSupport::TimeZone["Edinburgh"]
assert_includes ActiveSupport::TimeZone.country_zones("gb"), ActiveSupport::TimeZone["London"]
end
def test_country_zones_without_mappings
assert_includes ActiveSupport::TimeZone.country_zones(:sv), ActiveSupport::TimeZone["America/El_Salvador"]
end