np_notify_rrule — Syntax reference
np_notify_rrule is parsed by recpyx next_occurrence().
It accepts English expressions (canonical grammar) and French expressions (auto-normalised to English before parsing).
Timezone suffix is supported with values such as in Europe/Paris.
Grammaire BNF complète des expressions acceptées par next_occurrence
Grammaire BNF complète des expressions acceptées par next_occurrence
1) Lexique
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<yyyy> ::= <digit><digit><digit><digit>
<mm> ::= <digit><digit>
<dd> ::= <digit><digit>
<hh> ::= <digit> | <digit><digit>
<min2> ::= <digit><digit>
<date> ::= <yyyy> "-" <mm> "-" <dd>
<month-day> ::= <mm> "-" <dd>
<time24> ::= <hh> ":" <min2>
<time12> ::= <hh> [":" <min2>] ("am" | "pm")
<time> ::= <time24> | <time12>
<timezone> ::= <tz-token> "/" <tz-token>
<tz-token> ::= letter { letter | "_" }
<int> ::= <digit> { <digit> }
<weekday> ::= "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday"
<weekday-list> ::= <weekday> { ("and" | ",") <weekday> }
<month-name> ::= "january" | "february" | "march" | "april" | "may" | "june" |
"july" | "august" | "september" | "october" | "november" | "december"
<ordinal> ::= "first" | "second" | "third" | "fourth" | "fifth" | "last"
<monthday> ::= ("1".."31") ["st" | "nd" | "rd" | "th"]
<monthday-list> ::= <monthday> { ("and" | ",") <monthday> }
<time-list> ::= <time> { ("and" | ",") <time> }
2) Grammaire de haut niveau
<schedule> ::= <rule-list> [<tz-suffix>]
<rule-list> ::= <rule> { ", and" <rule> }
<tz-suffix> ::= " in " <timezone>
<rule> ::= <base-rule> { <suffix-clause> }
<suffix-clause> ::= <date-window> | <until-window> | <except-clause> | <weekend-shift>
3) Règles de base
<base-rule> ::= <oneshot>
| <every-day>
| <every-weekday>
| <every-weekday-list>
| <every-n-units>
| <hourly-between>
| <step-within-day>
| <monthly-rule>
| <yearly-date>
| <yearly-nth-weekday>
<oneshot> ::= <date> " at " <time>
<every-day> ::= "every day at " <time-list>
<every-weekday> ::= "every weekday at " <time-list>
<every-weekday-list> ::= "every " <weekday-list> " at " <time-list>
<every-n-units> ::= "every " <int> " " <unit> [" on " <weekday-list>] [" at " <time-list>]
<unit> ::= "minutes" | "hours" | "days" | "weeks"
<hourly-between> ::= "every hour between " <time> " and " <time>
| "every " <int> " hours between " <time> " and " <time>
<step-within-day> ::= "every " <day-scope> " every " <int> " " <step-unit>
" between " <time> " and " <time>
<day-scope> ::= "day" | "weekday"
<step-unit> ::= "hours" | "minutes"
<monthly-rule> ::= "every month on the " <monthly-selector> " at " <time>
<monthly-selector> ::= "last day"
| <monthday-list>
| <ordinal> " " <weekday>
<yearly-date> ::= "every year on " <month-day> " at " <time>
<yearly-nth-weekday> ::= "every year on the " <ordinal> " " <weekday>
" of " <month-name> " at " <time>
4) Suffixes (ordre libre)
<date-window> ::= " between " <date> " and " <date>
<until-window> ::= " until " <date>
<except-clause> ::= " except " <except-item-list>
<except-item-list> ::= <except-item> { ("," | " ") <except-item> }
<except-item> ::= <weekday>
| <date>
| "public holidays"
| "on public holidays"
<weekend-shift> ::= " if weekend then next monday"
| " if weekend then next business day"
Exemples exhaustifs par cas de la grammaire
A) One-shot date/time
2026-01-15 at 09:00
2026-12-31 at 11:45pm
B) Every day
every day at 09:00
every day at 09:00 and 17:00
C) Every weekday
every weekday at 09:00
every weekday at 9am and 5pm
D) Named weekday list
every monday and wednesday at 08:30
every tuesday, thursday and friday at 14:00
E) Every N units
every 15 minutes
every 2 hours
every 2 weeks on monday at 08:30
F) Hourly between
every hour between 09:00 and 17:00
every 2 hours between 08:00 and 20:00
G) Step within day
every day every 2 hours between 08:00 and 20:00
every weekday every 30 minutes between 09:00 and 18:00
H) Monthly patterns
every month on the 1st and 15th at 09:00
every month on the last day at 18:00
every month on the first monday at 10:00
I) Yearly fixed date
every year on 07-14 at 09:00
every year on 12-31 at 23:30
J) Yearly nth weekday
every year on the first monday of september at 09:00
every year on the last friday of november at 18:00
K) Date windows / until
every day at 09:00 between 2026-01-01 and 2026-03-31
every weekday at 09:00 until 2026-12-31
L) Exceptions
every weekday at 09:00 except monday
every day at 09:00 except 2026-08-15
every day at 09:00 except public holidays
every day at 09:00 except on public holidays
M) Weekend shifts
every month on the 1st at 09:00 if weekend then next monday
every year on 01-01 at 09:00 if weekend then next business day
N) Multi-rule schedule and timezone suffix
every weekday at 09:00, and every month on the last friday at 18:00
every day at 09:00, and every day at 17:00 in Europe/Paris
Équivalents français (normalisés automatiquement)
Ces formulations françaises sont acceptées, puis normalisées en anglais en interne avant parsing.
tous les jours à 09:00
tous les jours ouvrés à 09:00 et 17:00
toutes les 2 semaines le lundi à 08:30
chaque mois le dernier vendredi à 18:00
tous les jours à 09:00 en Europe/Paris
tous les jours à 09:00 sauf jours fériés
tous les jours à 09:00 sauf le lundi
tous les jours à 09:00 jusqu'au 2026-12-31
Example library (ready to copy/paste)
1) Daily basics
every day at 09:00
every day at 08:00 and 18:00
every day at 07:30 and 12:00 and 20:30
every day at 6am
every day at 8:15pm
tous les jours à 09:00
tous les jours à 08:00 et 18:00
2) Weekdays vs named weekdays
every weekday at 09:00
every weekday at 09:00 and 17:00
every monday and wednesday and friday at 08:30
every tuesday and thursday at 10:00
every saturday and sunday at 11:00
tous les jours ouvrés à 09:00
tous les lundis, mercredis et vendredis à 08:30
3) Every N minutes/hours/days/weeks
every 15 minutes
every 30 minutes
every 2 hours
every 4 hours at 09:00
every 2 days at 08:00
every 2 weeks on monday at 08:30
every 3 weeks on tuesday and thursday at 14:00
toutes les 2 semaines le lundi à 08:30
4) Hourly between
every hour between 09:00 and 17:00
every hour between 8am and 6pm
every 2 hours between 08:00 and 20:00
every 3 hours between 00:00 and 23:00
every hour between 06:30 and 22:30
toutes les heures entre 09:00 et 17:00
5) Step within day
every day every 2 hours between 08:00 and 20:00
every day every 30 minutes between 09:00 and 12:00
every weekday every 60 minutes between 09:00 and 18:00
every weekday every 15 minutes between 08:30 and 10:00
every weekday every 2 hours between 10:00 and 16:00
tous les jours ouvrés toutes les 30 minutes entre 09:00 et 18:00
6) Monthly patterns
every month on the 1st at 09:00
every month on the 1st and 15th at 09:00
every month on the last day at 18:00
every month on the first monday at 10:00
every month on the last friday at 18:00
every month on the 5th, 10th and 20th at 07:45
chaque mois le premier lundi à 10:00
chaque mois le dernier vendredi à 18:00
7) Yearly patterns
every year on 01-01 at 09:00
every year on 07-14 at 09:00
every year on 12-31 at 23:30
every year on the first monday of september at 09:00
every year on the last friday of november at 18:00
every year on the third thursday of june at 14:00
chaque année le 14-07 à 09:00
8) Date windows / until
every day at 09:00 between 2026-01-01 and 2026-01-31
every weekday at 09:00 between 2026-02-01 and 2026-06-30
every 2 weeks on monday at 08:30 between 2026-01-01 and 2026-12-31
every month on the last friday at 18:00 until 2027-12-31
every day every 2 hours between 08:00 and 20:00 until 2026-09-30
tous les jours à 09:00 jusqu'au 2026-12-31
9) Exceptions
every day at 09:00 except monday
every weekday at 09:00 except friday
every day at 09:00 except 2026-08-15
every day at 09:00 except 2026-08-15, 2026-08-16
every day at 09:00 except public holidays
every day at 09:00 except on public holidays
tous les jours à 09:00 sauf le lundi
tous les jours à 09:00 sauf jours fériés
10) Weekend shift
every month on the 1st at 09:00 if weekend then next monday
every month on the last day at 09:00 if weekend then next monday
every year on 01-01 at 09:00 if weekend then next business day
every year on 12-31 at 18:00 if weekend then next business day
every month on the first monday at 09:00 if weekend then next business day
chaque mois le 1er à 09:00 si week-end alors lundi suivant
11) Time formats
every day at 09:00
every day at 9:00
every day at 9am
every day at 9:30am
every day at 5pm
every day at 11:45pm
every weekday at 9am and 5pm
12) Multi-rule schedules with ", and"
every weekday at 09:00, and every month on the last friday at 18:00
every day at 09:00, and every day at 17:00
every 2 weeks on monday at 08:30, and every year on 12-31 at 18:00
every day at 09:00 except public holidays, and every month on the 1st at 08:00
every weekday at 09:00 until 2026-12-31, and every year on 01-01 at 09:00
tous les jours à 09:00, and every month on the last day at 18:00
13) Timezones
every day at 09:00 in Europe/Paris
every weekday at 09:00 and 17:00 in Europe/Paris
every day at 09:00 in America/New_York
every month on the last friday at 18:00 in America/New_York
every day at 09:00 in Asia/Manila
every year on 12-31 at 23:30 in Asia/Manila
Quick start
every day at 09:00— one reminder every day at 09:00.every weekday at 09:00 and 17:00— two reminders on business days.every 2 weeks on monday at 08:30— bi-weekly reminder on Monday morning.every month on the last friday at 18:00— month-end close reminder.every day at 09:00 in Europe/Paris— explicit timezone schedule.
Common errors
- Wrong pluralisation: use
every day, notevery days. - Missing "at": use
every weekday at 09:00 and 17:00. - Wrong timezone format: use IANA zones like
Europe/Paris, notUTC+1. - Multi-rule separator: use
, andbetween rules. - Mixed FR/EN tokens: avoid mixed forms like
tous les jours at 09:00; use eithertous les jours à 09:00orevery day at 09:00.