如何使用现有的Time.zone为Rails创建一个Ruby DateTime?

33

我有用户在 Ruby on Rails 网站上输入日期。我使用类似以下代码将日期解析为 DateTime 对象:

date = DateTime.new(params[:year].to_i, params[:month].to_i, params[:day].to_i, params[:hour].to_i, params[:minute].to_i)
或者
date = DateTime.parse(params[:date])

两个DateTime对象的时间都不会处于之前我设置的用户时区中,类似于以下内容:

Time.zone = "Pacific Time (US & Canada)"
我该如何将上述的 DateTime 解析为正确的时区?我知道 DateTime.new 方法有第七个参数用于时间偏移量。是否有一种简单的方法可以查找给定时间的时区偏移量?或者我应该使用除 DateTime 之外的其他东西吗?

我怎么才能将上述的DateTime转换为正确的时区?我知道DateTime.new方法有一个第7个参数,用于时间偏移量。是否有一种简便的方法来查找特定时间所在时区的偏移量?或者我应该使用除DateTime之外的其他东西?

5个回答

41

尝试:

Time.zone = "Pacific Time (US & Canada)"
Time.zone.parse('8-11-2013 23:59:59') #=> Fri, 08 Nov 2013 23:59:59 PST -08:00 
Time.now.in_time_zone("Pacific Time (US & Canada)")

或者

DateTime.now.in_time_zone("Pacific Time (US & Canada)")

2
只是为了补充这里的答案,您可以在常量中找到所有可用区域的列表 https://apidock.com/rails/TimeZone - Edgar Villamarin Uribe

25
你可以使用以下代码来创建一个带有你所需的TimeZoneDateTime对象。
DateTime.new(2013, 6, 29, 10, 15, 30).change(:offset => "+0530")

在 Ruby v1.9.1 中,以下代码可以像魔法一样完成同样的工作。

DateTime.new(2013, 6, 29, 10, 15, 30, "+0530")

文档在这里


2
如果您已经有一个带有设置时区的现有时间,您可以执行DateTime.new(2013, 6,29,10,15,30).change(:offset => known_time.zone)。 - Adreamus
这不会得到期望的值。关键是时间“10:15:30”应该在所需的时区内,并且想要从中获得一个值:(byebug)p DateTime.new(2015,12,27,0,0,0).change(:offset => 'America/New_York') 2015年12月27日星期日00:00:00 +0000 - mcr
1
DateTime.new接受偏移量作为第七个可选参数。请参见https://dev59.com/S2Uo5IYBdhLWcg3wrhFD#49559402以了解用法。 - Tun
谢谢@twnaing。已更新评论 :-) - SriramK89

22

如果之前设置了Time.zone,则可以使用Time.zone.local

user_time = Time.zone.local(params[:year].to_i, params[:month].to_i, params[:day].to_i, params[:hour].to_i, params[:minute].to_i, 0)

请查看ActiveSupport::TimeWithZone文档。


3
对于任何拥有Railscasts.com专业账户的人:http://railscasts.com/episodes/106-time-zones-revised - wintermeyer
1
@wintermeyer,因为你的推荐,我刚刚订阅了 Railscasts,谢谢。 - at.
如果您想接受0或-1等月份和日期参数,请参见https://dev59.com/S2Uo5IYBdhLWcg3wrhFD#49559402。 - Tun

7

DateTime.new从ruby 1.9.1开始接受可选的偏移量参数(作为第七个参数)。

我们可以这样写:

DateTime.new(2018, 1, 1, 0, 0, 0, Time.zone.formatted_offset)

1
如果你已经有一个名为“datetime”的正确的DateTime对象,并且想要复制它,你可以简单地在其上调用'getutc',然后使用'in_time_zone'。
DateTime.new(datetime.getutc.year, datetime.getutc.month, datetime.getutc.day, time.getutc.hour, time.getutc.min).in_time_zone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接