2009-06-01 19 views
5

Estoy tratando de convertir nuestra aplicación Rails 2.3 para manejar correctamente las zonas horarias (en este momento todo está en UTC que no es correcto, pero es conveniente!)Almacenamiento correcto de fechas con TimeZone en MySQL DB para una aplicación Rails

tengo estos ajustes en environment.rb:

config.active_record.default_timezone = :utc 
config.time_zone = "UTC" 

De cara al futuro, en cada solicitud en nuestra aplicación planeo hacer la siguiente configuración para establecer la zona horaria:

Time.zone = user.time_zone 

Dónde user.time_zone es su preferencia elegida (por ejemplo, US Pacific Time).

Esto funciona bien en la aplicación, pero mi pregunta se relaciona con lo que Rails almacena en el MySQL DB. Si el usuario elige una fecha del 1 de junio de 2009, se almacena en un campo DATETIME en la base de datos en UTC pero con el desplazamiento de la zona horaria. Por ejemplo, si el usuario ha seleccionado un huso horario GMT+6, la fecha elegida del 1 de junio de 2009 termina en la base de datos como 2009-06-01 06:00:00 UTC.

Hubiera esperado que se almacenara como 2009-06-01 00:00:00 UTC en la base de datos. ¿Es correcto mi razonamiento o Rails está haciendo algo inesperado aquí?

+0

¿Solo necesita mostrar las fechas en la zona horaria del usuario, o es importante almacenarlas específicamente en esa zona horaria? –

+0

Chris Me gustaría almacenarlo en UTC y solo mostrar las fechas en la zona horaria del usuario – Olly

Respuesta

4

este blog post habla acerca de la manipulación de zona horaria nativa en Rails 2.1 +:

http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/

Lo esencial es que Rails almacenar todos los registros de la base de datos en UTC y luego convertir a la zona horaria a los usuarios para su visualización . Lo cual tiene sentido: almacenar todos los datos en una forma neutral, y luego convertirlos a la forma deseada en el último minuto.

0

Debe configurar la zona horaria en el objeto de datos antes de establecer la fecha.

1

Según su respuesta a mi comentario, diría que simplemente almacene la fecha según la hora del servidor local, luego use la fecha de JavaScript :: toLocaleString() para convertirla a su zona horaria local. Escribí un artículo sobre esto hace un par de años, que puedes encontrar en here.

El artículo JS estaba escrito en MooTools, pero desde entonces lo reescribí con jQuery, así que mostraré ese código.

Las partes importantes:

Cuando la prestación de HTML, utilice los milisegundos desde la Época.

<span class="dt"><!-- <%= blah.created_at_epoch_ms %> --><%= blah.created_at %></span> 

que requiere un método en su modelo definido de esta manera:

def created_at_epoch_ms 
    self.created_at.to_i * 1000 
end 

El JS para transformar las fechas:

$(document).ready(function(){ 
     $('span.dt').each(function(){ 
       var date = new Date(); 

       date.setTime(this.firstChild.data); 

       $(this).parent().text(date.toLocaleString()); 
     }); 
}); 

Esto debe convertir la cadena a la hora local del usuario, y la magia ocurre en toLocaleString(). El único navegador del que he oído hablar que no implementa es Safari 2.0, que no debería representar un gran problema, ya que creo que la mayoría de los usuarios han avanzado.

Utilizo este método en my site, y si miras el código fuente de la página, puedes ver lo que hace.El código real que se envía al navegador parece:

<!-- 1243484521000 -->2009-05-28 04:22:01 UTC 

que se convierte en mi navegador (Hora del Centro) a

Wednesday, May 27, 2009 11:22:01 PM 

Si han permitido JS, tomará el valor de la nodo de comentario, transfórmelo y reemplace toda la cadena (incluida la hora UTC) con la hora local. Si JS está desactivado, solo verán la hora a medida que el servidor la vea.

Cuestiones relacionadas