Ich habe eine Rails-Time-basierte Abfrage, die einige seltsame Zeitzone-sensitive Verhalten hat, obwohl, soweit ich weiß, ich UTC verwende. Auf den Punkt gebracht, geben diese Abfragen unterschiedliche Antworten:Warum unterscheidet sich diese Rails-Abfrage je nach Zeitzone?
>> Model.find(:all,:conditions=>['created_at<=?',(Time.now-1.hours).gmtime]).length
=> 279
>> Model.find(:all,:conditions=>['created_at<=?',(Time.now-1.hours)]).length
=> 280
Wo der DB tut eigentlich ein Modell in der letzten Stunde erstellt werden, enthalten, und die Gesamtzahl der Modelle ist 280. So wird nur die erste Abfrage ist richtig.
jedoch in environment.rb ich habe:
config.time_zone = 'UTC'
Die System-Zeitzone (wie durch 'Datum' berichtete) ist BST (die GMT + 1) - so irgendwie windet sich dies bis behandelt zu werden als UTC und Brechen von Abfragen.
Dies verursacht mir alle Arten von Problemen, wie ich die Abfrage zu verschiedenen Zeiten zu einer Aktion (die dann mit Time.parse() konvertiert werden muss parametrieren), und obwohl ich in UTC-Zeiten sende ' um eine Stunde aus "DST Ausgabe Getreide viel. Selbst die Verwendung von '.gmtime()' scheint es nicht immer zu beheben.
Offensichtlich wird der Unterschied irgendwie durch eine implizite Konvertierung verursacht, die irgendwo dazu führt, dass BST falsch als UTC behandelt wird, aber warum? Speichern Schienen nicht die Zeitstempel in UTC? Ist die Time-Class-Zeitzone nicht bekannt? Ich benutze Rails 2.2.2
Also was ist hier los - und was ist die sichere Art und Weise um es zu programmieren?
bearbeiten, einige zusätzliche Informationen zu zeigen, was die DB und Time-Klasse tun:
>> Model.find(:last).created_at
=> Tue, 11 Aug 2009 20:31:07 UTC +00:00
>> Time.now
=> Tue Aug 11 22:00:18 +0100 2009
>> Time.now.gmtime
=> Tue Aug 11 21:00:22 UTC 2009
Interessante ... Time.utc für Time.gmtime ein Synonym ist? Auch bekomme ich >> Time.zone => #>. Ich denke, das Problem ist, dass meine Art zu denken "Di Aug 11 22:00:18 +0100 2009" und "Di Aug 11 21:00:22 UTC 2009" auf die gleiche logische Zeit bezogen sind. Ich nehme an, dass rails/ruby den Offset beim Erstellen des SQL ignoriert. –
frankodwyer
Ich glaube, Time # utc ist nur ein Alias für Time # gmtime.Außerdem wird der Zeitzonen-Offset ignoriert, wenn eine normale Zeit behandelt wird (Time.now), aber bei der Verwendung von Time.zone.now berücksichtigt. Also am besten immer Time.zone benutzen, dann solltest du nicht "utc" aufrufen müssen. – ryanb
danke, das hilft sehr. Es ist für mich nicht intuitiv, dass es so funktioniert, aber zumindest verstehe ich, was jetzt passiert. Ich habe den Code entsprechend geändert und es scheint das Problem geklärt zu haben. Eine andere Sache, die meinen Code warf war, dass 1.Jahre nicht durch 1.Woche teilbar ist, wie ich es erwartet hatte ... Ich machte eine Schleife und bekam deswegen einen nicht verwandten, aber ähnlichen Fehler. – frankodwyer