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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4467781/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:55:02  来源:igfitidea点击:

How do I alter the timezone of a DateTime in Ruby?

ruby-on-railsrubydatetimetimezoneruby-on-rails-3

提问by Daniel Beardsley

Reading, writing, and serializing dates and times while keeping the time zone constant is becoming annoying. I'm using Ruby (and Rails 3.0) and am trying to alter the time zone of a DateTime. (to UTC) but not the time itself.

在保持时区不变的同时读取、写入和序列化日期和时间变得很烦人。我正在使用 Ruby(和 Rails 3.0)并试图更改 DateTime 的时区。(到UTC)但不是时间本身。

I want this:

我要这个:

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

The closest I have come is this, but it's not intuitive.

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

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

Is there any better way?

有没有更好的办法?

回答by Alex Kremer

Using Rails 3, you're looking for DateTime.change()

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

回答by Phrogz

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

Edit: This answer doesn't account for the information provided by comment to another answer that the desire is to have the reported 'hours' be the same after the time zone change.

编辑:这个答案没有考虑到另一个答案的评论提供的信息,即希望报告的“小时”在时区更改后保持不变。

回答by Sam

Using a number offset e.g. '+1000' wont work all year round because of daylight savings. Checkout ActiveSupport::TimeZone. More info here

由于夏令时,使用数字偏移量(例如“+1000”)不会全年有效。签出 ActiveSupport::TimeZone。 更多信息在这里

回答by maerics

I would use a Timeobject instead. So get the current local time then increment it by the UTC offset and convert to UTC, like so:

我会改用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

Although, per Phrogz comment, if you just want to store timestamps in a location independent way then just use the current UTC time:

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

Time.now.utc

回答by kogitoja

As @Sampointed out, changing offset is not sufficient and would lead to errors. In order to be resistant to DST clock advancements, the conversion should be done in a following way:

正如@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)

回答by Zia Ul Rehman Mughal

If someone(like me) has time zone in string format like "Pacific Time (US & Canada)"

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

Than this is the best way i found:

这是我发现的最好方法:

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

回答by Khoj Badami

You can specify the Time Zone you want to use in your app by adding the following line in the config file (config/application.rb): config.time_zone = 'Mumbai'

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

You can find the official documentation for the same here: http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html

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

The other option is that you "Monkey Patch" the 'DateTime' class.

另一种选择是您“猴子补丁”“DateTime”类。