Как правильно конвертировать или запрашивать диапазон дат для Rails / MySQL DateTime Column - PullRequest
6 голосов
/ 12 марта 2009

У меня есть приложение rails, где я сохраняю create_at как datetime (стандарт). Я строю форму для поиска, и я обнаружил, что должен использовать find_by_sql для выполнения некоторых сложных подзапросов. Форма имеет диапазон дат (без времени) для поиска элементов в поле selected_at.

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

... status_changes.created_at between '2009-01-24' and '2009-03-12' ...

Я получаю обратно записи, которые имеют дату create_at 2009-01-23 17:10:39 -0800, потому что они хранятся в БД как 2009-01-24 01:10:39 (UTC)

Как я могу это исправить, чтобы результат не возвращал соответствующую запись?

Кажется, мне нужно либо преобразовать диапазон дат, чтобы он был специфичен для UTC, либо указать find_by_sql выполнять поиск по текущему часовому поясу вместо чтения столбца как utc ...

Кто-нибудь принимает?

John

Ответы [ 7 ]

12 голосов
/ 13 марта 2012

Современный способ ActiveRecord сделать это:

Model.where(time_field: date1..date2)
7 голосов
/ 12 марта 2009

Если вы не используете find_by_sql, а вместо этого используете find с предложением :conditions, которое позволяет Rails выполнять подстановки, оно автоматически преобразует все.

Model.find :all, 
  :conditions => ["created_at between ? and ?", start_date, end_date]

В худшем случае, если Rails смущен датами, вы можете преобразовать их во времена, и это должно выглядеть красиво:

Model.find :all, 
  :conditions => ["created_at between ? and ?", 
                   start_date.to_time, end_date.to_time]
4 голосов
/ 20 мая 2010

Я знаю, что это старый вопрос, но в ответ на запрос Streamlines о CONVERT_TZ:

Если у вас не загружены таблицы часовых поясов с именами mySQL (что весьма маловероятно при простой установке), вам нужно вводить часовые пояса как смещение от UTC.

CONVERT_TZ(status_changes.created_at, '+00:00', '+08:00') between '2009-01-24' and '2009-03-12')
1 голос
/ 12 марта 2009

MySQL имеет функцию CONVERT_TZ , которая принимает дату и время и преобразует ее из одного часового пояса в другой. Вы можете создать свой запрос для преобразования сохраненного значения (UTC) в местный часовой пояс (PST).

CONVERT_TZ(status_changes.created_at,'UTC',?) between ? and ?, 'PST, '2009-01-24', '2009-03-10'
0 голосов
/ 18 апреля 2012
Model.where(:from => "2012-01-01".to_date.."2012-06-30".to_date)

работал для меня (: from это поле базы данных типа 'date')

0 голосов
/ 09 сентября 2010

Поскольку Rails хранит даты в UTC в базе данных, вы должны использовать метод utc для Time или DateTime

т.е.

Model.find :all, 
  :conditions => ["created_at between ? and ?", start_date.utc, end_date.utc]
0 голосов
/ 02 августа 2010

Я попробовал ответ Яна, но он не совсем сработал. Rails правильно обрабатывает часовой пояс, когда записи сохраняются и загружаются, но, похоже, не делает то же самое для параметров запроса. Обратите внимание, что приложение, над которым я работаю, находится в Rails 2.1.1, поэтому с тех пор ситуация могла несколько улучшиться.

С помощью одного небольшого изменения я смог заставить решение Иана работать: получить значение времени в часовом поясе UTC, используя метод getutc, а затем передать его как параметр. Это также не должно причинять никакого вреда в любых более поздних версиях Rails, которые могут правильно обрабатывать часовой пояс, поскольку время UTC не изменяется getutc, только часовой пояс.

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