我为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"
答案 0 :(得分:38)
DateTime.now.in_time_zone(Time.zone).beginning_of_day
答案 1 :(得分:20)
time_zone = Time.zone # any time zone really
time_zone.local(date.year, date.month, date.day)
问题是,Date.beginning_of_day
不尊重ActiveSupport 2.3中的Time.zone
到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)
答案 2 :(得分:9)
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
天:
# 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")
答案 3 :(得分:2)
关闭Peder的回答,这是我为PST时区做的事情:
DateTime.now.in_time_zone("Pacific Time (US & Canada)").beginning_of_day
答案 4 :(得分:1)
may2 = Date.new(2012,5,2)
midnight = Time.zone.local(may2.year,may2.month,may2.day).beginning_of_day
2012年5月2日星期三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
=>星期二,01五月2012 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(),但我没弄清楚如何。
答案 5 :(得分:1)
我知道这篇文章很老了,但是呢:
Time.zone.parse("12am")
答案 6 :(得分:0)
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
答案 7 :(得分:0)
正如Leonid Shevtsov所说,Date.beginning_of_day
不尊重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 ) }