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

2019-01-22 12:51发布

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.

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?

7条回答
看我几分像从前
2楼-- · 2019-01-22 13:20

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'

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

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

查看更多
一夜七次
3楼-- · 2019-01-22 13:30
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.

查看更多
Evening l夕情丶
4楼-- · 2019-01-22 13:33

Using Rails 3, you're looking for 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
查看更多
对你真心纯属浪费
5楼-- · 2019-01-22 13:33

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)
查看更多
一夜七次
6楼-- · 2019-01-22 13:37

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

查看更多
干净又极端
7楼-- · 2019-01-22 13:39

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

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:

Time.now.utc
查看更多
登录 后发表回答