StaleElementException
StaleElementException

Reputation: 270

get no of months, years between two dates in ruby

I'm trying to write web ui tests to choose date from jquery calender based on user input (watir-webdriver), how can find no of months years between two give dates, i searched few solution couldn't get what i want

date1 = Date::strptime("2013-09-19", "%Y-%m-%d")  
date2 = Date::strptime("2013-09-25", "%Y-%m-%d")  
date3 = Date::strptime("2013-10-01", "%Y-%m-%d")  
date4 = Date::strptime("2014-01-20", "%Y-%m-%d")  
date5 = Date::strptime("2014-12-01", "%Y-%m-%d")  

desired output

diff between date1,date2 -- 0 yrs, 0 month(s)  
diff between date1,date3 -- 0 yrs, 1 month(s)  
diff between date1,date4 -- 0 yrs, 4 month(s)  
diff between date1,date5 -- 1 yrs, 3 month(s)  

i checked time_diff gem also

Upvotes: 3

Views: 6849

Answers (3)

DaniG2k
DaniG2k

Reputation: 4903

I took this from the TimeDifference gem but it works so nicely that I thought I'd share. If you're using Rails, make a class called TimeDifference with the following code:

class TimeDifference
  private_class_method :new

  def self.between(start_time:, end_time:)
    new(start_time, end_time)
  end

  def in_seconds
    @time_diff
  end

  def in_minutes
    in_component(:minutes)
  end

  def in_hours
    in_component(:hours)
  end

  def in_days
    in_component(:days)
  end

  def in_weeks
    in_component(:weeks)
  end

  def in_months
    (@time_diff / (1.day * 30.42)).round(2)
  end

  def in_years
    in_component(:years)
  end

  private

  def initialize(start_time, end_time)
    start_time = time_in_seconds(start_time)
    end_time   = time_in_seconds(end_time)
    @time_diff = (end_time - start_time).abs
  end

  def time_in_seconds(time)
    time.to_time.to_f
  end

  def in_component(component)
    (@time_diff / 1.send(component)).round(2)
  end
end

And then simply call:

start_time = DateTime.parse('2 June, 1999 9:00:00')
end_time = DateTime.parse('19 April, 2021 9:00:00')

time_difference = TimeDifference.between(
  start_time: start_time,
  end_time: end_time
)

time_difference.in_days
=> 7992.0

time_difference.in_months
=> 262.72

time_difference.in_years
=> 21.88

Note: if you're not using Rails you might have to require ActiveSupport.

Upvotes: 0

Dex
Dex

Reputation: 12759

Here is my attempt. Works in multiple units:

  def date_diff(date1, date2, units=:months)
    seconds_between = (date2.to_i - date1.to_i).abs
    days_between = seconds_between / 60 / 60 / 24

    case units
      when :days
        days_between.floor
      when :months 
        (days_between / 30).floor
      when :years
        (days_between / 365).floor
      else
        seconds_between.floor
    end
  end

Usage:

date_diff(Time.now, 10.years.ago - 77.days, :years)  #=> 10 
date_diff(10.years.ago - 77.days, Time.now, :months) #=> 124
date_diff(10.years.ago - 77.days, Time.now, :days)   #=> 3730

Upvotes: 3

tessi
tessi

Reputation: 13574

I'd calculate the difference in months (be aware that we ignore day differences here) and then calculate the number of years by dividing that number by 12:

##
# Calculates the difference in years and month between two dates
# Returns an array [year, month]
def date_diff(date1,date2)
  month = (date2.year * 12 + date2.month) - (date1.year * 12 + date1.month)
  month.divmod(12)
end

date_diff date1, date4 #=> [0, 4]
date_diff date1, date2 #=> [0, 0]
date_diff date1, date3 #=> [0, 1]
date_diff date1, date5 #=> [1, 3]

Upvotes: 10

Related Questions