django-scheduler icon indicating copy to clipboard operation
django-scheduler copied to clipboard

RRule Examples

Open aubricus opened this issue 6 years ago • 9 comments

Learning python dateutil rrule and how it applies to the params field in events is a bit daunting.

Any chance you can post here some common examples?

Possible Simple Rules:

  • Event repeats Monthly
  • Event repeats Weekly
  • Event repeats Daily
  • Event repeats Hourly

Possible more complex examples:

  • Event repeats weekdays (M,T,W,T,F)
  • Event repeats 3x a day on Monday and Wednesday

Thoughts?

aubricus avatar Jun 08 '18 00:06 aubricus

I'd even take some links to unit tests! :)

aubricus avatar Jun 08 '18 00:06 aubricus

This section of the dateutil docs is semi-helpful:

http://dateutil.readthedocs.io/en/stable/rrule.html#rrule-examples

aubricus avatar Jun 08 '18 00:06 aubricus

You can add general rrule params in the params field separated by semicolons in the format:

interval:2; count:2;

lggwettmann avatar Jun 16 '18 17:06 lggwettmann

Thanks @lggwettmann

I was thinking it would be helpful to post some examples of commonly used rules and how to configure them (since there are no defaults) without needing a complete understanding of python date rrules.

Even a link in the docs models section to this bit would be helpful: https://github.com/llazzaro/django-scheduler/blob/develop/schedule/models/rules.py#L23-L50

This is getting into the territory of "I should probably submit a PR". If I have time I'll try to put something together.

aubricus avatar Jul 03 '18 22:07 aubricus

Hallo guys

is there some reason why to not use dateutil.rrule.rrulestr for parsing rule params? for example i want repeat rule on first Monday every month, can i achieve this in scheduler Rule params?

with rrulestr i can do:

In [32]: from dateutil.rrule import rrulestr
In [33]: from datetime import datetime
In [34]: rr = rrulestr("FREQ=MONTHLY;BYDAY=+1MO")
In [35]: now = datetime.now()
In [36]: now
Out[36]: datetime.datetime(2018, 11, 8, 12, 12, 42, 579411)
In [37]: rr.after(now)
Out[37]: datetime.datetime(2018, 12, 3, 12, 12, 34)

tyctor avatar Nov 08 '18 01:11 tyctor

i have looked into code probably only get_rrule_object method of Event model is enough to rewrite this is working for me:

def get_rrule_object(self, tzinfo):
    if self.rule is None:
        return
    params = ['FREQ={}'.format(self.rule.frequency)]
    if self.rule.params:
        params.append(self.rule.params)

    if timezone.is_naive(self.start):
        dtstart = self.start
    else:
        dtstart = tzinfo.normalize(self.start).replace(tzinfo=None)

    if self.end_recurring_period is None:
        until = None
    elif timezone.is_naive(self.end_recurring_period):
        until = self.end_recurring_period
    else:
        until = tzinfo.normalize(
            self.end_recurring_period.astimezone(tzinfo)).replace(tzinfo=None)
    if until:
        until = until.strftime('UNTIL=%Y%m%dT%H%M%S')
        params.append(until)
    rule = ';'.join(params)
    return rrulestr(rule, dtstart=dtstart)

tyctor avatar Nov 08 '18 04:11 tyctor

Here are some examples: [ { "model": ".rule", "pk": 2, "fields": { "name": "Weekly", "description": "Weekly", "frequency": "WEEKLY", "params": " " } }, { "model": ".rule", "pk": 3, "fields": { "name": "Monthly", "description": "Monthly", "frequency": "MONTHLY", "params": " " } }, { "model": ".rule", "pk": 4, "fields": { "name": "Every 2 weeks", "description": "Every 2 weeks", "frequency": "WEEKLY", "params": "INTERVAL:2" } }, { "model": ".rule", "pk": 5, "fields": { "name": "Every weekday", "description": "Every weekday", "frequency": "DAILY", "params": "BYWEEKDAY:0,1,2,3,4" } }, { "model": ".rule", "pk": 6, "fields": { "name": "Every Saturday", "description": "Every Saturday", "frequency": "DAILY", "params": "BYWEEKDAY:SA" } }, { "model": ".rule", "pk": 7, "fields": { "name": "Every Sunday", "description": "Every Sunday", "frequency": "DAILY", "params": "BYWEEKDAY:SU" } }, { "model": ".rule", "pk": 8, "fields": { "name": "Quarterly", "description": "Quarterly", "frequency": "MONTHLY", "params": "INTERVAL:3" } }, { "model": ".rule", "pk": 10, "fields": { "name": "Daily", "description": "Daily", "frequency": "DAILY", "params": " " } } ]

ricosalomar avatar Feb 18 '20 13:02 ricosalomar

I wish @tyctor 's code can be merged, otherwise, special days can be a bit tricky. For the following yearly params:

Martin Luther King Jr. Day (Third Monday of the January): bymonth:1;byweekday:MO;bysetpos:3 US President Day (Third Monday of the February): bymonth:2;byweekday:MO;bysetpos:3 Good Friday (Friday before Easter): byeaster:-2 Easter day (first Sunday after the full Moon that occurs on or after the spring equinox): byeaster:0 Mothers day(2nd Sunday in May): bymonth:5;byweekday:SU;bysetpos:2 US Father's day(3rd Sunday in Jun): bymonth:6;byweekday:SU;bysetpos:3 Columbus Day(the second Monday of October): bymonth:10;byweekday:MO;bysetpos:2 US Memorial day (Last Monday of May) : bymonth:5;byweekday:MO;bysetpos:-1 US Labor day (1st Monday of September): bymonth:9;byweekday:MO;bysetpos:1 US Thanksgiving (4th Thursday in November): bymonth:11;byweekday:TH;bysetpos:4

Now could anyone try Juneteenth? (June 19th each year, also observed on the closest weekday if it lands on a weekend )

xjlin0 avatar Sep 30 '22 15:09 xjlin0

Please provide a PR and I will be happy to merge this.

llazzaro avatar Oct 26 '22 22:10 llazzaro