From: Joel VanderWerf Date: 2004-03-19T04:06:39+09:00 Subject: Re: Thinking about a date-matching algorithm... Hal Fulton wrote: > I did a little swapping of ideas with dblack on this. Now I'm > opening discussion to anyone interested. > > I'm writing a little to-do manager (chiefly for my own use). > > I want to allow recurring tasks. Some of these will be simple, like > "Every Monday." Others will be more complex, like "Every 2nd and 4th > Friday." Some might not even be based on weeks or months at all, but > might be like: "Every ten days, no matter what." > > There'd also be an option to give advance warning (N days) on each > event. > > So the question becomes: Given a date (typically "today") and a list > of recurring tasks, how do I determine which ones need to be displayed? What about using regexps? You can look at this whole problem as making queries against time-points expressed in several equivalent coordinate systems, such as: (day of week, ordinal of day in month, month of year) (day of month, month of year) (day of week, week of year) (day of year) Now, if you don't mind translating your given data into these coordinate systems, expressed as a string, then the query can be expressed as a regex, or a logical combination of regexes. For example, require 'date' today = Date.today def ord(x); (x-1)/7+1; end def coords(date) [ "day-ordinal-month: %d, %d, %d" % [date.wday, ord(date.mday), date.mon], "day-month: %d, %d" % [date.mday, date.mon], "day-week: %d, %d" % [date.wday, date.cweek], "day of year: %d" % date.yday, "Julian day: %d" % date.jd, "year: %d" % date.year ].join("; ") end coords = coords(today) p coords every_thurs = /day-week: 4/ puts "It's Thursday again." if coords =~ every_thurs first_or_third_thurs = /day-ordinal-month: 4, (1|3)/ puts "It's the 1st or 3rd Thursday again." if coords =~ first_or_third_thurs # Ok, so regexes can't handle everything: tenth_day = proc {|d| d[/Julian day: (\d+)/, 1] % 10 == Date.new(2004,1,8).jd % 10} puts "It's a multiple of ten days since 8 Jan 2004" if tenth_day