【问题标题】:comparison of Date with ActiveSupport::TimeWithZone failed日期与 ActiveSupport::TimeWithZone 的比较失败
【发布时间】:2012-10-10 02:39:53
【问题描述】:

我的Waiver 模型上有一个age 方法,看起来像:

  def age(date = nil)

    if date.nil?
      date = Date.today
    end
    age = 0
    unless date_of_birth.nil?
      age = date.year - date_of_birth.year
      age -= 1 if date < date_of_birth + age.years #for days before birthday
    end
    return age
  end

然后我有一个看起来像这样的规范:

it "calculates the proper age" do
 waiver = FactoryGirl.create(:waiver, date_of_birth: 12.years.ago)
 waiver.age.should == 12
end

当我运行这个规范时,我得到comparison of Date with ActiveSupport::TimeWithZone failed。我做错了什么?

Failures:

  1) Waiver calculates the proper age
     Failure/Error: waiver.age.should == 12
     ArgumentError:
       comparison of Date with ActiveSupport::TimeWithZone failed
     # ./app/models/waiver.rb:132:in `<'
     # ./app/models/waiver.rb:132:in `age'
     # ./spec/models/waiver_spec.rb:23:in `block (2 levels) in <top (required)>'

【问题讨论】:

  • 我不知道它为什么会失败,但是如果将 date_of_birth 设置为 12.years.ago.to_date 而不是 12.years.ago,它可以正常工作。

标签: ruby-on-rails ruby ruby-on-rails-3 unit-testing rspec


【解决方案1】:

您将Date 的实例与date &lt; date_of_birth + age.years 表达式中的ActiveSupport::TimeWithZone 实例进行比较; ActiveSupport::TimeWithZone 是according to the docs,一个类时间类,可以表示任何时区的时间。如果不执行某种转换,您根本无法比较 DateTime 对象。在控制台上尝试Date.today &lt; Time.now;您会看到类似的错误。

12.years.ago 等表达式和典型的 ActiveRecord 时间戳是 ActiveSupport::TimeWithZone 的实例。您最好确保只处理Time 对象或Date 对象,但不能同时处理此方法。为了使您的比较是最新的,表达式可以改为:

age -= 1 if date < (date_of_birth + age.years).to_date

【讨论】:

  • 感谢您的深入解释。我已经对我的代码进行了适当的更改,现在一切正常!
  • 其实你可以比较一下 Date 和 TimeWithZone,但是 Rails 似乎会默认将 Date 转换为 00:00:00 UTC,这可能会引入错误。 IE。 >> Time.zone.parse('Tue, 01 Aug 2017 00:00:00 CEST +02:00') &lt; Date.new(2017,8,1) => true
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-03
  • 1970-01-01
  • 2019-10-01
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多