Tenho um cadastro foo
no banco de dados que possui :start_time
e :timezone
atributos.
O :start_time
é um horário em UTC - 2001-01-01 14:20:00
, por exemplo. O :timezone
é uma string - America/New_York
, por exemplo.
Quero criar um novo objeto Time com o valor de, :start_time
mas cujo fuso horário é especificado por :timezone
. Não quero carregar o :start_time
e depois converter para :timezone
, porque o Rails será inteligente e atualizará a hora do UTC para ser consistente com esse fuso horário.
Atualmente,
t = foo.start_time
=> 2000-01-01 14:20:00 UTC
t.zone
=> "UTC"
t.in_time_zone("America/New_York")
=> Sat, 01 Jan 2000 09:20:00 EST -05:00
Em vez disso, quero ver
=> Sat, 01 Jan 2000 14:20:00 EST -05:00
ie. Eu quero fazer:
t
=> 2000-01-01 14:20:00 UTC
t.zone = "America/New_York"
=> "America/New_York"
t
=> 2000-01-01 14:20:00 EST
Respostas:
Parece que você quer algo na linha de
Isso diz converter a hora local (usando a zona) para utc. Se você
Time.zone
definiu, então você pode, é claro,Isso não usará o fuso horário anexado a t - pressupõe que seja local em relação ao fuso horário do qual você está convertendo.
Um caso extremo a ser evitado aqui são as transições de horário de verão: o horário local especificado pode não existir ou ser ambíguo.
fonte
Time.use_zone(self.timezone) { Time.zone.local_to_utc(t) }.localtime
Acabei de enfrentar o mesmo problema e aqui está o que vou fazer:
Aqui está a documentação sobre asctime
fonte
asctime
é que ele descarta quaisquer valores de subsegundos (que minha resposta mantém).Se você está usando Rails, aqui está outro método na linha da resposta de Eric Walsh:
fonte
.in_time_zone
ao final.Time.zone.now
por algo mais próximo do momento que você deseja alterar funcione?Você precisa adicionar a diferença de tempo ao seu tempo depois de convertê-lo.
A maneira mais fácil de fazer isso é:
Não sei por que você faria isso, embora seja provavelmente melhor trabalhar com os tempos da maneira como eles são construídos. Acho que algumas informações básicas sobre por que você precisa mudar o horário e os fusos horários seriam úteis.
fonte
Time.in_time_zone
exigindo as partes corretas de active_support:require 'active_support/core_ext/time'
Na verdade, acho que você precisa subtrair o deslocamento depois de convertê-lo, como em:
fonte
Depende de onde você vai usar esse tempo.
Quando seu tempo é um atributo
Se o tempo for usado como um atributo, você pode usar a mesma gem date_time_attribute :
Quando você define uma variável separada
Use a mesma gem date_time_attribute :
fonte
Uma pequena função rápida que criei para resolver o trabalho. Se alguém tiver uma maneira mais eficiente de fazer isso por favor poste!
fonte
A premissa do OP está incorreta: “Não quero carregar o: start_time e depois converter para: timezone, porque o Rails será inteligente e atualizará o horário do UTC para ser consistente com aquele fuso horário.” Isso não é necessariamente verdade, conforme demonstrado pela resposta fornecida aqui.
fonte
t.zone
antes,t.change
o que você vê? E quando você corrert.zone
atrást.change
? E para quais parâmetros você está passandot.change
exatamente?Eu criei alguns métodos auxiliares, um dos quais apenas faz a mesma coisa que o autor original do post em Ruby / Rails - Alterar o fuso horário de um tempo, sem alterar o valor .
Além disso, documentei algumas peculiaridades que observei e também esses helpers contêm métodos para ignorar completamente a economia automática de luz do dia aplicável durante as conversões de tempo, que não estão disponíveis prontamente no framework Rails:
Exemplos que podem ser tentados no console Rails ou em um script Ruby após envolver os métodos acima em uma classe ou módulo:
Espero que isto ajude.
fonte
Aqui está outra versão que funcionou melhor para mim do que as respostas atuais:
Ele transporta nanossegundos usando "% N". Se você deseja outra precisão, consulte esta referência strftime .
fonte
Passei um tempo significativo lutando com TimeZones também, e depois de mexer no Ruby 1.9.3 percebi que você não precisa converter para um símbolo de fuso horário nomeado antes de converter:
O que isso implica é que você pode se concentrar em obter a configuração de tempo apropriada primeiro na região que deseja, da maneira como você pensaria sobre isso (pelo menos na minha cabeça eu particiono desta forma) e, em seguida, converter no final para a zona com o qual deseja verificar sua lógica de negócios.
Isso também funciona para Ruby 2.3.1.
fonte