如何在Ruby中更改DateTime的时区?
在保持时区不变的同时读取,写入和序列化日期和时间变得令人讨厌。 我正在使用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
有没有更好的方法?
使用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
使用数字偏移,例如’+ 1000’,由于夏令时,不会全年工作。 Checkout ActiveSupport :: TimeZone。 更多信息在这里
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
编辑 :此答案不考虑通过评论提供的信息来解释另一个答案,即希望在时区更改后报告的“小时”相同。
我会改用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
正如@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)
如果有人(像我一样)有字符串格式的时区,如“太平洋时间(美国和加拿大)”
这是我找到的最佳方式:
datetime.change(ActiveSupport::TimeZone[time_zone_string].formatted_offset(false)
您可以通过在配置文件(config / application.rb)中添加以下行来指定要在应用中使用的时区:config.time_zone =’Mumbai’
你可以在这里找到相同的官方文档: http : //api.rubyonrails.org/classes/ActiveSupport/TimeZone.html
另一个选择是你“猴子补丁”“日期时间”类。