查询日期时间范围,同时考虑时区

发布于 2024-11-06 18:18:52 字数 874 浏览 0 评论 0原文

我在查询时遇到很多麻烦。我真的不知道如何很好地解释这一点,但我会尝试。

基本上,我们有几个带有“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜未央樱花落 2024-11-13 18:18:52

您永远不想在数据库中存储时区信息。

以下是讨论一些陷阱的阅读内容:

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 using posted_at between ? and ?.

放手` 2024-11-13 18:18:52

您可能会更幸运地将开始时间和结束时间转换为 UTC,这将使时区在进行查询本身时几乎不相关。这很容易完成:

start_date.to_time.to_datetime.beginning_of_day.utc
end_date.to_time.to_datetime.end_of_day.utc

您还可以将查询调整为:

posted_at BETWEEN :start AND :end

确保您正在搜索的字段也有索引,否则您将获得糟糕的性能。

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:

start_date.to_time.to_datetime.beginning_of_day.utc
end_date.to_time.to_datetime.end_of_day.utc

You can also adjust your query to be:

posted_at BETWEEN :start AND :end

Be sure to have an index on the fields you're searching, too, or you will get horrible performance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文