Time.zone y consultas Mysql

Hola a todos,
Actualmente ando trabajando en un proyecto llamado mientrenamiento.com.
Aquí, cuando un usuario se da de alta, debe seleccionar su zona horaria,
para ello utilizo el Timezone de Rails 2.1.

El problema con el que me encuentro es el siguiente, un usuario puede
insertar entrenamientos, cada entrenamiento tiene su campo ‘created_at’
que se guarda en UTC en la base de datos, independientemente de la zona
horaria del usuario. Imaginemos ahora un entrenamiento insertado a las
00:01 hora local de Madrid:

Time.zone
=> #<TimeZone:0x21f4cec @tzinfo=#<TZInfo::DataTimezone: Europe/Madrid>,
@name=“Madrid”, @utc_offset=3600>
t = Training.find(1)
=> #<Training id: 1, user_id: 1, shoe_id: 1, block: “long_run”,
distance: 8000.0, unit: “km”, duration_hour: 0, duration_min: 40,
duration_sec: 0, calories: 0, max_heart_rate: 0, average_heart_rate: 0,
description: “”, created_at: “2008-07-01 22:01:00”, updated_at:
“2008-07-02 12:54:29”, is_planning: false, weight: “”, route_id: nil>
t.created_at
=> Wed, 02 Jul 2008 00:01:00 CEST +02:00

Como se puede observar, en la BD tenemos la hora 22:01:00 del día 1 de
Julio, pero realmente lo insertamos el 2 de Julio a las 00:01 hora local
española. Esto me está dando problemas al pintar las gráficas de
kilómetros, ya que este entrenamiento en cuestión se pintará el día 1 y
no el 2 como sería lo correcto. El problema lo veo en la consulta SQL:

@trainings = current_user.trainings.finished.find(:all,
:conditions => [“created_at between ? and ?”,
@date.beginning_of_month, @date.end_of_month],
:select => “DATE(created_at) as created_at, sum(distance)/1000 as
distance”,
:group => “DATE(created_at)”)

Donde:

@date = Time.zone.parse("#{params[:date]}").to_date ||

Time.zone.today

La sentencia SQL generada es:

SELECT DATE(created_at) as created_at, sum(distance)/1000 as

distance FROM trainings WHERE (trainings.user_id = 1 AND (created_at
between ‘2008-07-01’ and ‘2008-07-31’)) AND (is_planning = 0) GROUP BY
DATE(created_at) ORDER BY created_at desc

Resultado:

created_at distance
2008-07-01 8

Por ese motivo la gráfica me está pintando el entrenamiento en el día 01
y no en el 02 como debería.

¿Alguien me puede dar alguna pista sobre este tema?

Muchas gracias por anticipado a todos !

On Jul 2, 2008, at 4:41 PM, Vicent G. wrote:

¿Alguien me puede dar alguna pista sobre este tema?

Yo creo que tienes es un problema de Offsets.

Lo que insertas en la base de datos está en UTC así que lo que extraes
de la base de datos está en UTC

Has de adaptar la fecha que extraes al TimeZone del usuario.

Mirate …

http://ryandaigle.com/articles/2008/1/25/what-s-new-in-edge-rails-easier-timezones

Hola Francesc,
Un placer hablar contigo, creo que ya lo hemos hecho en alguna otra
ocasión.

Ten en cuenta que en la sentencia SQL estoy agrupando por GROUP BY
DATE(created_at), es decir, por fechas, y desde aquí no puedo convertir
la fecha/hora UTC a la fecha/hora de la zona del usuario en cuestión.
Por eso comentaba que el problema lo tenía en la sentencia SQL.

Si te fijas, Google Analytics se encontró con un problema similar, las
estadísticas del día no te las da hasta el día siguiente. Lo que pasa
que ellos han solucionado el problema y yo no se como :wink:

Un saludo.

On Jul 2, 2008, at 5:24 PM, Vicent G. wrote:

Ten en cuenta que en la sentencia SQL estoy agrupando por GROUP BY
DATE(created_at), es decir, por fechas, y desde aquí no puedo
convertir
la fecha/hora UTC a la fecha/hora de la zona del usuario en cuestión.
Por eso comentaba que el problema lo tenía en la sentencia SQL.

El problema lo tienes
aquí:
@date.beginning_of_month

Que ha de ser …

@date.zone.beginning_of_month

Joder, como me gusta Rails. ¿Simple no? A mi se me caen los lagrimones
de emoción cuando veo estas cosas.

Hola a los dos,
pues es una pena, al hacer el @date.zone.beginning_of_month devuelve un
error, no está definido.

Tendré que buscar otra solución;
gracias de todas formas.

Que ha de ser …

@date.zone.beginning_of_month

Muchas gracias Francesc,
aunque creo que @date.zone no está definido para Date:Class, si lo
estuviera problema solucionado !

Gracias.

On Jul 2, 2008, at 5:50 PM, Vicent G. wrote:

@date.zone.beginning_of_month

Pero puedes hacer un Time.zone.now.beginning_of_month.to_s(:db)