Rails: converta UTC DateTime para outro fuso horário

112

Em Ruby / Rails, como faço para converter um DateTime UTC para outro fuso horário?

Drew Johnson
fonte

Respostas:

206
time.in_time_zone(time_zone)

Exemplo:

zone = ActiveSupport::TimeZone.new("Central Time (US & Canada)")
Time.now.in_time_zone(zone)

ou apenas

Time.now.in_time_zone("Central Time (US & Canada)")

Você pode encontrar os nomes dos fusos horários do ActiveSupport fazendo:

ActiveSupport::TimeZone.all.map(&:name)
# or for just US
ActiveSupport::TimeZone.us_zones.map(&:name)
Mckeed
fonte
No irb, quando tento Time.now.in_time_zone ('CST'), obtenho o erro "método indefinido 'in_time_zone'". Existem classes Rails que eu preciso para fazer isso funcionar?
Drew Johnson
Qual versão do Rails você está usando? Funciona se você usar Time.zone.now.in_time_zone (...)?
mckeed
13
Para usar isso fora do Rails, require 'active_support/time'primeiro.
sunaku
3
Você pode listar todos os fusos horários executando rake time:zones:all. Veja também rake -D time. Defina o fuso horário padrão em config/application.rb.
user664833
1
@AdamEberlin No Rails você normalmente usa ActiveSupport :: TimeWithZone, não DateTime. Todo esse código funciona em objetos DateTime ruby ​​e também em objetos Time.
mckeed
6

se Time.zonefor o fuso horário desejado, você pode usar@date.to_time.to_datetime

> @date
=> Tue, 02 Sep 2014 23:59:59 +0000
> @date.class
=> DateTime
> @date.to_time
=> 2014-09-02 12:59:59 -1100
> @date.to_time.to_datetime
=> Tue, 02 Sep 2014 12:59:59 -1100 
vladCovaliov
fonte
Não funciona no Rails 5 `Time.zone # => Europe / Paris my_date # => Quarta, 29 de março de 2017 19:00:20 +0200 my_date.to_time # =>" 2017-03-29T17: 00: 20.000+ 00:00 "my_date.to_time.to_datetime # => Quarta, 29 de março de 2017 17:00:20 +0000`
Cyril Duchon-Doris
5

Em rubi puro, com apenas require 'date', use o new_offsetmétodo:

require 'date'

d=DateTime.parse('2000-01-01 12:00 +0200')
l=d.new_offset('-0700')
u=l.new_offset('UTC')
puts "#{u.strftime('%a %F %T %Z')} ❖ #{l.strftime('%a %F %T %Z')}"

Testado com ruby ​​2.3.7 que veio como padrão no Mac OS X 10.13.

Jbyler
fonte
3

Experimente objetos TimeWithZone do ActiveSupport manipulados com TimeZone. ActiveSupport também fornece o método in_time_zone para converter um horário UTC em um fuso horário especificado. A resposta de mckeed mostra o código.

Fred
fonte
Qual é a sintaxe para importar TimeWithZone para minha classe? Ou eu consigo por padrão com Rails?
Drew Johnson
1
Eu acredito que você entende por padrão. mckeed tem o código de que você precisa, mas você não o verá no irb. Você precisa executá-lo no Rails.
Fred
Você está certo - obrigado, Fred - ele vem com Rails por padrão. Eu estava me agarrando a qualquer coisa, tentando fazer funcionar no irb.
Drew Johnson
3

Apenas no caso, se você está lidando com o objeto ActiveRecord no Rails.

Pode ser uma boa ideia usar Time.use_zoneum fuso horário por solicitação que substitua o fuso horário padrão definido emconfig.time_zone

Mais detalhes eu explico em https://stackoverflow.com/a/25055692/542995

zdk
fonte
0

Estou usando o simple_form no Rails 4 e acabei de adicionar o campo de entrada como

<%= f.input :time_zone, :as => :time_zone %>

com a migração

class AddTimeZoneColumnToTextmessage < ActiveRecord::Migration
  def change
    add_column :textmessages, :time_zone, :string
  end
end
maudulus
fonte
1
Isso não responde à questão de como você converte objetos DateTime
zykadelic