Como alterar o fuso horário padrão para o Active Record no Rails?

140

No meu application.rbdeparei com o seguinte comentário

# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
 config.time_zone = 'Eastern Time (US & Canada)'

Como você pode ver acima, cheguei config.time_zoneao horário EST. No entanto, ainda quando os registros são criados no banco de dados, parece que eles datetimeestão sendo armazenados no formato UTC.

No comentário acima, eles dizem

... e faça a conversão automática do Active Record para esta zona ...

Como posso fazer isso e onde?

Além disso, eu vou implantar isso no heroku também e eu gostaria que a configuração continuasse

Onipresente
fonte
No MySQL, datetime é um tipo de fuso horário menor. Ou seja, pode estar em qualquer fuso horário que você quiser. Se você o tratar como UTC, tudo bem. Mas tome cuidado se alguém estiver olhando diretamente para o seu banco de dados e interpretá-lo de maneira diferente.
Vanuan

Respostas:

199

Decidi compilar esta resposta porque todas as outras parecem estar incompletas.

config.active_record.default_timezone determina se Time.local (se definido como: local) ou Time.utc (se definido como: utc) ao extrair datas e horas do banco de dados. O padrão é: utc. http://guides.rubyonrails.org/configuring.html


Se você deseja alterar o fuso horário do Rails , mas continuar com o Active Record salvo no banco de dados no UTC , use

# application.rb
config.time_zone = 'Eastern Time (US & Canada)'

Se você deseja alterar o fuso horário do Rails E ter os tempos de armazenamento do Active Record nesse fuso horário, use

# application.rb
config.time_zone = 'Eastern Time (US & Canada)'
config.active_record.default_timezone = :local

Aviso : você realmente deve pensar duas vezes, até três vezes, antes de salvar os tempos no banco de dados em um formato não UTC.

Nota
Não esqueça de reiniciar o servidor Rails após a modificação application.rb.


Lembre-se de que config.active_record.default_timezonepode levar apenas dois valores

  • : local (converte para o fuso horário definido em config.time_zone)
  • : utc (converte para UTC)

Veja como você pode encontrar todos os fusos horários disponíveis

rake time:zones:all
Mihai-Andrei Dinculescu
fonte
5
Esta parece ser a resposta mais completa / precisas - @Omnipresent
Aegix
2
Essa deve ser a resposta aceita. Está mais completo.
Enrique Moreno Tent
@ Mihai-AndreiDinculescu Você acha que é melhor armazenar os datetimevalores em UTC no banco de dados e apenas alterá-los no frontend como com moment.jsou o que você sugere para mostrar esses dados no fuso horário correto para qualquer usuário?
Alexventuraio 11/11
@AlexVentura Sim, as pessoas mais espertas do que eu concordaram há muito tempo, que armazenar datas no UTC é o melhor caminho a percorrer.
Mihai-Andrei Dinculescu 11/11
É, eu entendi. Mas o que você sugere implementar nas visualizações de trilhos para mostrar os valores corretos para qualquer usuário com fuso horário diferente?
Alexventuraio 11/11
187

adicionando o seguinte aos application.rbtrabalhos

 config.time_zone = 'Eastern Time (US & Canada)'
 config.active_record.default_timezone = :local # Or :utc
Onipresente
fonte
59
É trabalhar para mim com esta:config.time_zone = 'London' config.active_record.default_timezone = :local
Dean Perry
41
Você pode ver todos os fusos horários executando isto em rails c- #ActiveSupport::TimeZone.all.map(&:name)
Dean Perry
5
Muito obrigado! Eu estava lutando com isso também. Eu tenho um aplicativo PHP herdado herdado que interage com o mesmo banco de dados mysql e armazena todos os momentos como local; atualizá-lo para usar o UTC não era uma opção. O que eu anteriormente não havia conseguido nada: config.time_zone = 'Central Time (US & Canada)' config.active_record.default_timezone = 'Central Time (US & Canada)' mas defini-lo com o símbolo: local fez o truque.
precisa
8
As guias dos trilhos dizem que config.active_record.default_timezonesó deve ser definido como :localou :utc. Presumo que qualquer outra coisa teria resultados inesperados.
Kelvin
2
Você pode ver todos os fusos horários executando isso emrake time:zones:all
Orlando
34

Cheguei à mesma conclusão que Dean Perry depois de muita angústia. config.time_zone = 'Adelaide'e config.active_record.default_timezone = :localfoi a combinação vencedora. Aqui está o que eu encontrei durante o processo.

James Barona
fonte
5
Esta é a resposta certa, default_timezone aceita apenas: local ou: utc
Francesco Belladonna
20

No meu caso (Rails 5), acabei adicionando essas 2 linhas no meu app/config/environments/development.rb

config.time_zone = "Melbourne"
config.active_record.default_timezone = :local

É isso aí! E para garantir que Melbourne fosse lida corretamente, executei o comando no meu terminal:

bundle exec rake time:zones:all

e Melbourne estava listando no fuso horário em que estou!

Carole
fonte
E se eu quiser que cada usuário veja valores de data e hora em seu próprio fuso horário?
Alexventuraio 11/11
@AlexVentura quando você mostra valores de data e hora para seus usuários, converte-os em seus fusos horários. Fazendo os registros do banco de dados persistente é uma prática melhor
Waheed
10

Se você deseja definir o fuso horário como UTC globalmente, você pode fazer o seguinte no Rails 4:

# Inside config/application.rb
config.time_zone = "UTC"
config.active_record.default_timezone = :utc

Certifique-se de reiniciar seu aplicativo ou você não verá as alterações.

sergserg
fonte
3

Nos trilhos 4.2.2, vá para application.rbe use config.time_zone='city'(por exemplo: 'London' ou 'Bucharest' ou 'Amsterdam' e assim por diante).

Deve funcionar muito bem. Funcionou para mim.

Andrei Laslo
fonte
3

Eu tive que adicionar este bloco ao meu environment.rbarquivo e tudo estava bem :)

Rails.application.configure do
    config.time_zone = "Pacific Time (US & Canada)"
    config.active_record.default_timezone = :local
end
  • Adicionei antes da linhaRails.application.initialize!
Taylor A. Leach
fonte
1

para usuário chinês, basta adicionar duas linhas abaixo para você config/application.rb:

config.active_record.default_timezone = :local
config.time_zone = 'Beijing'
Siwei Shen 申思维
fonte
0

No Ruby on Rails 6.0.1, vá para config > locales > application.rb e adicione o seguinte:

require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module CrudRubyOnRails6
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.0

    config.active_record.default_timezone = :local
    config.time_zone = 'Lima'

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end

Você pode ver que estou configurando o fuso horário com 2 linhas:

config.active_record.default_timezone =: local
config.time_zone = 'Lima'

Espero que ajude aqueles que estão trabalhando com Ruby on Rails 6.0.1

Juan Castro Lurita
fonte
-2

Se você deseja definir a hora local, adicione o seguinte texto em application.rb

config.time_zone = 'Chennai'

# WARNING: This changes the way times are stored in the database (not recommended)
config.active_record.default_timezone = :local

Em seguida, reinicie o servidor

Anand
fonte
12
default_timezone aceita uma das duas opções ..: local ou: UTC .. ele não aceita um fuso horário específico, de modo que este não vai funcionar .. Você precisa definir default_timezone para: LOCAL
Urkle