Rails:如何将日期时间字符串解析为特定时区

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rails:如何将日期时间字符串解析为特定时区相关的知识,希望对你有一定的参考价值。

我在Debian上使用Rails 3.2和ruby 1.9.3。我有一个应用程序,通过html表单以字符串的形式收集日期,时间和时区。像这样的东西:

start_date: "04-15-2010",
start_time: "10:00:00",
timezone: "Central Time (US & Canada)"

我想要做的是将这3个元素解析为一个以UTC格式保存到我的数据库中的日期,在这种情况下,一旦它在UTC时区,就会增加7个小时到开始时间。因此,一旦它在数据库中作为UTC而不是收到的中央时间,存储的时间将是17:00。

我试过这样的东西来解析日期:

ActiveSupport::TimeZone[timezone].at DateTime.strptime("{ 2012-04-09 20:00:00 }", "{ %Y-%m-%d %H:%M:%S }").to_i

但是,我无法将时区合并到%Z的结果时间中。它要么不解析,要么将时间解释为UTC而不是中心时间。所以我的问题是,如何在不改变存储的实际日期/时间值的情况下将日期字符串强制转换为某个时区。我希望能够将字符串解析为包含当时正确时区的日期/时间对象,以便将来的时区转换准确无误。我看了一遍,找不到办法做到这一点。这很奇怪,因为这似乎是从HTML表单输入的日期常见的事情。感谢您的任何帮助。

答案

%Z是指定时区名称的正确方法。你试过以下吗?

date_and_time = '%m-%d-%Y %H:%M:%S %Z'
DateTime.strptime("04-15-2010 10:00:00 Central Time (US & Canada)",date_and_time)
另一答案

试试这个:

zone = "Central Time (US & Canada)"  

ActiveSupport::TimeZone[zone].parse("2013-04-03 17:47:00")
另一答案

使用String#in_time_zone(Rails 4+)

我个人更喜欢使用String#in_time_zone

>> '22.09.1986 10:30'.in_time_zone('Central Time (US & Canada)')
# => Mon, 22 Sep 1986 10:30:00 CDT -05:00

这会将String中的日期和时间解析为提供的时区。

另一答案

这是我提出的方法。不是最漂亮的,但它的确有效。允许使用指定的格式解析字符串,然后将其转换为我知道Time.zone.parse所需的格式。

class ActiveSupport::TimeZone
  def strptime(time, format='%m/%d/%Y')
    formatted = Time.strptime(time, format).strftime('%Y-%m-%d %T')
    parse(formatted)
  end
end

然后你可以做类似于另一个问题中提到的事情,但具有指定的格式:

zone = "Central Time (US & Canada)"  
ActiveSupport::TimeZone[zone].strptime('2013-04-03', '%Y-%m-%d')

或者,如果您已经设置了时区:

Time.zone = "Central Time (US & Canada)" 
Time.zone.strptime('01/13/2006')

我使用了%m/%d/%Y的默认格式,因为这是我的用户输入的大部分时间。您可以根据需要自定义,或使用默认格式DateTime使用,相信是iso8601(%FT%T%z

另一答案

我终于找到了这样做的肮脏而又明确的方法。

首先,使用普通的Ruby Time.strptime解析字符串,如下所示:

time = Time.strptime('12 : 00 : PM', '%I : %M : %p')

这样您就可以获得解析时间,但尚未获得正确的时区。要解决这个问题,让我们将时间转换为字符串形式,并使用标准的ActiveSupport :: TimeZone #parse解析它

Time.zone.parse(time.to_s)

结果是ActiveSupport :: TimeWithZone,我们的时间被解析为正确的时区。

我们必须这样做的原因是ActiveSupport :: TimeZone和ActiveSupport :: TimeWithZone都不支持strptime方法。因此,我们必须使用没有时区信息的核心Ruby strptime解析Time,将其转换为ActiveSupport对象中可接受的格式,然后再次解析它。

另一答案

要使DateTime获取日期字符串并附加UTC以外的时区而不更改日期字符串的值,请使用此,它很容易,在闰日不会中断:)

xx = DateTime.strptime("9/1/15 #{object.time_zone}", "%m/%d/%Y %Z")
另一答案

转换UTC格式的特定日期格式。

ActiveSupport::TimeZone['UTC'].parse(Time.strptime('01/24/2019T16:10:16', "%m/%d/%YT%H:%M:%S").asctime)

以上是关于Rails:如何将日期时间字符串解析为特定时区的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Joda Time 解析包含时区的日期

iOS Swift:当字符串包含时区缩写时,如何将特定的日期字符串格式转换为日期对象?

Javascript:将字符串解析为日期作为本地时区

如何将 UTC 格式的字符串转换为特定时区的日历?

如何将日期时间(在特定时区)转换为纪元秒

如何使用 MQ 的 esql 将日期的特定时区转换为 GMT 时区?