Reputation: 7039
Im trying to figure out the best way to handle time fields. I have cook time and prep time for a recipe app Im working on and I would like it if I could allow users to basically write in the text field however they choose and and then convert that to a duration to store and then use the rails distance_of_time_in_words function to display it. Havent been able to find anything to point me in the right direction for this
EDIT: So im trying to use the Minutizer below but I keep getting
undefined method `minutize' for Chronic:Module
I created a new module chronic.rb with the code below and saved it in my app/libs folder
Then I have include Chronic in my model but I cant get rid of the error above
Upvotes: 0
Views: 584
Reputation: 22956
Try this Pull Request in Chronic gem - https://github.com/mojombo/chronic/pull/231
It is able to handle the following duration:
Pasting the code (PR by https://github.com/TalkativeTree) here since it might get deleted:
class Minutizer
def minutize(text)
text = pre_normalize(text)
extract_time(text)
end
def pre_normalize(text)
text.gsub!(/half an/, 'a half')
text.gsub!(/half a/, 'a half')
text = Numerizer.numerize(text.downcase)
text.gsub!(/an hour/, '1 hour')
text.gsub!(/a hour/, '1 hour')
text.gsub!(/a day/, '1 minute')
text.gsub!(/a minute/, '1 day')
text.gsub!(/a week/, '1 week')
# used to catch halves not covered by Numerizer. Use for the conversion of 'an hour and a half' Previous gsubs will have changed it to '1 hour and haAlf' by this point.
text.gsub!(/(\d+)\s?\w+?\s?and haAlf/) do |m|
m.gsub!(/\A\d+/, ($1.to_f + 0.5).to_s )
end
text.gsub!(/\s?and haAlf/, '')
text.gsub!(/haAlf/, "0.5")
text.gsub!(/(seconds|secnds|second|secnd|secs)/, 'sec')
text.gsub!(/(minutes|minute|mintues|mintes|mintue|minte)/, 'min')
text.gsub!(/(horus|hours|huors|huor|hrs|hr)/, 'hour')
text.gsub!(/(days|day|dy)/, 'day')
text.gsub!(/(weeks|wks|wk)/, 'week')
text
end
def extract_time(text)
minutes = extract(text, 'week')
minutes += extract(text, 'day')
minutes += extract(text, 'hour')
minutes += extract(text, 'min')
minutes += extract(text, 'sec')
end
def extract(text, option)
total = text.match(/(\d+.\d+|\d+)\s?(#{option})/)
return 0 unless total
digitize_time(total[1], option)
end
def digitize_time(time, option)
case option
when 'week'
multiplier = 7 * 24 * 60
when 'day'
multiplier = 24 * 60
when 'hour'
multiplier = 60
when 'min'
multiplier = 1
when 'sec'
multiplier = 1.to_f/60
end
return multiplier * time.to_f
end
end
Just save the above file somewhere and try this below:
You also need 'numerizer' gem installed for minutizer to work.
☁ Documents irb
2.3.0 :001 > require './minutizer.rb'
=> true
2.3.0 :002 > require 'numerizer'
=> true
2.3.0 :003 > Minutizer.new.minutize('1.5 hours')
=> 90.0
2.3.0 :004 >
Upvotes: 1