-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ActiveSupport::TimeZone.country_zones helper #20625
Conversation
@Envek can |
@senny |
I added soritng to zones array, so order of zones from |
@@ -248,7 +249,19 @@ def [](arg) | |||
# 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') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests are showing the use of a symbol. Can we use :us
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure we can. Anyway it will be converted to string and upcased. Will push fix in a minute.
👍 /cc @rafaelfranca |
Can this PR be reviewed further? It's got stuck and I do not know why. |
Looks good to me. I assigned @pixeltrix to have another look. |
Nice idea @Envek. |
MAPPING.key(tz_id) | ||
end.map do |tz_id| | ||
self[MAPPING.key(tz_id)] | ||
end.sort |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block is a little unwieldy - try breaking it out into a couple of private methods. Also try to do it in one map if possible so that we're not generating too many arrays. If you can't don't worry as they are cached so they're not regenerated on every request.
I'm 👍 on the idea - just need to fix the merge conflicts and tidy up the core loop |
I've simplified block that searches for ActiveSupport's Now its task should be clear. Also rebased on top of current master. |
def country_zones(country_code) | ||
code = country_code.to_s.upcase | ||
@country_zones[code] ||= | ||
TZInfo::Country.get(code).zone_identifiers.map do |tz_id| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this return a ThreadSafe::Cache
? If not, we need to use a each here instead of a map, and push things to our ThreadSafe::Cache
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should it return a ThreadSafe::Cache
? I've initialized cache instance earlier and only adding key/value pairs to it, never overwriting. Key is the country code, value is the array of timezone objects.
The another cache (@lazy_zones_map
) in this file used similarly — created beforehand and added timezone objects by timezone names as keys afterwards when needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arthurnn: I think @Envek is using @country_zones
(ThreadSafe::Cache
) correctly here.
PS:
I've initialized cache instance earlier and only adding key/value pairs to it, never overwriting.
@Envek just wanted to clarify, it is thread-safe to do something like this:
cache = ThreadSafe::Cache.new
cache[:foo] = [1,2]
cache[:foo] = [1,2,3] # rewriting/updating cache is ok
cache[:foo] += [4] # this is just syntactic sugar for cache[:foo] = cache[:foo] + [4]
however this wouldn't be thread-safe:
cache = ThreadSafe::Cache.new
cache[:foo] = [1,2]
cache[:foo] << 3 # updating ruby Arrays is not thread-safe
PS n. 2: ThreadSafe::Cache
has been merged into https://github.com/ruby-concurrency/concurrent-ruby, so on rebase you'll need to replace ThreadSafe::Cache.new
with Concurrent::Map.new
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thedarkone thanks for the clarification! I'm only adding new key/value pairs to the cache, so no place for such a mistake, but I will remember for future use. Sadly, I can't see good docs with explanations for this neither in thread_safe
nor in concurrent-ruby
.
Sure, will change to Concurrent::Map
as soon as core team will be satisfied and rebase time will come.
@arthurnn @pixeltrix is there any issues left? If not I will be glad to rebase. |
Rebased on top of current master, changed cache storage from |
@pixeltrix could you please review this PR? |
Is there anything prevents this PR from being merged? P.S> Now with signed commit! |
That helper will return time zones for any country that tzdata knows about. So it will be much simpler for non-US people to list own country time zones in HTML selects or anywhere.
Add ActiveSupport::TimeZone.country_zones helper
I always wondered why there is a method to retrieve all time zones for US, but no such methods for another countries until I discovered that tzdata is already knows about all countries and their timezones and tzinfo gem even have an API for that.
Live example:
UPDATE: Method
ActiveSupport::TimeZone.us_zones
reimplemented withActiveSupport::TimeZone.country_zones('us')
P.S> This PR is a good addition to my talk about working with timezones in Rails apps at DevConf