obsidian-tasks
obsidian-tasks copied to clipboard
Recurrence '🔁 every 4 weeks on Sunday when done' recurs as '1st Sunday after completion date', if the reference date is not Sunday
Expected Behavior
The following line is recognised by the edit Task dialog as having a recurring pattern of '🔁 every 4 weeks on Sunday when done', as expected from the text.
- [ ] Export Cloud Outlook data 🔁 every 4 weeks on Sunday when done 📅 2022-04-10
When I mark it as complete on Tuesday 19th April, I expect it to be re-scheduled for the 4th Sunday after Tuesday 19th April which is Sunday 15th May
Expected behaviour when completed on Tuesday 19th April:
- [ ] Export Cloud Outlook data 🔁 every 4 weeks on Sunday when done 📅 2022-05-15
- [x] Export Cloud Outlook data 🔁 every 4 weeks on Sunday when done 📅 2022-04-10 ✅ 2022-04-19
Current Behavior
- [ ] Export Cloud Outlook data 🔁 every 4 weeks on Sunday when done 📅 2022-04-10
However, when I mark it as complete on Tuesday 19th April, the result is:
Actual behaviour when completed on Tuesday 19th April
- [ ] Export Cloud Outlook data 🔁 every 4 weeks on Sunday when done 📅 2022-04-24
- [x] Export Cloud Outlook data 🔁 every 4 weeks on Sunday when done 📅 2022-04-10 ✅ 2022-04-19
That is, it seems to have picked the next Sunday, rather than the 4th Sunday.
Steps to Reproduce
- Create this task
- [ ] Export Cloud Outlook data 🔁 every 4 weeks on Sunday when done 📅 2022-04-10
-
Mark it is complete
-
Make sure that the completion date of the new task is at least 4 weeks away.
Context (Environment)
- Obsidian version: 0.14.6
- Tasks version: 1.5.1 - vanilla, none of my modifications
- [x] I have tried it with all other plugins disabled and the error still occurs
Possible Solution
None yet, but here's some more research...
Other observations
This one works:
- [ ] Export Cloud Outlook data 🔁 every 4 weeks on Sunday 📅 2022-04-10
... becoming the 4th Sunday after the previous due date...
- [ ] Export Cloud Outlook data 🔁 every 4 weeks on Sunday 📅 2022-05-08
- [x] Export Cloud Outlook data 🔁 every 4 weeks on Sunday 📅 2022-04-10 ✅ 2022-04-19
As does this:
- [ ] Export Cloud Outlook data 🔁 every 4 weeks when done 📅 2022-04-10
becoming 4 weeks after it was marked as complete...
- [ ] Export Cloud Outlook data 🔁 every 4 weeks when done 📅 2022-05-17
- [x] Export Cloud Outlook data 🔁 every 4 weeks when done 📅 2022-04-10 ✅ 2022-04-19
Trying it at https://jakubroztocil.github.io/rrule/, it could be the case that rrule is ignoring dtstart? If I set it manually (see second screenshot), it works as expected. Maybe we need to better set dtstart within our code? :thinking:

Thanks!
Trying it at https://jakubroztocil.github.io/rrule/
When I first read your reply on my phone, I was all "cool, we should document that site...". Having seen the screenshots and tried it out, I'm not so sure. I think the learning curve is probably too high for it to be useful to users...
Maybe we need to better set dtstart within our code?
I don't (yet) understand that, but it does sound intriguing. Will do some reading about rrule at some point.
To be honest, I assume it's a bug in the rrule implementation where we cannot do anything about it, but I still have a tiny bit of hope :sweat_smile:
Repro'd the issue starting this thread on current stable Obsidian and tasks. I then explored the tasks in the developer console and found the following:
rrule.options.dtstartis set totodayfor both tasks. i.e. it was not unset like in the screenshot above. The interpretation problem happens whentodayis not a Sunday.rrule.after(dateparam, inclusive)seems to have a selective acceptance of that first argument with the date that the recurrence should be after. Ifdateparamis before dtstart,dateparamis ignored entirely and the next Sunday after dtstart is used. Ifdateparamis after dtstart but before the next Sunday, result is still the next Sunday, not 4 weeks out. Ifdateparamis after the next Sunday (after timezone conversion) but anywhere within the next 4 weeks, then the answer is always the Sunday 4 weeks after the next Sunday. In other words, I thinkrrule.afterjust figures out which of the already-defined-based-on-dtstart 4-week rangesdateparamis in and then returns that.- Possible work-around: if a recurrence is "basedOnToday" (aka "when done"), make the argument to
rrule.afterbe 6 or 7 days in the future so that it falls into the next 4-week range rather than the one that ends this Sunday. This seems super annoying to generalize to otherrrule.freqparameters, though (monthly, yearly, daily, ....). Maybe we can use the result ofafterwith the second argument set to true as thedateparamin our actualafter(dateparam, false)calculation?
I've just had another example of this.
- [x] Download bank statements 🔁 every 3 months on the last Friday ⏳ 2022-04-29 ✅ 2022-04-29
- [x] Download bank statements 🔁 every 3 months on the last Friday ⏳ 2022-08-12 ✅ 2022-08-06
- [x] Download bank statements 🔁 every 3 months on the last Friday ⏳ 2022-11-25 ✅ 2022-11-16
- [x] Download bank statements 🔁 every 3 months on the last Friday ⏳ 2023-02-24 ✅ 2023-06-24
- [x] Download bank statements 🔁 every 3 months on the last Friday ⏳ 2023-05-26 ✅ 2023-06-24
- [x] Download bank statements 🔁 every 3 months on the last Friday when done ⏳ 2023-08-25 ✅ 2024-02-11
- [ ] Download bank statements 🔁 every 3 months on the last Friday when done ⏳ 2024-02-23
Note how before I added when done the every 3 months bit was working.
But once I added when done, it's now picked the last Friday in this month.