Rails 5: Not converting DateTime object timezone correctly

那年仲夏 提交于 2019-12-12 04:38:30

问题


This issue has been eating away at me for a while.

I take a date time string:

[14] pry(#<EventsController>)> params[:event][:ended_at]
=> "05/31/2017 2:00 PM"

I convert it to a DateTime object:

pry(#<EventsController>)> to_datetime = DateTime.strptime(params[:event][:ended_at], "%m/%d/%Y %H:%M %p")
=> Wed, 31 May 2017 14:00:00 +0000

If I run the in_time_zone method on the to_datetime object it outputs the wrong time for pacific timezone:

[16] pry(#<EventsController>)> to_datetime.in_time_zone("Pacific Time (US & Canada)")
=> Wed, 31 May 2017 07:00:00 PDT -07:00

It should read "2:00PM" the same as how it is entered.

If I go to google and check to see if "14:00:00 +0000" is the correct entry for PDT time it verifies as correct:

http://imgur.com/a/ZJ80F

Any clues about why it's not converting correctly?


回答1:


the error comes that the ended_at is been assumed by the system configuration that in this case is '+0000' you need to include the original timezone the ended_at is.

irb(main):001:0> date = "05/31/2017 2:00 PM"
=> "05/31/2017 2:00 PM"
irb(main):002:0> to_datetime = DateTime.strptime(date, "%m/%d/%Y %H:%M %p")
=> Wed, 31 May 2017 14:00:00 +0000

Note that this one has already set as UTC since was assumed by the system the timezone

irb(main):001:0> date = "05/31/2017 2:00 PM -0700"
=> "05/31/2017 2:00 PM -0700"
irb(main):002:0> to_datetime = DateTime.strptime(date, "%m/%d/%Y %H:%M %p %z")
=> Wed, 31 May 2017 14:00:00 -0700
irb(main):003:0> new_to_datetime = to_datetime.utc
=> Wed, 31 May 2017 21:00:00 +0000
irb(main):004:0> new_to_datetime.in_time_zone("Pacific Time (US & Canada)")
=> Wed, 31 May 2017 14:00:00 PDT -07:00

Update

@antonio's comment mention he was 1 hour off

irb(main):046:0> time = DateTime.strptime(date + " Pacific Time (US & Canada)", "%m/%d/%Y %H:%M %p %Z").class
=> DateTime
irb(main):047:0> time = DateTime.strptime(date + " Pacific Time (US & Canada)", "%m/%d/%Y %H:%M %p %Z")
=> Wed, 31 May 2017 14:00:00 -0800
irb(main):048:0> time.utc.class
=> Time

As you can see these are different classes and that's sign of problems what you can do is use Time instead of DateTime

irb(main):049:0> time = Time.strptime(date + " Pacific Time (US & Canada)", "%m/%d/%Y %H:%M %p %Z")
=> 2017-05-31 14:00:00 -0700
irb(main):050:0> time.class
=> Time



回答2:


If we look at your first attempt:

pry(#<EventsController>)> to_datetime = DateTime.strptime(params[:event][:ended_at], "%m/%d/%Y %H:%M %p")
=> Wed, 31 May 2017 14:00:00 +0000

we see that "05/31/2017 2:00 PM" is being parsed correctly in UTC, hence the +0000 offset.

Then, if you convert that UTC time to PDT, you apply a -7 hour adjustment:

=> Wed, 31 May 2017 07:00:00 PDT -07:00
# -------------------------------^^^^^^

and the 14:00:00 becomes 07:00:00 because 14 - 7 == 7.

If you want to_datetime to be in PDT then it would be easiest to start that way by telling DateTime.strptime that the timestamp string is PDT:

no_tz       = '05/31/2017 2:00 PM'
to_datetime = DateTime.strptime("#{no_tz} PDT", '%m/%d/%Y %H:%M %p %z')
# ------------------------------^^^^^^^^^^^^^^^---------------------^^

Then you'll get the 14:00:00 PDT you're looking for:

> to_datetime.iso8601
=> "2017-05-31T14:00:00-07:00" 
# -------------^^------^^^^^^


来源:https://stackoverflow.com/questions/43766762/rails-5-not-converting-datetime-object-timezone-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!