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"
time_zone = Time.zone # any time zone really
time_zone.local(date.year, date.month, date.day)
Le problème est, Date.beginning_of_day
n'honore pas Time.zone
dans ActiveSupport 2.3
Comparez https://github.com/Rails/rails/blob/v2.3.11/activesupport/lib/active_support/core_ext/date/calculations.rb#L64 (AS 2.3)
to https://github.com/Rails/rails/blob/master/activesupport/lib/active_support/core_ext/date/calculations.rb#L74 et https : //github.com/Rails/rails/blob/master/activesupport/lib/active_support/core_ext/date/zones.rb#L7 (AS 3)
DateTime.now.in_time_zone(Time.zone).beginning_of_day
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")
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
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.
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 ) }
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
Je sais que ce post est vieux, mais qu'en est-il:
Time.zone.parse("12am")