我们来看看日期:
1.9.2p320 :008 > Date.today => Wed,03 Oct 2012 1.9.2p320 :009 > Time.now => 2012-10-03 22:32:55 -0400
现在,鉴于午夜时分?
1.9.2p320 :005 > Date.today.midnight => Wed,03 Oct 2012 00:00:00 UTC +00:00
说得通.但昨天怎么样?
1.9.2p320 :006 > Date.yesterday.midnight => Wed,03 Oct 2012 00:00:00 UTC +00:00
呃,这没有多大意义.今天午夜和昨天午夜一样?你不能认真!
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
哦,你是认真的.明天怎么样?
1.9.2p320 :007 > Date.tomorrow.midnight => Fri,05 Oct 2012 00:00:00 UTC +00:00
等等,如果今天午夜是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
但今天不是零天?显然不是.
是我,还是内部一致?在我看来,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
但似乎这些是方便函数,将时区假设投入到一个便利函数而不是将其抛入另一个便利函数中是有意义的,所有这些都是同样的意思.
即使把它放在一边,它似乎也没有解释Date.today.midnight == Date.yesterday.midnight的事实,这简直就是疯了.
既然我知道我不能成为第一个被这个咬过的人,我问我错过了什么?
解决方法
Rails将基于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实际返回相同的日期!
尝试使用Time.zone =’东部时间(美国和加拿大)’或您所在的任何时区设置您的Rails时区,然后重试您的示例.