Hello all,
at long long last I have finally finished the ICal recurrence rule engine. I had to travel to Haskell in back to figure out a way to do it I liked.
Features: - To my knowledge this is the most compliant implementation of Recurrence rules - Full support for Exclusion dates and exclusion rules (!) - Minimal dependency on external libraries
If you look at the implementation you will notice it uses LazyList's to do it's work, which may make it seem a bit complicated. But this allows me to trivially add additional list mutations after-the-fact. For example, exclusion rules (i.e. all the logic of recurrence rules, but "differenced" to the rules to generate exceptions) were actually added in about 15 minutes. I know of no other implementations that have them at all.
The other advantage of the LazyList approach is that no more dates are calculated then needed (well, actually one extra per rule may be if needed for the stop test), but the set is none-the-less infinite.
The can be downloaded via Monticello as part of the iCalendar project with:
MCHttpRepository location: 'http://www.squeaksource.com/ical' user: '' password: ''
Thanks, and let me know if you see any problems with it. Jason
_________________________________________________________________ More photos, more messages, more storageget 2GB with Windows Live Hotmail. http://imagine-windowslive.com/hotmail/?locale=en-us&ocid=TXT_TAGHM_migr...
<JJ (Jason)> Features: - To my knowledge this is the most compliant implementation of Recurrence rules - Full support for Exclusion dates and exclusion rules (!) </JJ (Jason)>
The next release of Chronos will have full support for recurrence rules based on the iCal rule model--including exclusion dates and exclusion rules.
The implementation is based on a recurrence rule algebra, so that recurrence rules can be specified using algegraic expressions, which are then evaluated according to a recurrence rule algebra.
Example:
(RecurrenceSet from: (2007 month: #February day: 9)) add: (RecurrenceRule delta: 1 years count: 10 temporalExpression: ((WeekOfMonth week: 0) & (#Sunday asDayOfWeek | #Saturday asDayOfWeek) not) occurrenceIndices: #(0)); "Chronos uses 0 as the ordinal of the last value or element." do: [:each | Transcript cr; show: each % #rfc2822]
The iCal expression that specifies the same thing:
DTSTART;TZID=America/Los_Angeles:2007-02-09 RRULE:FREQ=YEARLY;COUNT=10;BYDAY=-1MO,-1TU,-1WE,-1TH,-1FR;BYSETPOS=-1
The output:
Wed, 28 Feb 2007 Fri, 29 Feb 2008 Fri, 27 Feb 2009 Fri, 26 Feb 2010 Mon, 28 Feb 2011 Wed, 29 Feb 2012 Thu, 28 Feb 2013 Fri, 28 Feb 2014 Fri, 27 Feb 2015 Mon, 29 Feb 2016
--Alan
squeak-dev@lists.squeakfoundation.org