带时区的 Strptime
我有一个用 DateTime.strptime
解析的字符串。字符串中日期的时区是 CET,但 Ruby 创建了一个 UTC DateTime 对象,当然它有 2 小时的偏移量。
目前我正在使用 DateTime.strptime().change(:offset => "+0020")
解决这个问题,但我很确定这不是它应该工作的方式。
有人可以启发我正确的方法吗?
I have a String which I parse with DateTime.strptime
. The Timezone of the Date in the String is CET but Ruby creates an UTC DateTime object which of course has an offset of 2hrs.
Currently I'm working around the issue with DateTime.strptime().change(:offset => "+0020")
but I'm pretty sure this is not the way it's meant to work.
Can someone enlighten me on the correct way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我按以下方式使用它:
这是你的意思吗?
I use it the following way:
Is it what you mean?
这适用于 Rails 5:
返回指定时区的时间。
This works in Rails 5:
Returns the time in the specified time zone.
至少从 Rails 4.2 开始(可能更早,尚未测试)只要您使用
Time#strptime
而不是DateTime.strptime
,就会自动应用当前时区:At least as of Rails 4.2 (maybe earlier, haven't tested) as long as you use
Time#strptime
instead ofDateTime.strptime
, the current time zone is automatically applied:我正在“strptiming”这个字符串:
本地时间戳,在我的例子中是奥克兰新西兰,字符串中没有时区时间戳,如图所示。
据我所知
Time.strptime
使用服务器时区作为基础。在我的情况和一般的良好实践中,我的服务器在 UTC 时区运行,因此字符串的每次解析最终都会创建一个时间对象,即 +0000 (UTC) 的时间:
然后转换为
in_time_zone(Time.zone)< /code> 给出:
可以看出,这比我想要的实际时间晚了 12 小时(UTC 偏移量)。
我尝试按照上面的方式使用
+' Oakland', '...%Z'
技巧,无需任何更改。然后我按照上面的方法使用了
+ '+1200', '...%Z'
技巧,它工作正常。然而,我担心夏天的时间,那么解析会花费一个小时,所以这就是我完成的结果:
结果:
它不是特别优雅,但它有效。
I was "strptiming" this string:
A local timestamp, which is in my case is Auckland NZ without a timezone stamp in the string as can be seen.
As best I can tell
Time.strptime
uses the server timezone as the base.In my situation, and general good practice, my servers run in UTC timezone so every parse of the string ended up creating a time object, the time to +0000 (UTC):
Then converting to
in_time_zone(Time.zone)
gave:Which as can be seen is 12 hours (the UTC offset) later than the actual time I wanted.
I tried to use the
+' Auckland', '...%Z'
trick as per above without any change.I then used the
+ '+1200', '...%Z'
trick as per above which worked correctly.However I was concerned about summer time, then the parsing would be out by an hour, so this is what I've finshed with:
Result:
It's not particularly elegant but it works.
您可以使用
to_time_in_current_zone
将日期转换为时区。例如:You can convert date to timezone with
to_time_in_current_zone
. For example:我一直在努力解决同样的问题,试图从表单中解析日期字符串并独立于服务器时间保存它。我遵循的过程就是这样。
我保证 RoR 和 Ruby 时区设置为 UTC。如果服务器也采用 UTC 时间,事情会变得更容易。
我使用 ActiveSupport:TimeZone 格式存储用户区域设置,例如
US/Eastern
我有一个解释日期函数,它可以解释本身不包含时区或偏移量的日期字符串,
这当然感觉不是一个完美的解决方案,但它有效。
确保时区正确的步骤是:
I have been battling this same issue trying to parse a date string from a form and save it independently of the servers time. The process I have followed is as such.
I assure the RoR and Ruby timezones are set to UTC. It makes it easier if the server is on UTC time as well.
I am storing the users locale using the ActiveSupport:TimeZone format like
US/Eastern
I have an interpret date function which can account for a date string that doesn't natively contain a timezone or offset
This of course doesn't feel like a perfect solution but it works.
The steps to assure the correct timezone are:
对于 Rails 5 之前的版本,以下内容将起作用:
For pre Rails 5, the following will work:
尝试一下
你在这里所做的事情:
假设您想更改为时区 5,
我将在您的日期时间上添加 5 小时,保持时区不变。
之后,如何调整偏移量以恢复原始数据并获得您想要的时区。
try this
what u are doing here:
suppose that u want to change to timezone 5
i'll add 5 hour to your datetime, maintain the time zone.
after, how adjust the offset to recover the original data and get the timezone that u want.
我无法删除已接受的答案
正如 @LeeJarvis 在下面的评论部分指出的那样,
Chronic.parse
不接受:time_class
选项。所以这个答案是有缺陷的,虽然看起来可行,但实际上并没有(除非 Chronic 很快允许传递:time_class
选项。)Chronic gem 确实很强大。
我这样使用它:
在上面的示例中,
User.first.time_zone
是“太平洋时间(美国和加拿大)”。Chronic 支持多种格式,因此请查看
https://github.com/mojombo/chronic
确保传递
:time_class 选项并转换为 UTC(在文档中,Chronic 在调用解析之前设置
:time_class
。我避免使用这种方法,因为它可能会导致应用程序中的其他部分无法工作)TimeZone 的文档位于
http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html
I can't delete an accepted answer
As @LeeJarvis pointed out in the comment section below,
Chronic.parse
does not accept a:time_class
option. So this answer is buggy and while it looks like it works, it doesn't (unless Chronic allows passing a:time_class
option soon.)The Chronic gem is really powerful.
I use it like this:
In my example above,
User.first.time_zone
is "Pacific Time (US & Canada)".Chronic supports a lot of formats so check it out at
https://github.com/mojombo/chronic
Make sure to pass the
:time_class
option and to convert to UTC (in the documentation, Chronic sets:time_class
before calling parse. I avoid this approach because it might cause other parts across the application not to work)TimeZone's documentation is at
http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html