class TellMeWhenever
Public Class Methods
parse(str)
click to toggle source
# File lib/tell_me_whenever.rb, line 8 def self.parse(str) str = str.downcase target = nil # figure out whether an exact date was used # match against months months = { "january" => 1, "february" => 2, "march" => 3, "april" => 4, "may" => 5, "june" => 6, "july" => 7, "august" => 8, "september" => 9, "october" => 10, "november" => 11, "december" => 12} targetMonth = 0 months.each do |key, value| if str.include? key then targetMonth = value end end # match against weekdays weekdays = { "monday" => 1, "tuesday" => 2, "wednesday" => 3, "thursday" => 4, "friday" => 5, "saturday" => 6, "sunday" => 7} targetWeekday = 0 weekdays.each do |key, value| if str.include? key then targetWeekday = value end end # match against date offset units = ["year", "month", "week", "day", "hour"] targetUnits = [] units.each do |unit| if str.include? unit then targetUnits.push unit end end if targetMonth != 0 then target = DateTime.now.beginning_of_day.change({ month: targetMonth, day: 1, hour: 9 }) # find out whether a specific day was specified str.scan(/\d+/).map(&:to_i).sort.reverse.each do |day| # is this date within this month? if target.end_of_month.day >= day target = target.change({day: day}) break end end elsif targetWeekday != 0 then target = DateTime.now.beginning_of_day.change({ hour: 9 }) # falls within this week or next week? if target.monday.next_day(targetWeekday - 1) < target then target = target.next_week.next_day(targetWeekday - 1).change({hour: 9}) else target = target.monday.next_day(targetWeekday - 1).change({hour: 9}) end elsif targetUnits.length > 0 then target = DateTime.now if(!targetUnits.include?("hour") && !targetUnits.include?("day")) then target = target.change({hour: 9}) end # try to find all applicable quantifiers in the str string targetUnits.each do |unit| magnitude = 1 first = str.slice(0, str.index(unit)).scan(/\d+/).map(&:to_i).reverse.first if first != nil then magnitude = first end # TODO flag special cases on magnitude limitations if unit == "year" then if magnitude > 100 then magnitude = 100 end target = target + magnitude.years elsif unit == "month" then if magnitude > 1200 then magnitude = 1200 end target = target + magnitude.months elsif unit == "week" then if magnitude > 63600 then magnitude = 63600 end target = target + magnitude.weeks elsif unit == "day" then if magnitude > 100000 then magnitude = 100000 end target = target + magnitude.days elsif unit == "hour" then if magnitude > 100000 then magnitude = 100000 end target = target + magnitude.hours end end elsif str.include?("tomorrow") then target = DateTime.now.beginning_of_day.change({ hour: 9 }) + 1.days end return target end