J'ai une requête basée sur le temps de rails qui a un comportement bizarre sensible au fuseau horaire, même si pour autant que je sais que j'utilise UTC. En un mot, ces requêtes donnent des réponses différentes:Pourquoi cette requête de rails se comporte-t-elle différemment selon le fuseau horaire?
>> 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
Lorsque le DB contient en fait un modèle créé dans la dernière heure, et le nombre total de modèles est 280. Ainsi, seule la première requête est correcte.
Cependant, je environment.rb:
config.time_zone = 'UTC'
Le temps du système zone (tel que rapporté par 'date') est BST (qui est GMT + 1) - donc en quelque sorte ce serpente jusqu'à se traiter comme UTC et briser les requêtes. Cela me pose toutes sortes de problèmes car j'ai besoin de paramétrer la requête passant à différents moments d'une action (qui est ensuite convertie en utilisant Time.parse()), et même si j'envoie des temps UTC, ceci ' au large d'une heure, le problème de l'heure d'été est très important. Même en utilisant '.gmtime()' ne semble pas toujours le réparer.
Évidemment, la différence est causée d'une manière ou d'une autre par une conversion implicite quelque part, ce qui fait que la BST est mal traitée comme UTC, mais pourquoi? Les rails ne stockent-ils pas les horodatages en UTC? Le fuseau horaire Time Class n'est-il pas au courant? J'utilise Rails 2.2.2
Alors, que se passe-t-il ici - et quel est le moyen sûr de programmer autour d'elle?
modifier, quelques informations supplémentaires pour montrer ce que la DB et la classe du temps font:
>> 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
Intéressant ... est Time.utc synonyme de Time.gmtime? J'ai aussi >> Time.zone => #>. Je pense que le problème est que selon ma façon de penser "Tue Aug 11 22:00:18 +0100 2009" et "Tue Aug 11 21:00:22 UTC 2009" se réfèrent à la même heure logique. Je suppose que rails/ruby ignore simplement le décalage lors de la construction du SQL. –
frankodwyer
Je crois que Time # utc n'est qu'un alias de Time # gmtime.De même, le décalage de fuseau horaire est ignoré lors de l'utilisation d'une heure normale (Time.now) mais pris en compte lors de l'utilisation de Time.zone.now. Donc, mieux vaut toujours utiliser Time.zone alors vous ne devriez pas avoir à appeler "utc" dessus. – ryanb
merci, cela aide beaucoup. il est inintéressant pour moi que cela fonctionne de cette façon mais au moins je comprends ce qui se passe maintenant. J'ai changé le code en conséquence et il semble avoir résolu le problème. Une autre chose qui jetait mon code était que 1.years n'est pas divisible par 1.weeks comme je m'attendais à ce que ce soit ... Je faisais une boucle et obtenais une erreur non liée mais semblable à cause de cela. – frankodwyer