1

I'm looking into how to implement a human-friendly text representation of recurrence rules similar to the toText() and fromText() methods of rrule.js; however, I'd like to implement it in Python building on dateutil.rrule.

Testing such methods checking that they are each other's 'inverse', that is, calling one on the result of the other and checking that the result is equivalent to the original input. Which brings me to the question: what does it exactly mean for two rrule objects to be equivalent?

The latest version of dateutil.rrule, 2.6.0, does not appear to have an __eq__ method for the rrule class (see source code). Equivalence also does not seem to be as trivial as equivalence of all attributes, because sometimes a different freq parameter can still lead to the same recurrences. (For example, freq=DAILY and freq=WEEKLY leads to the same recurrence times if byweekday=FR is chosen; see screen grabs below from the rrule.js demo).

Does anyone know of an implementation of an equivalence relation for rrules? (It doesn't have to be in Python).

enter image description here

enter image description here

Kurt Peek
  • 52,165
  • 91
  • 301
  • 526

1 Answers1

1

Does anyone know of an implementation of an equivalence relation for rrules? (It doesn't have to be in Python).

No, because as far as I know it is not possible to have something reliable. For finite rules (with a COUNT or an UNTIL) you could compare their occurrence set - they would be "equivalent" if the two sets are identical. But you can't do that for infinite rules.

Your example: "freq=DAILY and freq=WEEKLY leads to the same recurrence times if byweekday=FR is chosen" is not always true and cannot be generalized. For example, change the frequency.

FREQ=DAILY;BYDAY=FR;INTERVAL=2
FREQ=WEEKLY;BYDAY=FR;INTERVAL=2

Or add more days to "byweekday" and combine with BYSETPOS.

FREQ=DAILY;BYDAY=MO,FR;BYSETPOS=-1
FREQ=WEEKLY;BYDAY=MO,FR;BYSETPOS=-1

And so on...

Testing such methods checking that they are each other's 'inverse', that is, calling one on the result of the other and checking that the result is equivalent to the original input.

So that being said, if your question is about testing, I think you are on the wrong track.

Just take a rule, generate text, parse text and compare the new object with the original one to make sure they are equals. Why would you need to bother about "equivalent"? There is no reason generating a text representation suddenly changes the frequency, is it?

Another approach is to test the two methods independently, and just admit that the "natural language" representation is fuzzy, and the two methods cannot be strictly inverse of each other. Take one data set of "rule => text version" and test the generation. Then take another data set of "text version => rule" and test the parser.

rlanvin
  • 6,057
  • 2
  • 18
  • 24
  • Indeed also in rrule.js, the `rrule` does not seem to be exactly reconstructable from its string representation as the latter omits the start time (the `dtstart` parameter). Perhaps it will suffice to implement only a "rule => text_version" conversion. – Kurt Peek Dec 05 '16 at 09:49