web-dev-qa-db-fra.com

Rails: obtenez #beginning_of_day dans le fuseau horaire

J'ai une configuration de fuseau horaire par défaut pour l'application Rails. Et une instance de l'objet Date.

Comment puis-je obtenir la valeur Date # début_du_jour pour renvoyer le début de la journée dans le fuseau horaire spécifié, mais pas dans mon fuseau horaire local.

Existe-t-il une autre méthode pour obtenir l'heure du début de la journée dans le fuseau horaire spécifié pour la date donnée?

date = Date.new(2014,10,29)

zone = ActiveSupport::TimeZone.new('CET')
date.foo(zone) # should return "Wed, 29 Oct 2014 00:00:00 CET +01:00"

zone = ActiveSupport::TimeZone.new('UTC')
date.foo(zone) # should return "Wed, 29 Oct 2014 00:00:00 UTC +00:00"
21
Bogdan Gusiev
20
Leonid Shevtsov
DateTime.now.in_time_zone(Time.zone).beginning_of_day
38
Peder

Date#beginning_of_day retournera toujours 00:00.

Mais si je comprends bien, vous voulez connaître l’heure dans un autre fuseau horaire alors que le fuseau horaire actuel est en début de journée.

Alors. Découvrons le début de la journée à votre place actuelle. Imaginez que c'est Paris, France:

bd = DateTime.now.in_time_zone('Paris').beginning_of_day
# or just
bd = DateTime.now.in_time_zone(1).beginning_of_day
#=> Thu, 24 Mar 2011 00:00:00 WET +01:00

Voyons maintenant quelle heure est à Moscou:

moscow_time = bd.in_time_zone("Moscow") # or in_time_zone(3)
#=> Thu, 24 Mar 2011 02:00:00 AST +03:00
london_time = bd.in_time_zone("London")
#=> Wed, 23 Mar 2011 23:00:00 GMT +00:00
kyiv_time = bd.in_time_zone("Kyiv")
#=> Thu, 24 Mar 2011 01:00:00 EET +02:00 

Pour forme différente now jour:

# You even shouldn't call now, because it by default will be 00:00
date = DateTime(2011, 1, 3).in_time_zone("-10")
# or
date = DateTime.new(2011,1,3,0,0,0,"-10")
# and same way as above
moscow_time = date.in_time_zone("Moscow") # or in_time_zone(3)

et convertir Date en DateTime

date = Date.new(2011,1,3).to_datetime.change(:offset => "EST")
9
fl00r

Au sujet de la réponse de Peder, voici ce que j'ai fait pour le fuseau horaire PST:

DateTime.now.in_time_zone("Pacific Time (US & Canada)").beginning_of_day
2
Tim S
may2 = Date.new(2012,5,2)
midnight = Time.zone.local(may2.year,may2.month,may2.day).beginning_of_day

Le mercredi 2 mai 2012 00:00:00 UTC +00: 00

midnight = Time.zone.local(may2.year,may2.month,may2.day).in_time_zone("Moscow").beginning_of_day

=> Mer., 02 mai 2012 00:00:00 MSK +04: 00

midnight = Time.zone.local(may2.year,may2.month,may2.day).in_time_zone("Alaska").beginning_of_day

=> Mar., 01 mai 2012 00:00:00 AKDT -08: 00

AVIS, c'est la mauvaise journée.

Ce qu'il faut, c'est un moyen de construire une TimeWithZone dans le fuseau horaire correct.

Time.zone="Alaska"
midnight = Time.zone.local(may2.year,may2.month,may2.day)

Je n'aime vraiment pas cela, car à ma connaissance, je viens de changer la notion system de la zone dans laquelle je me trouve. L'idée est de modifier les recherches dans la base de données pour qu'elles correspondent à la zone du client. ... Je dois donc sauvegarder la zone et la restaurer:

foo = Time.zone; Time.zone="Alaska"; midnight = Time.zone.local(may2.year,may2.month,may2.day); Time.zone = foo

Il semble que je devrais pouvoir appeler TimeWithZone.new (), mais je n'ai pas trouvé comment.

1
mcr

Comme Leonid Shevtsov l'a mentionné, Date.beginning_of_day n'honore pas Time.zone dans ActiveSupport 2.3.

Une alternative que j'ai utilisée, si vous êtes bloqué avec Rails 4.0 ou ActiveSupport 2.3 et que vous devez utiliser une date personnalisée:

date = Date.new(2014,10,29)
date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone  #.beginning_of_day
date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone #.end_of_day

Résultats:

2.0.0-p247 :001 > date = Date.new(2014,10,29)
 => Wed, 29 Oct 2014 

2.0.0-p247 :002 > date.to_time.change(hour: 0, min: 0, sec: 0)
 => 2014-10-29 00:00:00 -0500 

2.0.0-p247 :003 > date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone
 => Wed, 29 Oct 2014 05:00:00 UTC +00:00 

2.0.0-p247 :004 > date.to_time.change(hour: 23, min: 59, sec: 59)
 => 2014-10-29 23:59:59 -0500 

2.0.0-p247 :005 > date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone
 => Thu, 30 Oct 2014 04:59:59 UTC +00:00 

La portée de mon modèle d'origine qui a échoué et qui a utilisé .beginning_of_day pour .end_of_day n'a pas fonctionné:

scope :on_day, ->(date) { where( created_at: date.beginning_of_day..date.end_of_day ) }

Et, c’est ce qui a résolu le problème, car je ne pouvais pas passer à Rails 4.0.

scope :on_day, ->(date) { where( created_at: date.to_time.change(hour: 0, min: 0, sec: 0).in_time_zone..date.to_time.change(hour: 23, min: 59, sec: 59).in_time_zone ) }
0
Eric Wanchic
ActiveSupport::TimeZone['Europe/London'].parse('30.07.2013') # 2013-07-29 23:00:00 UTC 
ActiveSupport::TimeZone['Asia/Magadan'].parse('30.07.2013') # 2013-07-29 12:00:00 UTC
0
Dmitry Lihachev

Je sais que ce post est vieux, mais qu'en est-il:

Time.zone.parse("12am")
0
Jason Galuten