Rails:在时区中获取#beginning_of_day

我有一个rails应用程序的默认时区设置。 和Date对象的一个​​实例。

如何让Date#beginning_of_day返回指定时区内的一天的开始,而不是我当地的时区。

是否有其他方法可以在给定日期的指定时区内开始白天时间?

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) 

问题是, Date.beginning_of_dayTime.zone ActiveSupport 2.3中的Time.zone

比较https://github.com/rails/rails/blob/v2.3.11/activesupport/lib/active_support/core_ext/date/calculations.rb#L64(AS 2.3)

到https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/date/calculations.rb#L74和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将始终返回00:00。

但据我所知,你想知道在其他时区的时间,而在当前时区是一天的开始。

所以。 让我们在你当前的地方找到一天的开始。 想象一下,它是法国巴黎:

 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 

现在让我们来看看莫斯科几点钟了:

 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 

对于now不同forms:

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

并将Date转换为DateTime

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

关闭Peder的回答,这就是我为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 

星期三,02五月2012 00:00:00 UTC +00:00

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

=> 2012年5月2日星期三00:00:00 MSK +04:00

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

=>星期二,2012年5月1日00:00:00 AKDT -08:00

注意,这是错误的一天。

需要的是在正确的时区中构造TimeWithZone的方法。

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

我真的不喜欢这个,因为据我所见,我刚刚改变了我所在区域的系统概念。想法是改变我的数据库搜索以匹配客户区域…所以,我必须保存区域并恢复它:

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

看起来我应该能够调用TimeWithZone.new(),但我没弄明白怎么做。

 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 

正如Leonid Shevtsov所说, Date.beginning_of_dayTime.zone ActiveSupport 2.3中的Time.zone

我使用的另一种方法,如果您使用Rails 4.0或ActiveSupport 2.3,并且您需要使用自定义日期:

 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 

结果:

 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 

使用.beginning_of_day到.end_of_day的原始失败模型范围无效:

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

并且,这是修复它的原因,因为我无法升级到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 ) } 

我知道这篇文章很老了,但是怎么样:

 Time.zone.parse("12am")