如何将TZInfo标识符转换为Rails时区名称/密钥



如何将收到的js值转换为TZInfo标识符到Rails时区名称/键?

FROM: "America/New_York"返回自JavaScript TZinfo检测
TO: "Eastern Time (US & Canada)"约定在Rails TimeZone


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

ActiveSupport::TimeZone < Object映射中都可用,但rails使用键[i.g。"Eastern Time (US & Canada)"]在下拉框中,验证&存储到Time.use_zone() .


根据我对ActiveSupport::TimeZone.us_zones的理解,这似乎很重要,特别是在日光节省时间的情况下(轨道听起来处理得很好),仅仅匹配偏移量将无法完成。如果没有使用rails TimeZone名称存储到DB,则验证失败,并且不能在用户配置文件设置页面中与ActiveSupport::TimeZone.zones_map

的下拉列表正确匹配。

这样做的目的是用户不需要在注册时选择他们的时区,也不需要在注册后在他们的设置中更改它。浏览器检测它并在注册时将其传递给hidden_field。在极少数情况下,他们会在不同于他们家/工作的地方报名。他们可以在以后的帐户设置中手动重写。

似乎是一个常见的差距,当试图摄取js时区检测。这甚至可能成为一个次要问题,如何通过返回的信息从js到rails转换,然后回到js存储回的hidden_field的形式?希望我正确地提出了这个问题& &;不可否认,rails有点绿色,所以可能有一个简单的解决方案…

非常感谢你的帮助!
- e


ActiveSupport这样的时间。区文档
http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html method-i-parse

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


使用js打包的gem 'temporal-rails'来检测用户的时区:
https://github.com/jejacks0n/temporal

User Time_Zone实现如下:
http://railscasts.com/episodes/106-time-zones-revised

*使用设计&Devise-Inevitable


注册视图脚本

    <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>

用户模型
    validates_inclusion_of :time_zone, in: ActiveSupport::TimeZone.zones_map(&:name)

用户帐户设置表单

    <%= f.label :time_zone, label: "Time Zone" %><br />
    <%= f.time_zone_select :time_zone, ActiveSupport::TimeZone.us_zones %>

时态包含所需的逻辑,但要回答您的问题:

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

编辑,我想我的答案不完整。你想把它从"America/New_York"转到"Eastern Time (US &加拿大)",对吗?如果是这种情况,这是我最好的解决方案——尽管有人可能会提供更好的解决方案。

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

我相信每个人都真正在寻找解决@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>> 

否则,如果您尝试搜索activessupport的整个数据库的区域,您将一无所获:

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

复杂性归结为以下内容:

  • TZInfo gem严格遵守IANA时区规范
  • Rails的activessupport决定尝试简化区域的显示/使用,但不是区域的详尽数据库
  • activessupport可以查找一个合适的区域,如果你给它一个偏移
  • TZInfo不会给你一个偏移量,除非你在感兴趣的区域创建TZInfo::TimezonePeriod
  • Ruby 2.6显然正在重新访问时区支持来清理这个业务

IMO的最佳选择是Jo p对公认答案的评论。您可以这样查找:

irb> ActiveSupport::TimeZone::MAPPING.key("America/Chicago")
=> "Central Time (US & Canada)"

相关内容

  • 没有找到相关文章

最新更新