Ruby Benign谷无零DateTime

时间:2019-05-08 21:29:38

标签: ruby ruby-on-rails-3.2 comparator ruby-1.9 date-comparison

比较DateTimes时,所有要比较的对象必须是同一类型。但是,我有一个具有nil日期的数据集。我想将这些日期比任何其他日期都旧(或更新)。有没有一种方法可以构造一个比其他任何日期都旧(或替换为新)的良性值?

示例:

data = [
  { name: :foo, timestamp: make_benign(some_valid_timestamp) },
  { name: :bar, timestamp: make_benign(nil)}
]

data.sort_by{|datum| datum[:timestamp]} #=> [<bar>, <foo>]
data.max_by {|datum| datum[:timestamp]} #=> <foo>
data.min_by {|datum| datum[:timestamp]} #=> <bar>

编辑:由于这个问题,我碰巧被困在ruby 1.9上,因此旧版本的ruby的解决方案会很好。 (但是较新的解决方案也很适合将来参考)

1 个答案:

答案 0 :(得分:2)

the docs中,要求不是“所有对象都是同一类型”。它说:

  

另一个应该是日期对象或一个数值,作为天文儒略日数。

因此对于保证在任何日期之前/之后的良性值,您可以相应地使用-Float::INFINITYFloat::INFINITY

DateTime.now > Float::INFINITY  #=> false
DateTime.now > -Float::INFINITY #=> true

编辑:

所以我们需要一个可以在Ruby 1.9和Rails 3.2.9中工作的解决方案,嗯...

以上原因不起作用的原因是this monkeypatch in ActiveSupport

class DateTime
  def <=>(other)
    super other.to_datetime
  end
end

这尤其成问题。不幸的是,您可能只需要使用“ very big/small number”即可。

但是,如果您可以稍微升级到 Rails 3.2.13 (或手动应用此updated monkeypatch),则{{3 }}:

class DateTime
  def <=>(other)
    super other.kind_of?(Infinity) ? other : other.to_datetime
  end
end

...然后您可以使用the method signature was changed(这是TIL来代替)Float::Infinity,并且此方法的“固定”版本现在可以正确处理它:

DateTime.now > Date::Infinity.new  #=> false
DateTime.now > -Date::Infinity.new #=> true