views:

3944

answers:

4

I want to be able to compare Dates and Times in Rails without always having to call the to_time or to_date method. So I wrote the following code:

class Date
  def ==(other)
    if other.kind_of?(Time)
      self.to_time == other
    else
      super(other)
    end
  end
end

I know there's an easy way to write this so that I can make this work for >, <, >=, <= and <=>. But I forgot how :P Any ideas?

A: 

Your example looks okay, but I wouldn't use kind_of? - if other doesn't implement to_time you get an exception anyway!

Update: What you are looking for is probably the <=> operator!

Christoph Schiessl
A: 

Well, the Date and Time classes simply implement <=>, which is the normal Ruby comparison method/operator.

See also the documentation of Date#<=> and Time#<=> .

Jeroen Heijmans
A: 

I believe what you're asking for is already implemented using the comparison operator that the other posters have mentioned.

(segfault@megumi)(01:35)% ./script/console
Loading development environment (Rails 2.2.0)
irb(main):001:0> a = Date.now
NoMethodError: private method `now' called for Date:Class
    from (irb):1
    from :0
irb(main):002:0> a = Date.today
    => Mon, 10 Nov 2008
irb(main):003:0> b = Time.today
    => Mon Nov 10 00:00:00 -0500 2008
irb(main):004:0> a == b
    => nil
irb(main):005:0> puts "a" if a == b
    => nil
irb(main):006:0> puts "a" if a != b
    a
    => nil
irb(main):007:0>
segy
This fails for > or < operators, with the error"ArgumentError: comparison of Date with Time failed"
AShelly
+2  A: 

The easiest way to make any old Ruby class comparable is to implement the <=> instance method and include the Comparable mixin. You'll get the >, <, >=, <=, ==, etc. methods for free then.

One way of approaching this is to re-open the Date and Time classes to include Comparable and redefining their <=> methods to do the Date/Time conversions if necessary (falling back on the original <=> definition otherwise).

Chu Yeow
This is the answer I was looking for. Thanks!
gsmendoza