【问题标题】:How to get Rails to interpret a time as being in a specific time zone?如何让 Rails 将时间解释为特定时区?
【发布时间】:2011-07-01 17:57:02
【问题描述】:

在Ruby 1.8.7中,如何设置时间的时区?

在以下示例中,我的系统时区是 PST(UTC 后 -8:00 小时)

给定时间 (21 Feb 2011, 20:45),假设时间为 EST:

#this interprets the time as system time zone, i.e. PST
Time.local(2011,02,21,20,45) 
  #=> Mon Feb 21 20:45:00 -0800 2011

#this **converts** the time into EST, which is wrong!
Time.local(2011,02,21,20,45).in_time_zone "Eastern Time (US & Canada)" 
  #=> Mon, 21 Feb 2011 23:45:00 EST -05:00

但是,我想要的输出是: Mon Feb 21 20:45:00 -0500 2011(注意 -0500 (EST) 与 -0800 (PST) 相对,小时是相同的,即 20,而不是 23

更新(见下文更好的版本)

我设法让它工作,但我不喜欢它:

DateTime.new(2011,02,21,20,45).change :offset => -(300.0 / 1440.0)
  # => Mon, 21 Feb 2011 20:45:00 +0500

Where
  300 = 5 hrs x 60 minutes
  1440 = number of minutes in a day

or the "right" way:

DateTime.civil(2011,02,21,20,45,0,Rational(-5, 24))

问题:现在,有没有办法从Time.zone 确定 准确(即适应夏令时等)UTC 偏移量,以便我可以通过它换方法?

参考:DateTime::change method

更新(更好的版本)

感谢@ctcherry 提供的所有帮助!

Time.zone确定准确的时区信息:

DateTime.civil(2011,02,21,20,45,0,Rational((Time.zone.tzinfo.current_period.utc_offset / 3600), 24))

【问题讨论】:

标签: ruby ruby-on-rails-3


【解决方案1】:

在 ruby​​ 1.8.7 中,按照文档要求做的事情似乎并不容易:

http://www.ruby-doc.org/core-1.8.7/classes/Time.html

但是在 1.9 中,通过将时区偏移量传递给 Time 对象的 localtime() 方法,看起来要容易得多:

http://www.ruby-doc.org/core/classes/Time.html#M000346

更新

Time.zone 的偏移很简单,因为它本身就是一个对象:(这是在 Rails 控制台中)

ruby-1.8.7-p248 :001 > Time.zone
 => #<ActiveSupport::TimeZone:0x103150190 @current_period=nil, @name="Central Time (US & Canada)", @tzinfo=#<TZInfo::TimezoneProxy: America/Chicago>, @utc_offset=nil> 
ruby-1.8.7-p248 :002 > Time.zone.utc_offset
 => -21600 
ruby-1.8.7-p248 :003 > Time.zone.formatted_offset
 => "-06:00" 

【讨论】:

  • 再次感谢..是的,但我现在不能使用 1.9.2...grr
  • 没有意识到您的意思是 Rails 库是可用的,因为您只提到了 Ruby 1.8.7,请参阅我的回答更新以回答您关于查找偏移量的最后一个问题。
【解决方案2】:

所以我认为这将(几乎)完成您想要的:

require 'time'
t = "21 Feb 2011, 20:45"
Time.parse(t)           # => Mon Feb 21 20:45:00 -0700 2011
t += " -05:00"          # this is the trick
Time.parse(t)           # => Mon Feb 21 18:45:00 -0700 2011

它仍然会根据您的系统时区返回时间,但实际时间是您正在寻找的正确时间。

顺便说一下,这是在 1.8.7-p334 上测试的。

【讨论】:

  • 是的,这可能是可能的,但感觉太 hackish。我使用了 DateTime::change 方法(有关详细信息,请参阅问题)
猜你喜欢
  • 1970-01-01
  • 2012-09-28
  • 2019-09-06
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多