如何在Ruby中更改DateTime的时区?

时间:2010-12-17 04:51:34

标签: ruby-on-rails ruby datetime timezone ruby-on-rails-3

在保持时区不变的同时阅读,编写和序列化日期和时间变得令人讨厌。我正在使用Ruby(和Rails 3.0)并试图改变DateTime的时区。 (到UTC)但不是时间本身。

我想要这个:

t = DateTime.now
t.hour
-> 4
t.offset = 0
t.hour
-> 4
t.utc?
-> true

我最接近的是这个,但它并不直观。

t = DateTime.now
t.hour
-> 4
t += t.offset
t = t.utc
t.hour
-> 4
t.utc?
-> true

还有更好的方法吗?

7 个答案:

答案 0 :(得分:37)

使用Rails 3,您正在寻找DateTime.change()

dt = DateTime.now
=> Mon, 20 Dec 2010 18:59:43 +0100
dt = dt.change(:offset => "+0000")
=> Mon, 20 Dec 2010 18:59:43 +0000

答案 1 :(得分:9)

使用数字偏移,例如由于夏令时,'+1000'不会全年工作。 Checkout ActiveSupport :: TimeZone。 More info here

答案 2 :(得分:8)

我会改用Time对象。因此,获取当前本地时间,然后将其增加UTC偏移量并转换为UTC,如下所示:

t = Time.now # or Time.parse(myDateTime.asctime)
t # => Thu Dec 16 21:07:48 -0800 2010
(t + t.utc_offset).utc # => Thu Dec 16 21:07:48 UTC 2010

虽然根据Phrogz评论,如果您只想以独立于位置的方式存储时间戳,那么只需使用当前的UTC时间:

Time.now.utc

答案 3 :(得分:8)

d = DateTime.now
puts [ d, d.zone ]
#=> 2010-12-17T13:28:29-07:00
#=> -07:00

d2 = d.new_offset(3.0/24)
puts d2, d2.zone
#=> 2010-12-17T23:28:29+03:00
#=> +03:00

修改:此答案不会考虑通过评论另一个答案提供的信息,即希望在时区更改后报告的“小时”相同。

答案 4 :(得分:3)

正如 @Sam 指出的那样,更改偏移量是不够的,并且会导致错误。为了抵抗DST时钟的进步,转换应按以下方式进行:

d = datetime_to_alter_time_zone
time_zone = 'Alaska'

DateTime.new
  .in_time_zone(time_zone)
  .change(year: d.year, month: d.month, day: d.day, hour: d.hour, min: d.min, sec: d.sec)

答案 5 :(得分:1)

如果有人(像我一样)的字符串格式为时区,例如“太平洋时间(美国和加拿大)”

这是我找到的最佳方式:

datetime.change(ActiveSupport::TimeZone[time_zone_string].formatted_offset(false)

答案 6 :(得分:-1)

您可以通过在配置文件(config / application.rb)中添加以下行来指定要在应用中使用的时区:     config.time_zone ='孟买'

您可以在此处找到相同的官方文档:http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html

另一个选择是你“猴子补丁”“日期时间”类。