Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Convenience methods for time zones outside the U.S.

#195

In the TimeZone class in ActiveSupport, there is a convenience method us_zones that dynamically creates a list of all time zones for the U.S.

As is easy to see f.e. from the comments at RailsCasts 106 (Time zones in Rails 2.1) there is a need for convenience methods for other regions of the world as well.

This patch implements the following methods:

  • zones_by_regex(regex) returns a collection of TimeZone objects that match the given regular expression (f.e., "/Europe/")
  • african_zones, american_zones, asian_zones, atlantic_zones, australian_zones, european_zones, and pacific_zones return collections of TimeZone objects for the respective world regions.
  • These methods (with the exclusion of zones_by_regex) use lazy evaluation and result caching; the collection for - say - Europe is create upon the first invocation and stored in a class attribute. The next invocation does not have to evaluate the complete set of TimeZone objects again but can simply re-use the pre-computed collection.

Reported by Martin Eisenhardt · May 14th, 2008 @ 06:43 PM

State: resolved
Milestone: 2.1.1
Assigned to: Geoff Buesing Geoff Buesing
Importance: Low

Activity

  1. Star Trader
    Star Trader

    I agree with the stated purpose of the ticket, but I'm dubious of the patch. The regular expressions given in the convince methods seem to return more results then expected. E.g. #pacific_zones would include the the U.S. Pacific time zone but not the Alaskan.

    Before this patch is applied, I think further discussion need to happen about just which timezones to group together. This should be based on potential user bases, and not necessarily on broad regular expressions

    May 14th, 2008 @ 10:43 PM

  2. Martin Eisenhardt
    Martin Eisenhardt

    Hello Star Trader,

    thank you for the review and valuable input. I do agree that further discussion as to which time zones shall be grouped together is necessary.

    The patch I sent in is merely a quick and dirty hack that provides convenience methods for regions outside the U.S., and naturally, it can be enhanced.

    Having said that, I would like to suggest that you might have another look at the code with reference to you claim that the U.S. pacific time zone would be in pacific_zones whereas the Alaskan time zone is not.

    This is not true. Both the U.S. pacific time zone and the Alaskan time zone are in american_zones but not in pacific_zones.

    The regular expression I use in the patch does not match against the Ruby on Rails time zone names but against the TZinfo names, f.e. "Europe/Dublin" or "Pacific/Samoa".

    Since there is no TZinfo with "Pacific/Alaska" (or similar), the Alaskan time zone is not included in pacific_zones. The same holds for the other convenience methods.

    The following time zones are in pacific_zones:

    • International Date Line West
    • Midway Island
    • Samoa
    • Hawaii
    • Guam
    • Port Moresby
    • New Caledonia
    • Auckland
    • Fiji
    • Marshall Is.
    • Wellington
    • Nuku'alofa

    Now, while it is debatable whether a time zone can in more than one group (f.e. Hawaii is in us_zones and in pacific_zones) I can not see any clear mis-classification. The same holds for the other convenience methods provided with the patch.

    I do agree that it would be advantageous to have the time zones grouped not be a mere regular expression but by a more sophisticated approach; nevertheless, the approach in the patch seems to work quite good.

    May 15th, 2008 @ 10:24 AM

  3. Pratik
    Pratik
    • Assigned user set to Geoff Buesing

    May 15th, 2008 @ 11:35 AM

  4. Geoff Buesing
    Geoff Buesing

    1. If we're to add more convenience methods for grouping time zones, we need to justify each one we add: it should address a common, real-world application need.

    So, even if we can agree on which time zones to group together as Pacific zones, is there actually a common need for a Pacific time zone grouping?

    2. Any convenience method we add would need to be thread-safe -- see how we're preloading TimeZone.all for an example

    May 15th, 2008 @ 03:14 PM

  5. Martin Eisenhardt
    Martin Eisenhardt

    Hi Geoff,

    ad 1.) I agree that a Pacific time zone group is probably nothing that will be used very much. I do see much uses for european_zones or asian_zones.

    At the same time, I advocate strongly against leaving one world region out just because the corresponding method will not be used very much.

    Please see again the comments on RailsCasts 106 (Time zones in Rails 2.1) to see what kind of impression that leaves: People feel left out and not cared about, especially in the current state where there is only a us_zones method. Clearly, Rails is used outside the U.S., and a lonely us_zones method conveys a certain US-centric point of view. I am not sure whether this will actually help things.

    I am sure that you will decide what is best for Rails as a whole and include (or not include!) just the methods that make the most sense.

    ad 2.) I already did a thread-safe version and will upload a new patch with this comment. Thanks for the advice.

    Kind regards, Martin

    May 15th, 2008 @ 04:25 PM

  6. Bryce
    Bryce

    Maybe we could stick with continents, i.e europe_zones, asia_zones, australian_zones, african_zones, south_american_zones, north_american_zones (because there's also Canada)

    May 15th, 2008 @ 10:26 PM

  7. Geoff Buesing
    Geoff Buesing

    To be clear, I'm not advocating leaving out one world region. I'm advocating that we only add additional TimeZone convenience methods to core if we can prove there's a common need for them in real-world applications. Without that justification, we're just putting zones into buckets for no real reason other than to appease one upset person in a comments thread.

    Keep in mind that, the us_zones method is a convenience method used only to make it easy to float US zones to the top of the time zone select. But you're not limited to just these zones -- the time_zone_select api allows you to pass in any set of zones you need. A globalization plugin could easily hook into this and provide an extended set of convenience methods.

    May 16th, 2008 @ 04:36 AM

  8. Bryce
    Bryce

    I'm advocating that we only add additional TimeZone convenience methods to core if we can prove there's a common need for them in real-world applications.

    Definitely, however I think the key disagreement is the fact that /only/ U.S zones are included by default - If anything, there should be at least a helper function for european zones - being a very populated area.

    the time_zone_select api allows you to pass in any set of zones you need

    I'll have to read more about this specific API

    May 16th, 2008 @ 06:16 AM

  9. Geoff Buesing
    Geoff Buesing

    Here's an example of how to float a custom grouping of zones to the top of time_zone_select:

    # config/initializers/time_zones.rb:
    MY_ZONES = [ TimeZone['Alaska'], TimeZone['Hawaii'] ]
    
    # app/views/users/_form.html.erb:
    <%= f.time_zone_select :time_zone, MY_ZONES %>
    

    May 16th, 2008 @ 02:37 PM

  10. Martin Eisenhardt
    Martin Eisenhardt

    OK, I got the point: This functionality is better implemented in an i18n plugin. No worries.

    But: You should really think about what kind of impression it makes if you

    • have a us_zones method and say this is justified because of many use cases, and - at the same time -
    • do not include similar methods for other countries or at least world regions, without leaving anyone out in the rain.

    The impression on non-US devs is - to say the least - a bit irritating. Of course, it is not difficult to implement the functionality outside of Rails in your own app, but you got the nagging feeling that Rails is somewhat US-centric and not overly interested in making things easy for devs in other geographic locations.

    Plus, the comment I linked to above contains not only one upset dev, but several; plus, it is only one blogpost with such comments.

    I can certainly understand that you do not want to bloat Rails with loads of convenience methods, especially given the critique that Rails is very large already.

    Well, I will simply implement this functionality in my apps, no problem there.

    May 16th, 2008 @ 03:19 PM

  11. Geoff Buesing
    Geoff Buesing

    The us_zones method is potentially helpful to devs all over the world, not just US-based devs.

    Proof in point: the us_zones method was first added to the framework by a non-US dev:

    http://dev.rubyonrails.org/chang...

    :)

    May 17th, 2008 @ 08:17 PM

  12. Martin Eisenhardt
    Martin Eisenhardt

    OK, Geoff, point taken ... :-D

    May 18th, 2008 @ 11:29 AM

  13. Adam S
    Adam S

    Can't help chipping in here:

    It's irrelevant whether the us_zones choice came from a non-US resident. Initially it seemed like a nice addition, but rejection of this patch reeks slightly of US-centricism... I personally would never use the us_zones method, but would use the australian_zones method. Does this count as a point towards real-world need? Should we take a poll? It's probably not exactly the same, but politicians say that for every letter they receive it represents 1000 votes... i.e. the comment(s) on rails casts represents more than one person's view. If they bothered to write it then they are probably not the only one thinking it. There have also been at least 3 other people (not including myself) comment on this ticket saying that they would like to see it implemented.

    I would advocate for "zones_by_regex" and no nation specific code. I honestly can't think of a reason not to implement, either; all by continent, or nothing but great APIs... Really. But of course I don't live in America so maybe i'm just bitter. ;)

    May 19th, 2008 @ 08:16 AM

  14. josh
    josh
    TimeZone.zones_by_regex(/../) # 30 char
    TimeZone::ZONES ~= /../ # 24 char
    

    Sorry, but I think zones_by_regex does not help really help.

    May 19th, 2008 @ 12:43 PM

  15. josh
    josh

    Nevermind. Didnt see it was matching the name attr. Geoff, I'd consider adding TimeZone~= And just keep the US zones.

    May 19th, 2008 @ 05:47 PM

  16. Geoff Buesing
    Geoff Buesing

    I like Josh's suggestion -- a TimeZone ~= method could match based on either the #name or the TZInfo identifier in the MAPPING hash.

    The time_zone_select priority zones option could then be enhanced to accept a regex, so this would be possible:

    <%= f.time_zone_select :time_zone, /Australia/ %>

    This seems like a reasonable compromise -- we can make localization easier, without adding a bunch of methods to the API.

    If someone's interested in pulling together a patch for this idea, I'd be happy to commit it.

    May 19th, 2008 @ 07:48 PM

  17. Pratik
    Pratik

    Removing "patch" tag.

    May 20th, 2008 @ 12:58 PM

  18. oddlyzen
    oddlyzen

    So, is someone working on this -- or not? Discussion seemed to die right after a reasonable solution was suggested... :)

    May 30th, 2008 @ 06:34 PM

  19. Ernie Miller
    Ernie Miller

    I just took a stab at it. Have a look at #479 and let me know what you think?

    June 24th, 2008 @ 11:46 PM

  20. Ernie Miller
    Ernie Miller

    Reposting patch here. Thanks to Jeremy Kemper for teaching me to read. ;)

    June 25th, 2008 @ 04:29 AM

  21. Ernie Miller
    Ernie Miller

    Reposting patch here. Thanks to Jeremy Kemper for teaching me to read. ;)

    June 25th, 2008 @ 04:29 AM

  22. Ernie Miller
    Ernie Miller

    Ugh. No way to remove a previous comment? Sorry. :/

    June 25th, 2008 @ 04:36 AM

  23. Ernie Miller
    Ernie Miller

    Hm. And now, it deleted both duplicate attachments when it wasn't responding to clicks before. Reposting the file. Sorry about that mess.

    June 25th, 2008 @ 04:50 AM

  24. Geoff Buesing
    Geoff Buesing
    • Tag set to activesupport, convenient, enhancemen, helper, i18n, patch, timezonece

    Ernie,

    I think the =~ method should be on the TimeZone instance, not the class, so that we're mirroring the semantics of String#=~

    We could then do the on-the-fly lookup in time_zone_select like so:

    # TODO: make this work with options[:model]
    if priority_zones.is_a?(Regexp)
      priority_zones = TimeZone.all.find_all {|z| z =~ priority_zones}
    end
    

    In the time_zone_select tests, instead of replicating the MAPPING hash etc in MockTimeZone, you could try stubbing out TimeZone.all so that it returns an array of TimeZone objects, and stub some of those objects to return true for =~.

    June 25th, 2008 @ 03:14 PM

  25. Geoff Buesing
    Geoff Buesing
    • Tag changed from activesupport, convenient, enhancemen, helper, i18n, patch, timezonece to actionpack, activesupport, i18n, patch, timezone

    Hmmm why did Lighthouse say I just added all of those tags?

    June 25th, 2008 @ 03:21 PM

  26. Ernie Miller
    Ernie Miller

    Geoff,

    Thanks -- Good calls. I'll work on those changes and resubmit, hopefully later today.
    
    

    June 25th, 2008 @ 06:16 PM

  27. Ernie Miller
    Ernie Miller

    Check out the new version, attached. Is this a bit better? I moved the priority_zones part into time_zone_options_for_select, instead, which allowed me to make it work with options[:model], and used the objects' #names instead of scanning the hash. It seems a little cleaner.

    I went with a true/false return on the =~... Should we perhaps return the zone itself or nil, instead? I could have gone either way with it.

    June 27th, 2008 @ 05:21 PM

  28. Jeremy Kemper
    Jeremy Kemper
    • State changed from new to open
    • Milestone set to 2.1.1

    June 28th, 2008 @ 02:10 AM

  29. Geoff Buesing
    Geoff Buesing

    re: TimeZone#=~

    1. I think returning just true or nil is fine for now

    2. instead of matching tzinfo.name, which will preload the tzinfo instance for every TimeZone, just match against MAPPING[name]

    3. need tests for this method

    re: time_zone_select

    1. makes sense to put the regex matching in time_zone_options_for_select

    2. in the test, you might consider using Mocha to stub out #=~ on MockTimeZone instances, as opposed to adding more logic to MockTimeZone

    June 28th, 2008 @ 06:48 PM

  30. Ernie Miller
  31. Ernie Miller
    Ernie Miller

    Done. I sort of feel like I cheated with my MockTimeZone stub, but then again, that's what the added test for TimeZone#=~ is for, I suppose. :)

    June 29th, 2008 @ 03:34 AM

  32. Repository
    Repository
    • State changed from open to resolved

    (from [d0092dc44d580f4179308c7394d9023098406f79]) Added support for regexp matching of priority zones in time_zone_select [#195 state:resolved]

    http://github.com/rails/rails/co...

    June 29th, 2008 @ 07:39 PM

  33. Ryan Bigg
    Ryan Bigg
    • Tag cleared.
    • Importance changed from to Low

    Automatic cleanup of spam.

    October 11th, 2010 @ 12:11 PM