2009-06-01 6 views
5

Ich bin dabei, unsere Rails 2.3-Anwendung auf Zeitzonen umzustellen (im Moment ist alles in UTC, was nicht stimmt, aber ist bequem!).Richtiges Speichern von Datumsangaben mit TimeZone in MySQL DB für eine Rails-Anwendung

Ich habe diese Einstellungen in environment.rb:

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

Auch in Zukunft auf jede Anfrage in unserer App mich darauf, die folgende Einstellung plane, die Zeitzone einzustellen:

Time.zone = user.time_zone 

Wo user.time_zone ist ihre bevorzugte Wahl (zB US Pacific Time).

Das funktioniert in der App gut, aber meine Frage bezieht sich darauf, was Rails dann in der MySQL DB speichert. Wenn der Benutzer ein Datum vom 1. Juni 2009 auswählt, wird dieser in einem Feld DATETIME in der Datenbank in UTC aber mit der Zeitzone versetzt. Wenn der Benutzer beispielsweise eine GMT+6 Zeitzone ausgewählt hat, endet ein ausgewähltes Datum vom 1. Juni 2009 in der Datenbank als 2009-06-01 06:00:00 UTC.

Ich hätte erwartet, dass dies als 2009-06-01 00:00:00 UTC in der Datenbank gespeichert wird. Ist mein Denken korrekt oder macht Rails hier etwas Unerwartetes?

+0

Müssen Sie nur die Daten in der Zeitzone des Benutzers anzeigen, oder ist es wichtig, sie speziell in dieser Zeitzone zu speichern? –

+0

Chris Ich möchte es in UTC speichern und nur die Daten in der Zeitzone des Benutzers anzeigen – Olly

Antwort

4

Dieser Blog-Post spricht über nativen Zeitzone in Rails Handhabung 2.1+:

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

Das Wesentliche ist, dass Rails alle Datensätze in der DB in UTC gespeichert werden und dann für die Anzeige auf die Benutzer Zeitzone konvertieren . Sinnvoll: Speichern Sie alle Daten in einer neutralen Form und konvertieren Sie sie dann in letzter Minute in die gewünschte Form.

0

Sie müssen die Zeitzone im Datenobjekt festlegen, bevor Sie das Datum festlegen.

1

Basierend auf Ihrer Antwort auf meinen Kommentar, würde ich einfach das Datum basierend auf der lokalen Serverzeit speichern und dann JavaScript's Date :: toLocaleString() verwenden, um es in ihre lokale Zeitzone zu konvertieren. Ich habe vor ein paar Jahren einen Artikel darüber geschrieben, den Sie unter here finden können.

Das JS des Artikels wurde in MooTools geschrieben, aber ich habe es seitdem mit jQuery neu geschrieben, also werde ich diesen Code zeigen.

Die wichtige Teile:

Wenn HTML-Rendering, verwenden Sie die Millisekunden seit der Epoche.

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

, die ein Verfahren in Ihrem Modell wie folgt definiert erfordert:

def created_at_epoch_ms 
    self.created_at.to_i * 1000 
end 

Die JS die Daten zu transformieren:

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

       date.setTime(this.firstChild.data); 

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

die Zeichenfolge konvertiert den Benutzer Ortszeit Dies sollte, und die Magie passiert in toLocaleString(). Der einzige Browser, von dem ich gehört habe, dass er dies nicht implementiert, ist Safari 2.0, was kein großes Problem darstellen sollte, da ich denke, dass die meisten Benutzer weiter gegangen sind.

Ich verwende diese Methode auf my site, und wenn Sie den Quellcode der Seite betrachten, können Sie sehen, was es tut.Der eigentliche Code, der an den Browser gesendet wird wie folgt aussieht:

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

, die in meinem Browser (Central Time) zu

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

Wenn sie aktiviert JS haben umgewandelt wird, wird es den Wert des nehmen Kommentiere den Knoten, transformiere ihn und ersetze die gesamte Zeichenfolge (einschließlich der UTC-Zeit) durch die lokale Zeit. Wenn JS deaktiviert ist, sehen sie nur die Zeit, die der Server sieht.