Ruby-on-rails Rails:如何将日期时间字符串解析为特定时区
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10091959/
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
Rails: How to parse date-time string into a specific time zone
提问by Matt Schwartz
I'm using Rails 3.2 and ruby 1.9.3 on Debian. I have an app that collects a date, time, and timezone in the form of strings via an HTML form. Something like this:
我在 Debian 上使用 Rails 3.2 和 ruby 1.9.3。我有一个应用程序,它通过 HTML 表单以字符串的形式收集日期、时间和时区。像这样的东西:
start_date: "04-15-2010",
start_time: "10:00:00",
timezone: "Central Time (US & Canada)"
What I'd like to do is parse these 3 elements into a single date that is saved into my database as UTC, which in this case would add 7 hours to the start time, once it's in the UTC time zone. So the stored time would be 17:00 once it's in the DB as UTC instead of the received Central time.
我想要做的是将这 3 个元素解析为一个日期,该日期作为 UTC 保存到我的数据库中,在这种情况下,一旦它处于 UTC 时区,就会将开始时间增加 7 小时。因此,一旦它在数据库中作为 UTC 而不是接收到的中央时间,存储的时间将是 17:00。
I have tried something like this to parse the date:
我试过这样的事情来解析日期:
ActiveSupport::TimeZone[timezone].at DateTime.strptime("{ 2012-04-09 20:00:00 }", "{ %Y-%m-%d %H:%M:%S }").to_i
However, I'm not able to incorporate the time zone into the resulting time with %Z. It either doesn't parse or the time is interpreted as UTC not Central time. So my question is, how to coerce a date string into a certain time zone without changing the value of the actual date/time stored. I'd like to be able to parse the string into a date/time object that includes the correct time zone with it at that timeso that future time zone conversions are accurate. I've looked all over and can't find a way to do this. It's strange, since this seems like something common one does with dates inputted from HTML forms. Thank you for any help.
但是,我无法使用 %Z 将时区合并到结果时间中。它要么不解析,要么时间被解释为 UTC 而不是中央时间。所以我的问题是,如何在不更改存储的实际日期/时间的值的情况下将日期字符串强制转换为某个时区。我希望能够将字符串解析成包括与它正确的时区的日期/时间对象在那个时候,这样未来的时区转换是准确的。我已经看遍了,找不到办法做到这一点。这很奇怪,因为这对于从 HTML 表单输入的日期似乎很常见。感谢您的任何帮助。
采纳答案by 0x4a6f4672
%Zis the correct way to specify a Time zone name. Have you tried the following ?
%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)
回答by ryancheung
Try this:
尝试这个:
zone = "Central Time (US & Canada)"
ActiveSupport::TimeZone[zone].parse("2013-04-03 17:47:00")
回答by Artur Beljajev
Use String#in_time_zone(Rails 4+)
使用String#in_time_zone(Rails 4+)
I personally prefer using String#in_time_zone:
我个人更喜欢使用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
This parses the date and time in the String into the time zone provided.
这会将字符串中的日期和时间解析为提供的时区。
回答by ifightcrime
This is the method that I came up with. Not the prettiest, but it works. Allows parsing the string using a specified format, and then turning it into the format that I know Time.zone.parserequires.
这是我想出的方法。不是最漂亮的,但它有效。允许使用指定格式解析字符串,然后将其转换为我知道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
Then you can do something like what was mentioned in another question, but with a specified format:
然后你可以做一些类似于另一个问题中提到的事情,但使用指定的格式:
zone = "Central Time (US & Canada)"
ActiveSupport::TimeZone[zone].strptime('2013-04-03', '%Y-%m-%d')
Or if you already have a time zone set:
或者,如果您已经设置了时区:
Time.zone = "Central Time (US & Canada)"
Time.zone.strptime('01/13/2006')
I used a default format of %m/%d/%Ybecause that's what my user input is most of the time. You can customize this to your needs, or use the default format DateTimeuses which is believe is iso8601 (%FT%T%z)
我使用了默认格式,%m/%d/%Y因为这是我的用户输入的大部分时间。您可以根据自己的需要对其进行自定义,或者使用默认的格式DateTime,相信是 iso8601 ( %FT%T%z)
回答by Phitherek_
I've finally found the dirty, yet definitive way to do this.
我终于找到了一种肮脏但明确的方法来做到这一点。
First, parse the string using plain Ruby Time.strptime like this:
首先,使用普通的 Ruby Time.strptime 解析字符串,如下所示:
time = Time.strptime('12 : 00 : PM', '%I : %M : %p')
This way you get the parsed Time, but not yet in correct timezone. To fix that, let's convert the time to string form and parse it with the standard ActiveSupport::TimeZone#parse
这样你就可以得到解析的时间,但还没有在正确的时区。为了解决这个问题,让我们将时间转换为字符串形式并使用标准 ActiveSupport::TimeZone#parse 解析它
Time.zone.parse(time.to_s)
The result is the ActiveSupport::TimeWithZone with our time parsed into the correct timezone.
结果是 ActiveSupport::TimeWithZone 将我们的时间解析为正确的时区。
The reason why we have to do it this way is that neither ActiveSupport::TimeZone nor ActiveSupport::TimeWithZone support the strptime method. So we have to parse the Time with core Ruby strptime that does not have timezone information, convert it to format acceptable in ActiveSupport objects and then parse it yet again.
我们必须这样做的原因是 ActiveSupport::TimeZone 和 ActiveSupport::TimeWithZone 都不支持 strptime 方法。因此,我们必须使用没有时区信息的核心 Ruby strptime 解析时间,将其转换为 ActiveSupport 对象中可接受的格式,然后再次解析它。
回答by DenisKo
Convert specific date format in UTC.
以 UTC 格式转换特定日期格式。
ActiveSupport::TimeZone['UTC'].parse(Time.strptime('01/24/2019T16:10:16', "%m/%d/%YT%H:%M:%S").asctime)
回答by Jon
To have DateTime take the date string and attach a timezone other than UTC without changing the values of the date string , use this, its easy , doesnt break on leap day :)
要让 DateTime 获取日期字符串并附加 UTC 以外的时区而不更改日期字符串的值,请使用它,它很简单,不会在闰日中断:)
xx = DateTime.strptime("9/1/15 #{object.time_zone}", "%m/%d/%Y %Z")

