如何转换TZInfo标识符的Rails区名称/键

问题描述 投票:24回答:2

怎样把收到TZInfo标识符的Rails区名称/键JS值?

FROM:"America/New_York"从JavaScript TZinfo检测返回 TO:"Eastern Time (US & Canada)"约定在Rails的时区使用

或另一个例子: "Pacific/Honolulu" =>转换为=> "Hawaii"

两者都是ActiveSupport::TimeZone < Object映射可用,但Rails使用的关键[胃内"Eastern Time (US & Canada)"]在下拉列表,验证与存放到Time.use_zone()

根据我的理解ActiveSupport::TimeZone.us_zones的是什么,这似乎是特别重要的一大跳节省时间incases(其中轨道听起来处理好),并匹配刚好偏移不会完成。如果没有存储到数据库与轨道区名称,然后验证失败而无法正常在用户的个人资料设置页面ActiveSupport::TimeZone.zones_map的下拉列表中匹配

这一目标是,用户没有选择他们的注册时区或需要注册后更改它的设置。浏览器检测到它,并将它传递给hidden_​​field上注册。在难得的机会,他们在比他们的家庭/工作方式不同的地方注册。它们可以手动后覆盖在他们的帐户设置。

似乎是一个共同的差距试图摄取JS时区时检测。这甚至可能成为如何通过从JS返回的信息,以轨道转换次级问题,然后回到JS来存回形式的hidden_​​field?希望我正确和无可否认陷害的问题有点绿色的导轨时,有可能是一个简单的解决这个...

非常感谢所有帮助! -E


的ActiveSupport Time.zone文档 http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html#method-i-parse

MAPPING = {"Eastern Time (US & Canada)" => "America/New_York"

使用JS包装宝石“颞轨道”来检测用户的时区: https://github.com/jejacks0n/temporal

用户TIME_ZONE工具所见: http://railscasts.com/episodes/106-time-zones-revised

*使用设计和制定,必然


Sign-Up View Script

    <script>
    $(function() {
        var detected_zone = Temporal.detect();
        console.log(detected_zone);  // returns object
        detected_zone = detected_zone.timezone.name;
        console.log(detected_zone);  // returns "America/New_York"
        $('#user_time_zone').val(detected_zone);  // ! need to convert this to rails TimeZone name !
    });
    </script>

User Model

    validates_inclusion_of :time_zone, in: ActiveSupport::TimeZone.zones_map(&:name)

User Account Settings Form

    <%= f.label :time_zone, label: "Time Zone" %><br />
    <%= f.time_zone_select :time_zone, ActiveSupport::TimeZone.us_zones %>
ruby-on-rails ruby-on-rails-3 timezone activesupport tzinfo
2个回答
24
投票

时间包括所需的逻辑,而是要回答你的问题:

Time.zone = ActiveSupport::TimeZone.new("America/New_York")

编辑,我想我的答案是不完整的。你想从“美国/纽约”得到它的“东部时间(美国和加拿大)”,正确吗?如果是这样的情况下,这是最好的解决方案,我有 - 尽管有人也许能够提供一个更好的。

ActiveSupport::TimeZone::MAPPING.select {|k, v| v == "America/New_York" }.keys.first


1
投票

神奇的,我相信大家好才是真的后,解决了@ajbraus提出的问题,是一个班轮这可能是的奇怪的最难的事情之一找到任何地方讨论:

timezone = ActiveSupport::TimeZone[TZInfo::Timezone.get('America/Vancouver').period_for_utc(Time.now.utc).utc_offset]
 => #<ActiveSupport::TimeZone:0x00007fc2baa6d900 @name="Pacific Time (US & Canada)", @utc_offset=nil, @tzinfo=#<TZInfo::TimezoneProxy: America/Los_Angeles>> 

否则,如果你试图通过的ActiveSupport的区域的整个DB搜索,你会得到虚无缥缈:

ActiveSupport::TimeZone.all.find{ |tz| tz.tzinfo == ActiveSupport::TimeZone.find_tzinfo('America/Vancouver') }
 => nil

复杂性可以归结为以下几点:

  • TZInfo宝石严格遵守时区的IANA规范
  • Rails的的ActiveSupport决定尝试简化区的显示/使用,但不是区域的详尽DB
  • 的ActiveSupport可以查找合适的区域,如果你给它一个偏移
  • TZInfo不给,除非你在感兴趣的区域中创建一个TZInfo :: TimezonePeriod你的偏移
  • 红宝石2.6显然是重新审查时区支持,清理这项业务了
© www.soinside.com 2019 - 2024. All rights reserved.