2009-06-01 6 views
5

Sto cercando di convertire la nostra applicazione Rails 2.3 per gestire correttamente i fusi orari (al momento tutto è in UTC che non è giusto, ma è conveniente!).Memorizzare correttamente le date con TimeZone nel DB MySQL per un'applicazione Rails

ho queste impostazioni in environment.rb:

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

Andando avanti, ad ogni richiesta nella nostra app Ho intenzione di fare la seguente impostazione per impostare il fuso orario:

Time.zone = user.time_zone 

Dove user.time_zone è la preferenza scelta (ad esempio US Pacific Time).

Questo funziona correttamente nell'app, ma la mia domanda si riferisce a ciò che Rails quindi memorizza nel DB MySQL. Se l'utente sceglie una data del 1 ° giugno 2009, questa viene archiviata in un campo DATETIME nel database in UTC ma con l'offset del fuso orario. Ad esempio, se l'utente ha selezionato un fuso orario GMT+6, una data scelta del 1 giugno 2009 finisce nel database come 2009-06-01 06:00:00 UTC.

Mi sarei aspettato che questo fosse memorizzato come 2009-06-01 00:00:00 UTC nel database. Il mio pensiero è corretto o Rails sta facendo qualcosa di inaspettato qui?

+0

Hai solo bisogno di visualizzare le date nel fuso orario dell'utente, o è importante memorizzarlo in modo specifico in quel fuso orario? –

+0

Chris Mi piacerebbe archiviarlo in UTC e visualizzare solo le date nel fuso orario dell'utente – Olly

risposta

4

questo post del blog parla di manipolazione Fuso orario nativo in Rails 2.1+:

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

il succo è che Rails memorizzerà tutti i record nel DB in UTC e poi convertire il fuso orario gli utenti per la visualizzazione . Il che ha senso: memorizzare tutti i dati in un modulo neutro e convertirli nel modulo desiderato all'ultimo minuto.

0

È necessario impostare il fuso orario nell'oggetto di dati prima di impostare la data.

1

In base alla risposta al mio commento, direi semplicemente memorizzare la data in base all'ora del server locale, quindi utilizzare JavaScript Date :: toLocaleString() per convertirlo nel fuso orario locale. Ho scritto un articolo su di esso un paio di anni fa, che puoi trovare here.

Il JS dell'articolo è stato scritto in MooTools, ma da allora l'ho riscritto con jQuery, quindi mostrerò quel codice.

Le parti importanti:

Quando il rendering in HTML, utilizzare i millisecondi dall'Epoca.

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

che richiede un metodo nel modello definito in questo modo:

def created_at_epoch_ms 
    self.created_at.to_i * 1000 
end 

Il JS per trasformare le date:

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

       date.setTime(this.firstChild.data); 

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

Questo dovrebbe convertire la stringa ora locale dell'utente, e la magia accade in toLocaleString(). L'unico browser che ho sentito non implementarlo è Safari 2.0, che non dovrebbe presentare molti problemi, poiché penso che la maggior parte degli utenti sia passata.

Io uso questo metodo su my site e se si guarda il codice sorgente alla pagina, è possibile vedere che cosa fa.Il codice vero e proprio che viene inviato al browser appare come:

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

che viene convertito nel mio browser (Central Time) per

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

Se hanno JS abilitato, ci vorrà il valore della commentare il nodo, trasformarlo e sostituire l'intera stringa (compresa l'ora UTC) con l'ora locale. Se JS è disabilitato, vedranno solo l'ora mentre il server lo vede.