Comment changer le fuseau horaire par défaut pour Active Record in Rails?

140

Dans mon application.rbje suis tombé sur le commentaire suivant

# 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)'

Comme vous le voyez ci-dessus, je suis config.time_zonearrivé à l'heure EST. Cependant, toujours lorsque les enregistrements sont créés dans la base de données, il semble datetimeêtre stocké au format UTC.

Dans le commentaire ci-dessus, ils disent

... et effectuez une conversion automatique de l'enregistrement actif vers cette zone ...

Comment puis-je faire ça et où?

De plus, je déploierai également ceci sur heroku et j'aimerais que le paramètre soit reporté

Omniprésent
la source
Dans MySQL, datetime est un type sans fuseau horaire. C'est-à-dire qu'il pourrait être dans n'importe quel fuseau horaire que vous voulez. Si vous le traitez comme UTC, c'est bien. Mais méfiez-vous si quelqu'un regarde directement votre base de données et l'interprète différemment.
Vanuan

Réponses:

199

J'ai décidé de compiler cette réponse car toutes les autres semblent incomplètes.

config.active_record.default_timezone détermine s'il faut utiliser Time.local (s'il est défini sur: local) ou Time.utc (s'il est défini sur: utc) lors de l'extraction des dates et heures de la base de données. La valeur par défaut est: utc. http://guides.rubyonrails.org/configuring.html


Si vous voulez changer le fuseau horaire de Rails , mais que vous continuez à enregistrer Active Record dans la base de données en UTC , utilisez

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

Si vous souhaitez modifier le fuseau horaire de Rails ET avoir des heures d' enregistrement Active Record dans ce fuseau horaire, utilisez

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

Attention : vous devriez vraiment réfléchir à deux fois, voire trois fois, avant de sauvegarder les temps dans la base de données dans un format non UTC.

Remarque
N'oubliez pas de redémarrer votre serveur Rails après la modification application.rb.


Souvenez-vous que cela config.active_record.default_timezonene peut prendre que deux valeurs

  • : local (convertit au fuseau horaire défini dans config.time_zone)
  • : utc (convertit en UTC)

Voici comment trouver tous les fuseaux horaires disponibles

rake time:zones:all
Mihai-Andrei Dinculescu
la source
5
Cela semble être la réponse la plus complète / précise - @Omnipresent
Aegix
2
Cela devrait être la réponse acceptée. C'est plus complet.
Enrique Moreno Tent
@ Mihai-AndreiDinculescu Pensez-vous qu'il est préférable de stocker les datetimevaleurs en UTC dans la base de données, puis de les modifier simplement dans le frontend comme avec moment.jsou que suggérez-vous pour afficher ces données dans le fuseau horaire correct pour n'importe quel utilisateur?
alexventuraio
@AlexVentura Oui, des gens plus intelligents que moi ont convenu il y a longtemps que stocker les dates en UTC était la meilleure façon de procéder.
Mihai-Andrei Dinculescu
Oui, j'ai compris. Mais que suggérez-vous d'implémenter dans les vues de rails pour afficher les valeurs correctes pour tout utilisateur avec un fuseau horaire différent?
alexventuraio
187

ajout de suite aux application.rbœuvres

 config.time_zone = 'Eastern Time (US & Canada)'
 config.active_record.default_timezone = :local # Or :utc
Omniprésent
la source
59
Cela fonctionne pour moi avec ceci:config.time_zone = 'London' config.active_record.default_timezone = :local
Dean Perry
41
Vous pouvez voir tous les fuseaux horaires en exécutant ceci dans rails c-ActiveSupport::TimeZone.all.map(&:name)
Dean Perry
5
Merci beaucoup! J'avais aussi du mal avec ça. J'ai une ancienne application PHP héritée qui interagit avec la même base de données mysql et stocke à tout moment en local; le mettre à jour pour utiliser UTC n'était pas une option. Ce que je n'avais auparavant rien accompli: config.time_zone = 'Central Time (US & Canada)' config.active_record.default_timezone = 'Central Time (US & Canada)' mais le définir sur le symbole: local a fait l'affaire.
Matt Hucke
8
Les guides de rails indiquent que cela config.active_record.default_timezonene devrait être réglé que sur :localou :utc. Je suppose que toute autre chose aurait des résultats inattendus.
Kelvin
2
Vous pouvez voir tous les fuseaux horaires en exécutant ceci dansrake time:zones:all
Orlando
34

J'en suis venu à la même conclusion que Dean Perry après beaucoup d'angoisse. config.time_zone = 'Adelaide'et config.active_record.default_timezone = :localc'était la combinaison gagnante. Voici ce que j'ai trouvé au cours du processus.

James Barona
la source
5
C'est la bonne réponse, default_timezone accepte uniquement: local ou: utc
Francesco Belladonna
20

Dans mon cas (Rails 5), j'ai fini par ajouter ces 2 lignes dans mon app/config/environments/development.rb

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

C'est tout! Et pour m'assurer que Melbourne a été lu correctement, j'ai exécuté la commande dans mon terminal:

bundle exec rake time:zones:all

et Melbourne listait dans le fuseau horaire dans lequel je suis!

Carole
la source
Que faire si je souhaite que chaque utilisateur voie les valeurs date-heure dans son propre fuseau horaire?
alexventuraio
@AlexVentura lorsque vous affichez des valeurs date-heure à vos utilisateurs, convertissez-les dans leurs fuseaux horaires. Il est préférable de rendre les enregistrements de la base de données persistants
Waheed
10

Si vous souhaitez définir globalement le fuseau horaire sur UTC, vous pouvez effectuer les opérations suivantes dans Rails 4:

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

Assurez-vous de redémarrer votre application ou vous ne verrez pas les modifications.

sergserg
la source
3

Sur les rails 4.2.2, allez à application.rbet utilisez config.time_zone='city'(par exemple: «Londres» ou «Bucarest» ou «Amsterdam» et ainsi de suite).

Il devrait fonctionner parfaitement. Cela a fonctionné pour moi.

Andrei Laslo
la source
3

J'ai dû ajouter ce bloc à mon environment.rbdossier et tout allait bien :)

Rails.application.configure do
    config.time_zone = "Pacific Time (US & Canada)"
    config.active_record.default_timezone = :local
end
  • Je l'ai ajouté avant la ligneRails.application.initialize!
Taylor A. Leach
la source
1

pour les utilisateurs chinois, ajoutez simplement deux lignes ci-dessous config/application.rb:

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

Dans Ruby on Rails 6.0.1, allez dans 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

Vous pouvez voir que je configure le fuseau horaire avec 2 lignes:

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

J'espère que cela aidera ceux qui travaillent avec Ruby on Rails 6.0.1

Juan Castro Lurita
la source
-2

Si vous souhaitez que l'heure locale soit définie, ajoutez le texte suivant dans 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

Puis redémarrez votre serveur

Anand
la source
12
default_timezone accepte l'une des deux options ..: local ou: utc .. il n'accepte pas un fuseau horaire spécifique, donc cela ne fonctionnera pas .. vous devez définir default_timezone sur: local
Urkle