Ruby null DateTime 的良性值
Ruby Benign vale for nil DateTime
比较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 的解决方案会很好。 (但较新的解决方案也很适合将来参考)
从the docs开始,要求是而不是 "all objects are the same type"。它说:
The other should be a date object or a numeric value as an astronomical Julian day number.
因此,对于保证 before/after any 日期的良性值,您可以相应地使用 -Float::INFINITY
和 Float::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 manually), where the method signature was changed 至:
class DateTime
def <=>(other)
super other.kind_of?(Infinity) ? other : other.to_datetime
end
end
...然后您可以使用 Date::Infinity
(TIL 那是一回事)而不是 Float::Infinity
,这个 "fixed" 版本的方法现在可以正确处理它:
DateTime.now > Date::Infinity.new #=> false
DateTime.now > -Date::Infinity.new #=> true
比较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 的解决方案会很好。 (但较新的解决方案也很适合将来参考)
从the docs开始,要求是而不是 "all objects are the same type"。它说:
The other should be a date object or a numeric value as an astronomical Julian day number.
因此,对于保证 before/after any 日期的良性值,您可以相应地使用 -Float::INFINITY
和 Float::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 manually), where the method signature was changed 至:
class DateTime
def <=>(other)
super other.kind_of?(Infinity) ? other : other.to_datetime
end
end
...然后您可以使用 Date::Infinity
(TIL 那是一回事)而不是 Float::Infinity
,这个 "fixed" 版本的方法现在可以正确处理它:
DateTime.now > Date::Infinity.new #=> false
DateTime.now > -Date::Infinity.new #=> true