Rails时间午夜时间会被打破吗?

Joh*_*tta 7 time timezone ruby-on-rails date utc

我们来看看日期:

1.9.2p320 :008 > Date.today
 => Wed, 03 Oct 2012 
1.9.2p320 :009 > Time.now
 => 2012-10-03 22:32:55 -0400
Run Code Online (Sandbox Code Playgroud)

现在,鉴于午夜时分?

1.9.2p320 :005 > Date.today.midnight
 => Wed, 03 Oct 2012 00:00:00 UTC +00:00 
Run Code Online (Sandbox Code Playgroud)

说得通.但昨天怎么样?

1.9.2p320 :006 > Date.yesterday.midnight
 => Wed, 03 Oct 2012 00:00:00 UTC +00:00 
Run Code Online (Sandbox Code Playgroud)

呃,这没有多大意义.今天午夜和昨天午夜一样?你不能认真!

1.9.2p320 :026 > Date.today.midnight == Date.yesterday.midnight
 => true 
1.9.2p320 :033 > 1.day.ago.midnight == Date.yesterday.midnight
 => true 
1.9.2p320 :034 > 1.day.ago.midnight == Date.today.midnight
 => true 
Run Code Online (Sandbox Code Playgroud)

哦,你是认真的.明天怎么样?

1.9.2p320 :007 > Date.tomorrow.midnight
 => Fri, 05 Oct 2012 00:00:00 UTC +00:00 
Run Code Online (Sandbox Code Playgroud)

等等,如果今天午夜是3点00:00,昨天午夜是3点00:00,明天午夜是5点00:00,4点00:00?

这里是:

1.9.2p320 :010 > 0.days.ago
 => Thu, 04 Oct 2012 02:34:58 UTC +00:00 
1.9.2p320 :011 > 0.days.ago.midnight
 => Thu, 04 Oct 2012 00:00:00 UTC +00:00
Run Code Online (Sandbox Code Playgroud)

今天不是零天显然不是.

是我,还是内部一致?在我看来,Date.today应该与0.days.ago相同.

我明白这days.ago实际上是使用Time对象,这是一个时区问题:

1.9.2p320 :030 > Date.today
 => Wed, 03 Oct 2012 
1.9.2p320 :021 > Time.now
 => 2012-10-03 22:40:09 -0400 
1.9.2p320 :023 > 0.days.ago
 => Thu, 04 Oct 2012 02:40:22 UTC +00:00 
1.9.2p320 :022 > Time.zone.now
 => Thu, 04 Oct 2012 02:40:14 UTC +00:00 
Run Code Online (Sandbox Code Playgroud)

但似乎这些是方便函数,将时区假设投入到一个便利函数而不是将其抛入另一个便利函数中是有意义的,所有这些都是同样的意思.

即使把它放在一边,它似乎也没有解释这个事实 - 这简直就是Date.today.midnight == Date.yesterday.midnight疯狂.

既然我知道我不能成为第一个被这个咬过的人,我问我错过了什么?

ros*_*sta 7

轨道将基地相对日期计算,例如yesterday,tomorrow,和midnight关闭的Date.current,其将尝试使用所配置的Time.zone: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/date/calculations.rb #L46

由于您Time.zone设置为UTC,因此您将无法获得与基于计算的结果相同的结果Date.today,这将使用计算机的时钟时间,除非您实际上坐在UTC时间.

所以,如果你和UTC之间的时差大于到午夜的时间,Date.yesterday并且Date.today实际上返回相同的日期!

尝试使用Rails时区Time.zone = 'Eastern Time (US & Canada)'或您所在的时区设置,然后重试示例.