Module | ::Utils::ParseTime |
In: |
lib/rbot/core/utils/parse_time.rb
|
FLOAT_RX | = | /((?:\d*\.)?\d+)/ |
ONE_TO_NINE | = | { :one => 1, :two => 2, :three => 3, :four => 4, :five => 5, :six => 6, :seven => 7, :eight => 8, :nine => 9, } |
ONE_TO_NINE_RX | = | Regexp.new ONE_TO_NINE.keys.join('|') |
TEENS_ETC | = | { :an => 1, :a => 1, :ten => 10, :eleven => 11, :twelve => 12, :thirteen => 13, :fourteen => 14, :fifteen => 15, :sixteen => 16, :seventeen => 17, :eighteen => 18, :nineteen => 19, } |
TEENS_ETC_RX | = | Regexp.new TEENS_ETC.keys.join('|') |
ENTIES | = | { :twenty => 20, :thirty => 30, :forty => 40, :fifty => 50, :sixty => 60, } |
ENTIES_RX | = | Regexp.new ENTIES.keys.join('|') |
LITNUM_RX | = | /(#{ONE_TO_NINE_RX})|(#{TEENS_ETC_RX})|(#{ENTIES_RX})\s*(#{ONE_TO_NINE_RX})?/ |
FRACTIONS | = | { :"half" => 0.5, :"half a" => 0.5, :"half an" => 0.5, :"a half" => 0.5, :"a quarter" => 0.25, :"a quarter of" => 0.25, :"a quarter of a" => 0.25, :"a quarter of an" => 0.25, :"three quarter" => 0.75, :"three quarters" => 0.75, :"three quarter of" => 0.75, :"three quarters of" => 0.75, :"three quarter of a" => 0.75, :"three quarters of a" => 0.75, :"three quarter of an" => 0.75, :"three quarters of an" => 0.75, } |
FRACTION_RX | = | Regexp.new FRACTIONS.keys.join('|') |
UNITSPEC_RX | = | /(years?|months?|s(?:ec(?:ond)?s?)?|m(?:in(?:ute)?s?)?|h(?:(?:ou)?rs?)?|d(?:ays?)?|weeks?)/ |
example: half an hour, two and a half weeks, 5 seconds, an hour and 5 minutes
# File lib/rbot/core/utils/parse_time.rb, line 107 107: def ParseTime.parse_period(str) 108: clean = str.gsub(/\s+/, ' ').strip 109: 110: sofar = 0 111: until clean.empty? 112: if clean.sub!(/^(#{FRACTION_RX})\s+#{UNITSPEC_RX}/, '') 113: # fraction followed by unit 114: num = FRACTIONS[$1.intern] 115: unit = ParseTime.time_unit($2) 116: elsif clean.sub!(/^#{FLOAT_RX}\s*(?:\s+and\s+(#{FRACTION_RX})\s+)?#{UNITSPEC_RX}/, '') 117: # float plus optional fraction followed by unit 118: num = $1.to_f 119: frac = $2 120: unit = ParseTime.time_unit($3) 121: clean.strip! 122: if frac.nil? and clean.sub!(/^and\s+(#{FRACTION_RX})/, '') 123: frac = $1 124: end 125: if frac 126: num += FRACTIONS[frac.intern] 127: end 128: elsif clean.sub!(/^(?:#{LITNUM_RX})\s+(?:and\s+(#{FRACTION_RX})\s+)?#{UNITSPEC_RX}/, '') 129: if $1 130: num = ONE_TO_NINE[$1.intern] 131: elsif $2 132: num = TEENS_ETC[$2.intern] 133: elsif $3 134: num = ENTIES[$3.intern] 135: if $4 136: num += ONE_TO_NINE[$4.intern] 137: end 138: end 139: frac = $5 140: unit = ParseTime.time_unit($6) 141: clean.strip! 142: if frac.nil? and clean.sub!(/^and\s+(#{FRACTION_RX})/, '') 143: frac = $1 144: end 145: if frac 146: num += FRACTIONS[frac.intern] 147: end 148: else 149: raise "invalid time string: #{clean} (parsed #{sofar} so far)" 150: end 151: sofar += num * unit 152: clean.sub!(/^and\s+/, '') 153: end 154: return sofar 155: end
str must much UNITSPEC_RX
# File lib/rbot/core/utils/parse_time.rb, line 83 83: def ParseTime.time_unit(str) 84: case str[0,1].intern 85: when :s 86: 1 87: when :m 88: if str[1,1] == 'o' 89: # months 90: 3600*24*30 91: else 92: #minutes 93: 60 94: end 95: when :h 96: 3600 97: when :d 98: 3600*24 99: when :w 100: 3600*24*7 101: when :y 102: 3600*24*365 103: end 104: end