www.francisfish.com

Click Bookshop to see my novels. Buddhist, father of 2, Ruby on Rails programmer for money, and fiction writer.

    follow me on Twitter

    Getting the number of months between two dates in Ruby/Rails - updated

    Published: 12:04 PM GMT, Wednesday, 2 April 2008

    Here lies the one that works, not the old one I posted ages ago. It also uses dates instead of timestamp differences and should therefore not break if you ask it to go before the Epoch (some time in 1970 I think):

    Also see Adrien's comment left here (he's much cleverer than me!) - it's really trivial:

    s is the start date and e is the end date (s is lower than e)

    (e.month - s.month) + 12 * (e.year - s.year)

    See!

    module DateUtils
    
      class << self
        def months_between( date1=Time.now, date2=Time.now )
    
          date1 ||= Time.now
          date2 ||= Time.now
    
          if date1 > date2
            recent_date = date1.to_date
    
            past_date = date2.to_date
          else
            recent_date = date2.to_date
    
            past_date = date1.to_date
          end
          years_diff = recent_date.year - past_date.year
    
          months_diff = recent_date.month - past_date.month
          if months_diff < 0
    
            months_diff = 12 + months_diff
            years_diff -= 1
    
          end
          years_diff*12 + months_diff
        end
    
      end
    
    end
    

    Comments (3)

    Thanks for the post and the subsequent comments. I have actually gone with Adrien's comment.

    Thanks Adrien.

    left by satya . Monday, 28 December 2009 4:43 PM

    Hi thanks for this useful post. I've copied your idea for a DateUtils module and put it in the lib of my rails app.

    Thought you might like to know that it can be squished into a two-liner making heavy use of parallel assignment...

    def months_between(date1=Date.today, date2=Date.today)

    (date1 > date2) ? (recent_date, past_date = date1, date2) : (recent_date, past_date = date2, date1)

    (recent_date.year - past_date.year) * 12 + (recent_date.month - past_date.month)

    end

    I don't think it loses too much readability...

    left by Henry . Wednesday, 18 June 2008 6:25 PM

    I've done this like that :

    s is the start date and e is the end date (s is lower than e)

    (e.month - s.month) + 12 * (e.year - s.year)

    left by Adrien . Tuesday, 15 April 2008 7:31 PM
    Add Comment