无法使用缩写设置时区

时间:2015-06-10 12:29:51

标签: ruby-on-rails timezone activesupport

我无法使用其缩写在Rails上设置时区,例如:

>> Time.zone = 'BRT'
ArgumentError: Invalid Timezone: BRT
        from /home/braulio/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-3.2.21/lib/active_support/core_ext/time/zones.rb:61:in `rescue in find_zone!'
        from /home/braulio/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-3.2.21/lib/active_support/core_ext/time/zones.rb:53:in `find_zone!'
        from /home/braulio/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/activesupport-3.2.21/lib/active_support/core_ext/time/zones.rb:37:in `zone='
        from (irb):14
        from /home/braulio/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-3.2.21/lib/rails/commands/console.rb:47:in `start'
        from /home/braulio/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-3.2.21/lib/rails/commands/console.rb:8:in `start'
        from /home/braulio/.rbenv/versions/2.1.5/lib/ruby/gems/2.1.0/gems/railties-3.2.21/lib/rails/commands.rb:41:in `<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>'

这是必要的,因为一些系统(android和一些浏览器)使用缩写报告时区。 缩写列表可以在http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations

找到

2 个答案:

答案 0 :(得分:4)

jstimezone使用缩写报告时区。它也非常多而且没有维护(https://bitbucket.org/pellepim/jstimezonedetect/issues?status=new&status=open)。使用标准的javascript更简单:

var offset = - new Date().getTimezoneOffset()/60

然后请准备好文件:

$.cookie("browser.tzoffset", offset, { expires: 30, path: '/' })

然后在rails中使用around_filter中的ApplicationController

  def set_time_zone
    return yield unless (utc_offset = cookies['browser.tzoffset']).present?
    utc_offset = utc_offset.to_i
    gmt_offset = if utc_offset == 0 then nil elsif utc_offset > 0 then -utc_offset else "+#{-utc_offset}" end
    Time.use_zone("Etc/GMT#{gmt_offset}"){ yield }
  rescue ArgumentError
    yield
  end

这样可以独立定位用户的所有日期,无论他/她在哪里。例如,在巴西,我们有多个时区。

PS:ActiveSupport::TimeZone[utc_offset.to_i]无法使用,因为它使用DST,请参阅https://github.com/rails/rails/issues/20504

PS:你也可以使用片刻:moment.parseZone(Date.now()).utcOffset()/60moment().format('zz')

答案 1 :(得分:0)

您不必使用around_filter。 把它放在before_action

Time.zone = "Etc/GMT#{gmt_offset}"

(Time.zone是本地线程。可以安全地更改。)