Konvertieren Sie UTC in Ortszeit in Rails 3

95

Ich habe Probleme beim Konvertieren einer UTC Timeoder TimeWithZoneder Ortszeit in Rails 3.

Say momentist eine TimeVariable in UTC (z moment = Time.now.utc. B. ). Wie konvertiere ich momentin meine Zeitzone und kümmere mich um die Sommerzeit (dh mit EST / EDT)?

Genauer gesagt, ich möchte "Montag, 14. März, 9 Uhr" ausdrucken, wenn die Zeit heute Morgen 9 Uhr EDT entspricht, und "Montag, 7. März, 9 Uhr", wenn die Zeit letzten Montag 9 Uhr EST war.

Hoffentlich gibt es einen anderen Weg?

Bearbeiten : Ich dachte zuerst, dass "EDT" eine erkannte Zeitzone sein sollte, aber "EDT" ist keine tatsächliche Zeitzone, eher wie der Zustand einer Zeitzone. Zum Beispiel würde es keinen Sinn machen, danach zu fragen Time.utc(2011,1,1).in_time_zone("EDT"). Es ist ein wenig verwirrend, als „EST“ ist eine aktuelle Zeitzone, in wenigen Orten verwendet , das Tageslicht nicht auf Sommerzeit verwenden und sind (UTC-5) einjährig.

Marc-André Lafortune
quelle

Antworten:

113

Rails hat seine eigenen Namen. Sehen Sie sie mit:

rake time:zones:us

Sie können auch rake time:zones:allfür alle Zeitzonen ausgeführt werden. So zeigen Sie weitere zonenbezogene Rechenaufgaben an:rake -D time

Um auf EST umzustellen, wird die Sommerzeit automatisch berücksichtigt:

Time.now.in_time_zone("Eastern Time (US & Canada)")
Zabba
quelle
21
Wie können Sie die Zeitzone automatisch für den Benutzer verwenden, der auf die Web-App zugreift?
Dmonopol
Ich habe nur Javascript gefunden und es dann an den Server zurückgegeben. (new Date()).getTimeZoneOffset(). Aber es ist ziemlich inkonsistent, also scheint dieser Typ sein eigenes geschrieben zu haben: onlineaspect.com/2007/06/08/…
Duke
2
Fügen Sie die Zeitzone automatisch zu allen ActiveRecord-Datenzeiten hinzu - config.time_zone = 'Eastern Time (USA & Kanada)' - in config / application.rb
idrinkpabst
Update: Besitzer der verknüpften JS-Lösung verweist auf neuere Lösung: pellepim.bitbucket.org/jstz
Miles
@dmonopoly Sie können die Zeitzone in der Anwendungskonfiguration festlegen config.time_zone = 'Wellington'und dann Time.current verwenden (was time.now entspricht, aber die von Ihnen festgelegte Zeitzone verwendet)
Sean
114

Time#localtime gibt Ihnen die Zeit in der aktuellen Zeitzone des Computers an, auf dem der Code ausgeführt wird:

> moment = Time.now.utc
  => 2011-03-14 15:15:58 UTC 
> moment.localtime
  => 2011-03-14 08:15:58 -0700 

Update: Wenn Sie zu bestimmten Zeitzonen anstatt zu Ihrer eigenen Zeitzone konvertieren möchten, sind Sie auf dem richtigen Weg. Anstatt sich über EST oder EDT Gedanken zu machen, gehen Sie einfach in die allgemeine östliche Zeitzone - sie wird anhand des Tages wissen, ob es sich um EDT oder EST handelt:

> Time.now.utc.in_time_zone("Eastern Time (US & Canada)")
  => Mon, 14 Mar 2011 11:21:05 EDT -04:00 
> (Time.now.utc + 10.months).in_time_zone("Eastern Time (US & Canada)")
  => Sat, 14 Jan 2012 10:21:18 EST -05:00 
Dylan Markow
quelle
Das ist ein Anfang. Wie kann ich die aktuelle Zeitzone einstellen (da ich nicht einmal sicher bin, wo die App gehostet wird, befindet sich der Server möglicherweise in einer anderen Zeitzone als der, die verwendet werden soll).
Marc-André Lafortune
6
Die "localtime" -Methode ist cool, aber die Zeitzone des Computers, auf dem der Code ausgeführt wird, ist nicht so hilfreich wie die Zeitzone des Benutzers, der auf die Web-App zugreift. (Wie hier erwähnt: stackoverflow.com/questions/6003491/rails-3-user-timezones/… ) Wie können Sie die Zeitzone für den Benutzer ermitteln, der auf die Web-App zugreift?
Dmonopol
@daze Ich kann mir vorstellen, dass Sie eine Option für Ihre Benutzer einrichten können, um ihre Zeitzonen auszuwählen und dann die in_time_zoneMethode mit ihrer Zeitzone zu verwenden.
Dylan Markow
1
Danke, die Ortszeitmethode ist genau das, was ich brauchte.
Bob
Time.now.localtimefunktioniert in einer normalen irb-Sitzung, aber wenn ich versuche, sie auf einem Computer auszuführen, der sich in der UTC-Zeitzone befindet, funktioniert sie nicht.
Ava
15

Es ist einfach, es mithilfe der lokalen Systemzone zu konfigurieren. Fügen Sie dies einfach in Ihrer application.rb hinzu

config.time_zone = Time.now.zone

Dann sollten Schienen Ihnen Zeitstempel in Ihrer Ortszeit anzeigen, oder Sie können so etwas wie diese Anweisung verwenden, um die Ortszeit zu erhalten

Post.created_at.localtime
jacr1614
quelle
15

Es gibt tatsächlich einen netten Edelstein, der local_timevon basecamp aufgerufen wird, um all das nur auf Kundenseite zu tun, glaube ich:

https://github.com/basecamp/local_time

Mahatmanich
quelle
Das funktioniert am besten. Wir kennen die bereits gespeicherte Zeit, die Art und Weise, sie dem Benutzer im Format anzuzeigen, erfolgt meiner Meinung nach am besten auf der Client-Seite, und das tut es auch.
Neeraj Shukla
1

Ich weiß nicht warum, aber in meinem Fall funktioniert es nicht wie zuvor vorgeschlagen. Aber es funktioniert so:

Time.now.change(offset: "-3000")

Natürlich müssen Sie den offsetWert auf Ihren ändern .

Seybo Glaux
quelle
0

Wenn Sie dies tatsächlich tun, nur weil Sie die Zeitzone des Benutzers abrufen möchten, müssen Sie lediglich Ihre Zeitzone in Ihnen ändern config/applications.rb.

So was:

Rails speichert Ihren Zeitrekord standardmäßig in UTC, auch wenn Sie die aktuelle Zeitzone angeben.

config.time_zone = "Singapore"

Das ist also alles, was Sie tun müssen und Sie können loslegen.

Therealadrain
quelle