How to Evaluate a Date Difference in Years, Months and Days (Ruby)

How to evaluate a date difference in years, months and days (ruby)?

Found the answer here:

More precise distance_of_time_in_words

with this gem:

https://github.com/radar/dotiw

How do I know the difference of days, months, and years from a date, can I use subtraction?

There are a handful of ways to accomplish what you're trying to do -- Here are a few possibilities.

Using Time (my recommendation so you have more flexibility later depending on how your needs change and how you end up expiring content):
You can convert the "days to expire" to seconds and then add that to your time object. For example:

require "time"

t = Time.parse("01/05/2019")
days_to_expire = 30
expiration = t + (60 * 60 * 24 * days_to_expire)

Using Date:

require "date"

d = Date.parse("01/05/2019")
days_to_expire = 30
expiration = d + days_to_expire

Using built-in helpers from Rails Active::Support:

t = Time.parse("01/05/2019")
days_to_expire = 30
expiration = t + days_to_expire.days

You can learn more about Ruby Time here and you can learn about the helpers built-in to Time and Numeric by Rails here and here.

How to calculate how many years passed since a given date in Ruby?

Do you want age as people typically understand it, or are you looking for a precise measure of time elapsed? If the former, there is no need to worry about leap years and other complications. You simply need to compute a difference in years and reduce it if the person has not had a birthday yet this year. If the latter, you can convert seconds elapsed into years, as other answers have suggested.

def age_in_completed_years (bd, d)
# Difference in years, less one if you have not had a birthday this year.
a = d.year - bd.year
a = a - 1 if (
bd.month > d.month or
(bd.month >= d.month and bd.day > d.day)
)
a
end

birthdate = Date.new(2000, 12, 15)
today = Date.new(2009, 12, 14)

puts age_in_completed_years(birthdate, today)

Find number of months between two Dates in Ruby on Rails

(date2.year * 12 + date2.month) - (date1.year * 12 + date1.month)

more info at http://www.ruby-forum.com/topic/72120

Calculate how many n.months between two dates

Thanks for @Cary's and @Lam's answer.

Here is my answer to find the n month.

# try to find the minimum n month between start_date and target_date
def calc_diff(start_date, target_date)
months_diff = (target_date.year * 12 + target_date.month) - (start_date.year * 12 + start_date.month)

## need to check the end of month because some special case
## start date: 2020-01-31 ; end date 2020-06-30
## the minimum n month must be 5
## another special case of Feb must consider (test case 15)

if start_date.day > target_date.day && !((start_date == start_date.end_of_month || target_date.month == 2) && (target_date == target_date.end_of_month))
months_diff = months_diff - 1
end
puts months_diff # it will show the minimum whole n month

# the target_date will between inside
# (start_date + months_diff.months) <= target_date < (start_date + (months_diff + 1).months)
(start_date + months_diff.months)..(start_date + (months_diff + 1).months)
end

The Test Cases:

## test case 1
## 6/15 - 7/15 => n = 5
calc_diff(Date.parse('2020-01-15'), Date.parse('2020-06-19'))

## test case 2
## 7/15 - 8/15 => n = 6
calc_diff(Date.parse('2020-01-15'), Date.parse('2020-07-15'))

## test case 3
## 5/15 - 6/15 => n = 4
calc_diff(Date.parse('2020-01-15'), Date.parse('2020-06-01'))

## test case 4 (special case)
## 6/30 - 7/31 => n = 5
calc_diff(Date.parse('2020-01-31'), Date.parse('2020-06-30'))

## test case 5
## 7/30 - 8/30 => n = 4
calc_diff(Date.parse('2020-04-30'), Date.parse('2020-07-31'))

## test case 6
## 6/30 - 7/30 => n = 2
calc_diff(Date.parse('2020-04-30'), Date.parse('2020-06-30'))

## test case 7
## 5/31 - 6/30 => n = 4
calc_diff(Date.parse('2020-01-31'), Date.parse('2020-05-31'))

## test case 8
## 2/29 - 3/31 => n = 1
calc_diff(Date.parse('2020-01-31'), Date.parse('2020-02-29'))

## test case 9
## 6/29 - 7/29 => n = 4
calc_diff(Date.parse('2020-02-29'), Date.parse('2020-06-30'))

## test case 10
## 7/29 - 8/29 => n = 5
calc_diff(Date.parse('2020-02-29'), Date.parse('2020-07-31'))

## test case 11
## 1/31 - 2/29 => n = 0
calc_diff(Date.parse('2020-01-31'), Date.parse('2020-02-28'))

## test case 12
## 2/29 - 3/31 => n = 1
calc_diff(Date.parse('2020-01-31'), Date.parse('2020-03-01'))

## test case 13
## 1/17 - 2/17 => n = 0
calc_diff(Date.parse('2020-01-17'), Date.parse('2020-01-17'))

## test case 14
## 1/17 - 2/17 => n = 0
calc_diff(Date.parse('2020-01-17'), Date.parse('2020-01-18'))

## test case 15 (special case)
## 1/30 - 2/29 => n = 1
calc_diff(Date.parse('2019-12-30'), Date.parse('2020-02-28'))

## test case 16
## 2/29 - 3/30 => n = 2
calc_diff(Date.parse('2019-12-30'), Date.parse('2020-02-29'))

How can I find the number of days between two Date objects in Ruby?

Subtract the beginning date from the end date:

endDate - beginDate 

How to check if difference between two dates is exactly in multiple of X number of months

This should work fine with Rails (end_of_month is needed) :

def month_id(date)
date.month + date.year * 12
end

def same_day?(date1, date2)
(last_day_of_month?(date1) && date2.day >= date1.day) ||
(last_day_of_month?(date2) && date1.day >= date2.day) ||
date1.day == date2.day
end

def last_day_of_month?(date)
date == date.end_of_month
end

def separated_by_multiple_of_x_months?(date1, date2, x = 4)
same_day?(date1, date2) && (month_id(date1) - month_id(date2)) % x == 0
end

separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-09-15'))
#=> true
separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-09-14'))
#=> false
separated_by_multiple_of_x_months?(Date.parse('2017-01-15'), Date.parse('2016-05-15'))
#=> true
separated_by_multiple_of_x_months?(Date.parse('2017-01-31'), Date.parse('2016-09-30'))
#=> true
separated_by_multiple_of_x_months?(Date.parse('2016-11-30'), Date.parse('2016-07-31'))
#=> true
separated_by_multiple_of_x_months?(Date.parse('2016-11-30'), Date.parse('2016-07-30'))
#=> true


Related Topics



Leave a reply



Submit