2009-09-06 9 views
90

Mes created_at horodatages sont stockés dans UTC:Convertir temps d'un fuseau horaire à l'autre dans Rails

>> Annotation.last.created_at 
=> Sat, 29 Aug 2009 23:30:09 UTC +00:00 

Comment puis-je convertir un d'eux « heure de l'Est (Etats-Unis & Canada) » (compte tenu de la lumière du jour des économies)? Quelque chose comme:

Annotation.last.created_at.in_eastern_time 

Répondre

159

Utilisez la méthode in_time_zone de la classe DateTime

Loading development environment (Rails 2.3.2) 
>> now = DateTime.now.utc 
=> Sun, 06 Sep 2009 22:27:45 +0000 
>> now.in_time_zone('Eastern Time (US & Canada)') 
=> Sun, 06 Sep 2009 18:27:45 EDT -04:00 
>> quit 

Donc, pour votre exemple particulier

Annotation.last.created_at.in_time_zone('Eastern Time (US & Canada)') 
+6

ou vous pouvez simplement utiliser heure ident 'now.in_time_zone (3)' ' – fl00r

+7

created_at.in_time_zone ("EST") 'est plus court – Orlando

+40

" EST "=" Heure normale de l'est ", il sera donc erroné pendant l'heure d'été. "Eastern Time (États-Unis et Canada)" détermine si c'est l'heure d'été ou pas pour vous. – jhiro009

2

Définir votre fuseau horaire à heure de l'Est.

Vous pouvez définir votre fuseau horaire par défaut dans config/environment.rb

config.time_zone = "Eastern Time (US & Canada)" 

Maintenant, tous les enregistrements que vous RETIREz sera dans ce fuseau horaire. Si vous avez besoin de fuseaux horaires différents, disons en fonction d'un fuseau horaire de l'utilisateur, vous pouvez le changer avec un before_filter dans votre contrôleur. Assurez-vous de stocker tous vos temps dans la base de données comme UTC et tout sera doux.

+2

J'éviterais 'Time.zone = ..'Comme il n'est pas sûr de thread. – gertas

+0

Est-ce important si vous utilisez un serveur d'application comme mongrel, thin ou passager? Ils courent plus d'une instance, seul thread je crois? Je peux me tromper, aimerais savoir! – nitecoder

+4

'Time.zone =' est thread-safe https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/time/zones.rb#L36-38. – lest

8

Si vous ajoutez ceci à votre /config/application.rb

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

Ensuite, vous pouvez cellule

Annotation.last.created_at.in_time_zone 

pour obtenir le temps dans la zone de temps spécifiée.

14

Bien que ce soit une vieille question, il vaut la peine de mentionner quelque chose. Dans un previous reply, il est suggéré d'utiliser un before_filter pour définir le fuseau horaire dans le temps.

Vous ne devriez jamais faire cela, parce que Time.zone stocke les informations dans le thread, et il sera probablement fuite à la prochaine demande traitée par ce thread. A la place, vous devez utiliser un filtre around_filter pour vous assurer que le Time.zone est réinitialisé une fois la requête terminée. Quelque chose comme:

around_filter :set_time_zone 

private 

def set_time_zone 
    old_time_zone = Time.zone 
    Time.zone = current_user.time_zone if logged_in? 
    yield 
ensure 
    Time.zone = old_time_zone 
end 

En savoir plus sur cette here

+0

De nos jours, il existe une méthode intéressante [Time.use_zone] (https://apidock.com/rails/Time/use_zone/class). – freemanoid

2

Si vous configurez votre /config/application.rb

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

Time.now.in_time_zone 

DateTime.now.in_time_zone 
Questions connexes