2009-03-11 9 views
6

Tengo una aplicación de rieles donde almaceno created_at como datetime (estándar). Estoy creando un formulario para buscar y encuentro que tengo que usar find_by_sql para hacer algunas subconsultas complejas. El formulario tiene un rango de fechas (sin tiempo) para buscar artículos creados en el campo.Cómo convertir o consultar correctamente el rango de fechas para Rails/MySQL DateTime Columna

El problema que encontramos es que si paso en tan sólo la cadena de fecha para la gama para consultar ...

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

Me estoy haciendo volver los registros que tienen una fecha de created_at 2009-01-23 17: 10:39 -0800 porque está almacenado en el db como 2009-01-24 01:10:39 (UTC)

¿Cómo puedo solucionar esto para que el resultado no devuelva el registro en cuestión?

parece que sea necesario para convertir el intervalo de fechas que ser UTC específica o decirle al find_by_sql de búsqueda basados ​​en zona horaria actual en lugar de leer la columna como UTC ...

Toda la toma?

John

Respuesta

4

Sé que esto es una cuestión de edad, sino en respuesta a Agiliza la consulta sobre CONVERT_TZ:

A menos que tengas cargados las tablas timezone con el nombre mySQL (lo cual es bastante improbable en una instalación simple), debes ingresar las zonas horarias como un desplazamiento de UTC.

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

Gracias Jordan. No estoy seguro de que pueda probar esto pronto, pero su respuesta parece plausible. – Streamline

1

MySQL tiene una función CONVERT_TZ que se lleva a una fecha y hora y la convierte de una zona horaria a otra. Puede construir su consulta para convertir desde el valor almacenado (UTC) a su zona horaria local (PST).

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

Si no se utiliza find_by_sql, sino más bien utilizar un find con una cláusula :conditions que vamos a hacer sustituciones rieles, que convertirá todo automáticamente.

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

peor de los casos, si los carriles se confunde con las fechas, puede convertirlos a veces y debe jugar muy bien:

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

Probé la respuesta de Ian, pero no funcionó del todo. Rails está manejando correctamente la zona horaria cuando los registros se guardan y cargan, pero no parece hacer lo mismo para los parámetros de consulta. Tenga en cuenta que la aplicación en la que estoy trabajando está en Rails 2.1.1, por lo que las cosas pueden haber mejorado algo desde entonces.

Con una pequeña modificación, pude hacer que la solución de Ian funcionara: Obtener el valor del tiempo en la zona horaria UTC utilizando el método getutc, y luego pasarlo como el parámetro. Esto tampoco debería causar ningún daño en las versiones posteriores de Rails que puedan manejar correctamente la zona del parámetro de tiempo, ya que getutc no modifica la hora UTC, solo la zona horaria.

0

Debido a que los carriles almacena las fechas en UTC en la base de datos se debe utilizar el método de utc en Time o DateTime

es decir,

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

Visita http://marklunds.com/articles/one/402 para más información – paulodeon

12

La moderna forma ActiveRecord de hacer esto es:

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

trabajó para mí (: a partir de la base de datos es el campo del tipo 'fecha')

Cuestiones relacionadas