Reputation: 2103
I need to translate a number of months, integer based, into a human friendly string containing information about years. its not easy to explain so I will just provide examples. inputs and outputs I want are:
input: 19
output: "1 year, 7 months"
input: 24
output: "2 years"
input: 26
output: "2 years, 2 months"
do you know any out of the box solutions? if not, how would you implement it yourself?
Upvotes: 1
Views: 178
Reputation: 6156
Since this question is tagged with Ruby on Rails, ActiveSupport extensions are available, so this works too:
number_of_months = 19 # for example
ActiveSupport::Duration.build(number_of_months.months).inspect.gsub(' and',', ')
Edit
I just noticed that there was a bug in ActiveSupport::Duration version 6.0.2.2 that was fixed sometime prior to version 6.1.0.alpha that caused rounding errors for certain values of number_of_months
.
Upvotes: 2
Reputation: 6064
input = 26
year, month = input.divmod(12)
if month.eql? 0 and year > 1
puts "#{year} years"
elsif month.eql? 0 and year.eql? 1
puts "#{year} year"
elsif year > 1
puts "#{year} years, #{month} month"
else
puts "#{year} year, #{month} month"
end
Output
2 years, 2 month
Upvotes: 2
Reputation: 11193
Just for fun:
num.divmod(12).then { |y, m| [y, m].zip ['years', 'months'] }
.reject{ |e| e.first.zero? }
.each{ |e| e.last.delete_suffix!('s') if e.first == 1 }
.join(' ')
.tap{ |res| res.replace('0 months') if res.empty? }
Samples:
[11, 12, 13, 23, 24, 25, 26].each { |n| p [n, n.divmod(12).then.......] } # pseudo
[11, "11 months"]
[12, "1 year"]
[13, "1 year 1 month"]
[23, "1 year 11 months"]
[24, "2 years"]
[25, "2 years 1 month"]
[26, "2 years 2 months"]
Upvotes: 1
Reputation: 1083
def pluralize(num, string)
[num, (num == 1 ? string : "#{string}s")] * ' '
end
def humanize_months(months)
months = input % 12
years = input / 12
text = []
text << pluralize(years, 'year') if years > 0
text << pluralize(months, 'month') if months > 0
text * ', '
end
Upvotes: 0