Skip to content

Instantly share code, notes, and snippets.

@ibanez270dx
Created October 30, 2018 07:55
Show Gist options
  • Save ibanez270dx/6c68cc9389557f2c483895930fab992c to your computer and use it in GitHub Desktop.
Save ibanez270dx/6c68cc9389557f2c483895930fab992c to your computer and use it in GitHub Desktop.
Return human age by date of birth
module ActionView::Helpers::DateHelper
def age(date_of_birth, **options)
from_time = normalize_distance_of_time_argument_to_time(date_of_birth)
to_time = normalize_distance_of_time_argument_to_time(options.delete(:to_time) || Time.now)
from_time, to_time = to_time, from_time if from_time > to_time
distance_in_minutes = ((to_time - from_time) / 60.0).round
case distance_in_minutes
when 0...43200 # 0 to 30 days
"#{(distance_in_minutes.to_f / 1440.0).round} days"
when 43200...MINUTES_IN_YEAR # 30 to 365 days
months = (distance_in_minutes.to_f / 43200.0).round
[months, "month".pluralize(months)].join(" ")
else # start accounting for leap years...
from_year = from_time.year
from_year += 1 if from_time.month >= 3
to_year = to_time.year
to_year -= 1 if to_time.month < 3
leap_years = (from_year > to_year) ? 0 : (from_year..to_year).count{ |x| Date.leap?(x) }
minute_offset_for_leap_year = leap_years * 1440
# Discount the leap year days when calculating year distance.
# e.g. if there are 20 leap year days between 2 dates having the same day and month then based on the 365 days
# calculation, the distance in years will come out to "over 80 years" when in written English it would read
# better as "about 80 years".
minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
remainder = minutes_with_offset % MINUTES_IN_YEAR
distance_in_years = minutes_with_offset.div MINUTES_IN_YEAR
if minutes_with_offset < (MINUTES_IN_YEAR * 2)
"#{(minutes_with_offset.to_f / 43200.0).round} months"
elsif remainder < MINUTES_IN_QUARTER_YEAR || remainder < MINUTES_IN_THREE_QUARTERS_YEAR
"#{distance_in_years} years"
else
"#{distance_in_years + 1} years"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment