2016-07-19 12 views
0

Ich arbeite mit einer Rails App, die ein Datum als String im Format "YYYY-MM-DD" bekommt und ich frage mich, was Die beste Methode, um es in ein TimeWithZone-Objekt zu konvertieren, das in einer bestimmten Zeitzone auf Mitternacht gesetzt ist und von einer Datenbank auch in Form eines Strings bereitgestellt wird.Der beste Weg, Mitternacht an einem bestimmten Tag in einer bestimmten Zeitzone in Rails zu bekommen

Grunde möchte ich dies:

"2016.06.01", "Amerika/New_York" => Mi, 1. Juni 2016 00.00.00 EDT -04: 00

" 2016-06-01 "," Europe/Berlin "=> Mi, 01 Jun 2016 00:00:00 CEST +02: 00

" 2016-01-01 "," Amerika/New_York "=> Fri, 01.01.2016 00:00:00 EST -05: 00

"2016-01-01", "Europa/Berlin" => Fr, 01 Jan 2016 00:00:00 CET +01: 00

Jetzt weiß ich, es ist definitiv nicht einfach Date.parse (x) .to_datetime.in_time_zone (y) .beginning_of_day da für die "Amerika/New_York" Beispiele, dass ergäbe „Tue, 31 Mai 2016 00:00:00 EDT -04: 00 "und" Do, 31 Dez 2015 00:00:00 EST -05: 00 ", also habe ich darüber nachgedacht, das zu korrigieren, indem ich einen Tag hinzufüge, wenn utc_offset negativ ist, so dass die Methode, die ich gebaut habe im Grunde sieht wie folgt aus:

def midnight_in_time_zone(date_string, time_zone_string) 
    time_with_zone = Date.parse(date_string). 
    to_datetime. 
    in_time_zone(time_zone_string). 
    beginning_of_day 

    time_with_zone += 1.day if time_with_zone.utc_offset < 0 

    time_with_zone 
end 

Dies funktioniert die Art und Weise, die ich will, aber es fühlt sich an wie ich das Rad in einer hacky Weise bin neu zu erfinden, da was ich versuche, zu tun scheint wie eine solche Grundfunktion, also frage ich mich, ob es eingebaute Methoden gibt, die ich nicht kenne, die ich verwenden könnte, um das einfacher zu machen, oder wenn irgendjemand von einer besseren Weise weiß, dies zu tun.

+0

Im Idealfall würde mit dem Sie arbeiten werden "DateTime" -Objekte zunächst, was bedeuten würde, dass Sie das Endergebnis einfacher erhalten könnten. Ich musste in der Vergangenheit einen ähnlichen Code schreiben und bin mir eines einfacheren Weges nicht bewusst. – Tass

+0

@Tass Gibt es eine Möglichkeit, ein neues DateTime-Objekt mit einer Zeitzonenverschiebung unter Verwendung des Standardnamens wie "America/New_York" zu erstellen? Ich weiß, dass die Offset-Nummer als String wie "-5" verwendet werden könnte, aber da sich diese mit der Sommerzeit für die meisten Zeitzonen in Nordamerika und Europa ändert, kann ich mir keinen guten Weg vorstellen, das ohne sie zu verwalten Es ist sogar noch mehr so, als würde man das Rad neu erfinden. Daher wäre es ideal, den Standardnamen zu verwenden und Rails den Offset bestimmen zu lassen. –

+0

Und da ich gerade von Daylight Savings gesprochen habe, habe ich festgestellt, dass meine "1 Tag" -Korrektur nicht funktioniert, wenn es auf einen Tag einer Sommerzeitumstellung in Zeitzonen hinter UTC fällt, da das Ergebnis entweder 23 Uhr oder 1 Uhr morgens ist die Richtung der Veränderung. –

Antwort

0

Sie können dies versuchen:

def midnight_in_time_zone(date_string, time_zone_string) 
    date_string.in_time_zone(time_zone_string) 
end 

diese Zeile erhöht 1 Tag automatisch, wenn time_with_zone.utc_offset der Wert kleiner als 0

Beispiel Ergebnis:

#Your code puts 
time_with_zone = Date.parse("2016-01-01").to_datetime.in_time_zone("America/New_York").beginning_of_day 
#=> Thu, 31 Dec 2015 00:00:00 EST -05:00 
#If you try this 
date_string.in_time_zone(time_zone_string) 
#=> Fri, 01 Jan 2016 00:00:00 EST -05:00 
+0

Thx, aber es sollte beachtet werden, dass Ihre Lösung in Rails 4 funktioniert. Einige unserer Server laufen immer noch auf Rails 3, aber ich denke, dass ich sie massieren kann, bis sie aktualisiert werden. –