Tengo una consulta basada en el tiempo de los raíles que tiene algún comportamiento extraño de zona horaria, aunque, por lo que sé, estoy usando UTC. En pocas palabras, estas consultas dan diferentes respuestas:¿Por qué esta consulta de rieles se comporta de manera diferente según la zona horaria?
>> 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
Cuando el DB contiene realmente un modelo creado en la última hora, y el número total de modelos es 280. Así que sólo la primera consulta es correcta.
Sin embargo, en environment.rb tengo:
config.time_zone = 'UTC'
La zona horaria del sistema (según lo informado por 'fecha') es BST (que es GMT + 1) - por lo que de alguna manera esto termina siendo tratados como UTC y consultas interrumpidas.
Esto me está causando todo tipo de problemas, ya que necesito parametrizar la consulta que pasa en momentos diferentes a una acción (que luego se convierten usando Time.parse()), y aunque envío horas UTC, esto ' fuera por una hora, el tema de DST cosecha mucho. Incluso el uso de '.gmtime()' no siempre parece arreglarlo.
Obviamente, la diferencia está causada de alguna manera por una conversión implícita en algún lugar que da lugar a que BST se trate incorrectamente como UTC, pero ¿por qué? ¿Los rieles no almacenan las marcas de tiempo en UTC? ¿No es consciente de la zona horaria de la clase Time? Estoy usando Rails 2.2.2
Entonces, ¿qué está pasando aquí, y cuál es la forma más segura de programarlo?
edición, algo de información adicional para mostrar lo que el PP y el horario de clases están haciendo:
>> 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
... Interesante es sinónimo de Time.utc Time.gmtime? También obtengo >> Time.zone => #>. Creo que el problema es que, a mi modo de pensar, "Tue Aug 11 22:00:18 +0100 2009" y "Mar Aug 11 21:00:22 UTC 2009" se refieren a la misma hora lógica. Supongo que rails/ruby simplemente está ignorando el desplazamiento al construir el SQL. –
frankodwyer
Creo que Time # utc es solo un alias de Time # gmtime.Además, el desplazamiento de la zona horaria se ignora cuando se trata de un tiempo normal (Time.now) pero se tiene en cuenta cuando se utiliza Time.zone.now. Lo mejor es usar siempre Time.zone, entonces no debería tener que llamar "utc" en él. – ryanb
gracias, eso ayuda mucho. no es intuitivo para mí que funcione de esa manera, pero al menos entiendo lo que está sucediendo ahora. Cambié el código en consecuencia y parece haber aclarado el problema. Otra cosa que arrojaba mi código era que 1.years no es divisible de manera uniforme por 1. semanas como esperaba ... Estaba haciendo un ciclo y obteniendo un error no relacionado pero similar debido a eso. – frankodwyer