Запрос диапазона дат и времени с учетом часового пояса - PullRequest
0 голосов
/ 13 мая 2011

У меня много проблем с запросом. Я не знаю, как объяснить это хорошо, но я собираюсь попробовать.

По сути, у нас есть несколько объектов с полем «posts_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

Хотя это дает мне точные результаты, оно также имеет ужасную производительность и вызывает некоторые таймауты в моем приложении.

Я не мог найти другой способ выполнить этот запрос и все еще сохранять точные результаты. Будет ли у кого-нибудь совет или идеи?

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 14 мая 2011

Вы никогда не хотите хранить информацию о часовом поясе в своей базе данных.

Вот чтение, в котором обсуждаются некоторые подводные камни:

http://derickrethans.nl/storing-date-time-in-database.html

Вы поправитесьРезультаты, как подсказывает Тэдман: добавьте новое поле со своей отметкой времени at time zone 'utc' и внесите его в указатель.После этого вы сможете захватывать вещи, используя posted_at between ? and ?.

0 голосов
/ 13 мая 2011

Возможно, вам больше повезет, если вы переведете время начала и окончания в 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

Убедитесь, что у вас есть индекс и по полям, которые вы ищете, илиВы получите ужасную производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...