2009-03-11 10 views
6

Mam aplikację szyny, w której przechowuję created_at jako datetime (standard). Buduję formularz do wyszukiwania i uważam, że muszę użyć find_by_sql do wykonywania złożonych podzapytań. Formularz ma zakres dat (brak czasu) do wyszukiwania dla pozycji created_at.Jak poprawnie konwertować lub zapytać Zakres dat dla szyn/MySQL DataTime Kolumna

Problem Uważam, że jeśli ja przechodzę tylko w ciągu aktualna oferta na zakres kwerendy ...

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

wracam rekordy, które mają datę created_at z 2009-01-23 17: 10:39 -0800, ponieważ jest on przechowywany w db jako 2009-01-24 01:10:39 (UTC)

Jak mogę to naprawić, aby wynik nie zwrócił rekordu?

Wydaje I albo trzeba konwertować zakres dat być UTC specyficzny lub poinformować find_by_sql do wyszukiwania na podstawie aktualnej strefy czasowej zamiast czytać kolumnę jako UTC ...

Wszelkie chętnych?

John

Odpowiedz

4

wiem, że jest to stara sprawa, ale w odpowiedzi Usprawnia zapytanie o CONVERT_TZ:

Jeśli nie masz załadowanych tabel strefy czasowej mySQL (co jest mało prawdopodobne w przypadku instalacji wanilii), musisz wprowadzić strefy czasowe jako przesunięcie od czasu UTC.

CONVERT_TZ(status_changes.created_at, '+00:00', '+08:00') between '2009-01-24' and '2009-03-12') 
+0

Dzięki Jordan. Nie jestem pewien, czy będę mógł to przetestować w najbliższym czasie, ale twoja odpowiedź wydaje się wiarygodna. – Streamline

1

MySQL ma CONVERT_TZ funkcję, która pobiera datetime i konwertuje go z jednej strefy czasowej do drugiej. Możesz zbudować zapytanie, aby przekonwertować z wartości przechowywanej (UTC) do lokalnej strefy czasowej (PST).

CONVERT_TZ(status_changes.created_at,'UTC',?) between ? and ?, 'PST, '2009-01-24', '2009-03-10' 
7

Jeśli nie używać find_by_sql, ale raczej użyć find z :conditions klauzuli Chodźmy Szyny zrobić substytucje, zostanie ona automatycznie konwertować wszystko.

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

Najgorszy przypadek, jeśli Rails jest zdezorientowany przez terminach, można przekonwertować je do czasów i powinno grać ładnie:

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

Próbowałem odpowiedzi Iana, ale nie działało. Railsy poprawnie obsługują strefę czasową, gdy zapisy są zapisywane i ładowane, ale nie wydają się robić tego samego dla parametrów zapytania. Zauważ, że aplikacja, nad którą pracuję, jest w Railsach 2.1.1, więc od tego czasu sytuacja nieco się poprawiła.

Jedno małe usprawnienie umożliwiło mi wykonanie rozwiązania Iana: Pobierz wartość czasu w strefie czasowej UTC za pomocą metody getutc, a następnie podaj ją jako parametr. Nie powinno to również powodować żadnych szkód w późniejszych wersjach Railsów, które mogą poprawnie obsługiwać strefę parametrów czasowych, ponieważ czas UTC nie jest zmieniany przez getutc, tylko strefę czasową.

0

Ponieważ Szyny przechowuje daty w UTC w bazie danych należy użyć metody utc na Time lub DateTime

tj

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

Więcej informacji można znaleźć na stronie http://marklunds.com/articles/one/402 – paulodeon

12

Nowoczesny ActiveRecord sposobem osiągnięcia tego celu jest:

Model.where(time_field: date1..date2) 
-1
Model.where(:from => "2012-01-01".to_date.."2012-06-30".to_date) 

pracował dla mnie (: z pola jest baza danych typu 'data')