查询日期时间范围,同时考虑时区
我在查询时遇到很多麻烦。我真的不知道如何很好地解释这一点,但我会尝试。
基本上,我们有几个带有“posted_at”字段的对象,该字段将发布内容的日期和时间以及时区保存在日期时间字段中。我需要查询并获取这些对象的日期范围。
以前,我将其转换为 Date 并将其与另一个 Date 对象进行比较。查询是这样的:
Date(posted_at) >= :start_date AND Date(posted_at) <= :end_date
但是,当 Postgre 将其转换为 Date 时,它丢失了时区信息,导致查询结果不准确。
因此,我对此进行了更改:
if start_date then
start_time = Time.zone.parse("#{start_date.year}-#{start_date.month}-#{start_date.day}")
conditions << "posted_at >= :start"
hash[:start] = start_time
end
if end_date then
end_time = Time.zone.parse("#{end_date.year}-#{end_date.month}-#{end_date.day}").end_of_day
conditions << "posted_at <= :end"
hash[:end] = end_time
end
虽然这为我提供了准确的结果,但它的性能也很糟糕,并且导致我的应用程序出现一些超时。
我找不到任何其他方法来执行此查询并仍然保持准确的结果。有人有一些建议或想法吗?
先感谢您。
I'm having a lot of trouble with a query. I don't really know how to explain this well, but I'm going to try.
Basically, we have several objects with a 'posted_at' field that keeps the date and time something was posted, with the time zone, in a datetime field. I need to query and get a range by date with those objects.
Previously, I was converting that to Date and comparing it to another Date object. The query was something like this:
Date(posted_at) >= :start_date AND Date(posted_at) <= :end_date
However, when Postgre converted it to Date, it lost the timezone info which caused innacurate results to the query.
So, I changed to this:
if start_date then
start_time = Time.zone.parse("#{start_date.year}-#{start_date.month}-#{start_date.day}")
conditions << "posted_at >= :start"
hash[:start] = start_time
end
if end_date then
end_time = Time.zone.parse("#{end_date.year}-#{end_date.month}-#{end_date.day}").end_of_day
conditions << "posted_at <= :end"
hash[:end] = end_time
end
While this gets me the accurate results, it also has horrible performance and is causing some timeouts in my application.
I couldn't find any other way to do this query and still keep the accurate results. Would anyone have some advice or ideas?
Thank you in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您永远不想在数据库中存储时区信息。
以下是讨论一些陷阱的阅读内容:
http://derickrethans.nl/storing -date-time-in-database.html
按照 tadman 的建议,您将获得更好的结果:添加一个新字段,其中包含时间戳
时区“utc”
和索引 它。然后,您将能够使用posted_at 之间的内容来获取内容?和?
。You never want to store timezone information in your database.
Here's a read that discusses some of the pitfalls:
http://derickrethans.nl/storing-date-time-in-database.html
You'll get better results as tadman suggests: add a new field with your timestamp
at time zone 'utc'
, and index it. You'll then be able to grab stuff usingposted_at between ? and ?
.您可能会更幸运地将开始时间和结束时间转换为 UTC,这将使时区在进行查询本身时几乎不相关。这很容易完成:
您还可以将查询调整为:
确保您正在搜索的字段也有索引,否则您将获得糟糕的性能。
You may have more luck converting your start and end times to UTC which would render the time-zone mostly irrelevant when making the query itself. This is done easily enough:
You can also adjust your query to be:
Be sure to have an index on the fields you're searching, too, or you will get horrible performance.