¿Cómo cambiar la zona horaria predeterminada para Active Record en Rails?

140

En mi application.rbme encontré con el siguiente comentario

# 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 puede ver desde arriba, he llegado config.time_zoneal tiempo EST. Sin embargo, aún cuando se crean registros en la base de datos, parece que datetimese está almacenando en formato UTC.

En el comentario anterior, dicen

... y hacer que Active Record se convierta automáticamente a esta zona ...

¿Cómo puedo hacer eso y dónde?

Además, también desplegaré esto en heroku y me gustaría que la configuración se transfiera

Omnipresente
fuente
En MySQL datetime es un tipo sin zona horaria. Es decir, podría estar en cualquier zona horaria que desee. Si lo tratas como UTC, está bien. Pero tenga cuidado si alguien está buscando en su base de datos directamente e interpretarlo de manera diferente.
Vanuan

Respuestas:

199

He decidido compilar esta respuesta porque todos los demás parecen estar incompletos.

config.active_record.default_timezone determina si se debe usar Time.local (si se establece en: local) o Time.utc (si se establece en: utc) al extraer fechas y horas de la base de datos. El valor predeterminado es: utc. http://guides.rubyonrails.org/configuring.html


Si desea cambiar la zona horaria de Rails , pero continúa guardando Active Record en la base de datos en UTC , use

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

Si desea cambiar la zona horaria de Rails Y tener tiempos de almacenamiento de Active Record en esta zona horaria, use

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

Advertencia : realmente debería pensarlo dos veces, incluso tres veces, antes de ahorrar tiempo en la base de datos en un formato que no sea UTC.

Nota
No olvide reiniciar su servidor Rails después de modificarlo application.rb.


Recuerde que config.active_record.default_timezonesolo puede tomar dos valores

  • : local (se convierte a la zona horaria definida en config.time_zone)
  • : utc (se convierte a UTC)

Así es como puede encontrar todas las zonas horarias disponibles

rake time:zones:all
Mihai-Andrei Dinculescu
fuente
55
Esta parece ser la respuesta más completa / precisa - @Omnipresent
Aegix
2
Esta debería ser la respuesta aceptada. Es más completo
Tienda Enrique Moreno
@ Mihai-AndreiDinculescu ¿Cree que es mejor almacenar los datetimevalores en UTC en la base de datos y luego simplemente cambiarlos en la interfaz como con moment.jso qué sugiere para mostrar estos datos en la zona horaria correcta para cualquier usuario?
alexventuraio
@AlexVentura Sí, las personas más inteligentes que yo acordaron hace mucho tiempo que almacenar las fechas en UTC es la mejor manera de hacerlo.
Mihai-Andrei Dinculescu
Si, lo tengo. Pero, ¿qué sugiere implementar en las vistas de rieles para mostrar los valores correctos para cualquier usuario con una zona horaria diferente?
alexventuraio
187

agregando seguidores a las application.rbobras

 config.time_zone = 'Eastern Time (US & Canada)'
 config.active_record.default_timezone = :local # Or :utc
Omnipresente
fuente
59
Me está funcionando con esto:config.time_zone = 'London' config.active_record.default_timezone = :local
Dean Perry
41
Puede ver todas las zonas horarias ejecutando esto en rails c-ActiveSupport::TimeZone.all.map(&:name)
Dean Perry
55
¡Muchas gracias! Había estado luchando con esto también. Tengo una aplicación PHP heredada heredada que interactúa con la misma base de datos mysql y almacena todo el tiempo como local; actualizarlo para usar UTC no era una opción. Lo que anteriormente no había logrado nada, config.time_zone = 'Central Time (US & Canada)' config.active_record.default_timezone = 'Central Time (US & Canada)' pero establecerlo en: símbolo local hizo el truco.
Matt Hucke
8
Las guías de rieles dicen que config.active_record.default_timezonesolo debe establecerse en :localo :utc. Supongo que cualquier otra cosa tendría resultados inesperados.
Kelvin
2
Puede ver todas las zonas horarias ejecutando esto enrake time:zones:all
Orlando
34

Llegué a la misma conclusión que Dean Perry después de mucha angustia. config.time_zone = 'Adelaide'y config.active_record.default_timezone = :localfue la combinación ganadora. Esto es lo que encontré durante el proceso.

James Barona
fuente
55
Esta es la respuesta correcta, default_timezone solo acepta: local o: utc
Francesco Belladonna
20

En mi caso (Rails 5), terminé agregando estas 2 líneas en mi app/config/environments/development.rb

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

¡Eso es! Y para asegurarme de que Melbourne se leyó correctamente, ejecuté el comando en mi terminal:

bundle exec rake time:zones:all

y Melbourne estaba en la zona horaria en la que estoy.

Carole
fuente
¿Qué sucede si quiero que cada usuario vea los valores de fecha y hora en su propia zona horaria?
alexventuraio
@AlexVentura cuando muestre valores de fecha y hora a sus usuarios, conviértalos a sus zonas horarias. Hacer que los registros de la base de datos sean persistentes es una mejor práctica
Waheed
10

Si desea establecer la zona horaria en UTC globalmente, puede hacer lo siguiente en Rails 4:

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

Asegúrese de reiniciar su aplicación o no verá los cambios.

sergserg
fuente
3

En los carriles 4.2.2, vaya application.rby use config.time_zone='city'(por ejemplo: 'Londres' o 'Bucarest' o 'Amsterdam' y así sucesivamente).

debería funcionar bien. Funcionó para mi.

Andrei Laslo
fuente
3

Tuve que agregar este bloque a mi environment.rbarchivo y todo estuvo bien :)

Rails.application.configure do
    config.time_zone = "Pacific Time (US & Canada)"
    config.active_record.default_timezone = :local
end
  • Lo agregué antes de la líneaRails.application.initialize!
Taylor A. Leach
fuente
1

para usuarios chinos, solo agregue dos líneas a continuación config/application.rb:

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

En Ruby on Rails 6.0.1, vaya a config > locales > application.rb y agrega lo siguiente:

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

Puede ver que estoy configurando la zona horaria con 2 líneas:

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

Espero que ayude a quienes trabajan con Ruby on Rails 6.0.1

Juan Castro Lurita
fuente
-2

Si desea establecer la hora local, agregue el siguiente texto en 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

Luego reinicie su servidor

Anand
fuente
12
default_timezone acepta una de dos opciones ...: local o: utc ... no acepta una zona horaria específica, por lo que esto no funcionará ... debe establecer default_timezone en: local
Urkle