I've got a little problem, I need to be able to have a reoccurring event (forever) that marks the day after the second Tuesday of each month.
Your probably thinking, why not just Wednesday of each month.
October 2008 is an example, it starts on a Wednesday. :(
Really I just need it in Outlook, probably (but not limited to) some iCalendar format file.
The following iCalendar rule should work:
RRULE:FREQ=MONTHLY;BYDAY=WE;BYMONTHDAY=9,10,11,12,13,14,15
It should be read as "The first Wednesday of every month that falls on the 9th or later".
Edit: To use, create a calendar with a recurring event and export it to .ics. Open the ics file, find the existing RRULE, replace it with this one and import the ics back into outlook.
Related
For example, Foo Holiday is the 3rd Tuesday in March. Bar Holiday is the 7th minute of the 7th hour of the 7th day of the 7th Month.
I have looked at standards like ISO8601 but it seems those are more concerned with explicit points in time.
As AlexApps99 described in their answer,
there is no standard that will cover all holidays.
For example, the start of Ramadan often depends on physically sighting the new moon, so it's impossible to predict the exact date, as cloudy weather might prevent anybody from spotting it in your country for a few days.
However, for many repeating events the follow simpler rules (e.g. Foo & Bar Holiday in your question), there is
iCalendar's RRULE (Recurrence Rule),
which is a standard for creating repeating patterns for recurring events.
Many calendar apps will have a GUI for creating RRULE.
RRULE is documented in
RFC 5545 Section 3.8.5.3.
For example, an event for U.S. Presidential Election day would be:
Every 4 years, the first Tuesday after a Monday in November, forever (U.S. Presidential Election day):
DTSTART;TZID=America/New_York:19961105T090000
RRULE:FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8
Example taken from RFC 5545 Section 3.8.5.3 Page 129
Foo Holiday (3rd Tuesday in March) could be described with:
RRULE;FREQ=YEARLY;BYMONTH=3;BYDAY=TU;BYMONTHDAY=15,16,17,18,19,20,21
Bar Holiday could be described with (7th minute of the 7th hour of the 7th day of the 7th Month) could be described with:
RRULE;FREQ=YEARLY;BYMONTH=7;BYMONTHDAY==7;BYHOUR=7;BYMINUTE=7
Unfortunately, the iCalendar RRULE spec can't can't handle more complicated rules.
Easter can't be done, (although https://github.com/sappjw/calendars contains Easter RRULEs accurate for
1900-2099, and the Python dateutil library's RRULE has an unofficial extension called BYEASTER, but even then, it only supports Western Easter).
Non-Gregorian calendars are also not supported, however, there is a
draft spec RFC7529 that adds
RRULE support for additional calendars, which would allow you to describe
Chinese New Year using the following syntax:
DTSTART;VALUE=DATE:20130210
RRULE:RSCALE=CHINESE;FREQ=YEARLY
SUMMARY:Chinese New Year
These define a recurring event for the Chinese New Year, with the
first instance being the one in Gregorian year 2013.
Example taken from RFC7529#Section 4.3.1
There's no standard way to represent holidays, because holidays are pretty hard to keep track of. Each country has their own set of holidays, and there are different definitions for what is considered a holiday (public holidays, school holidays, religious holidays, international hotdog day etc).
On top of that, the days that holidays lie on is pretty hard to predict. Many holidays celebrating events on the non-Gregorian calendar, such as Easter, will be on a different date each year, and others based on external events can be unpredictable into the future.
Many holidays are not just "days", but a range multiple days, or specific hours of a day, and you can't forget that these intervals have timezones attached too (and will be different in different countries)
With all this complexity, you'll need to create your own way to represent these holidays, probably ignoring some of the complexity you don't need to handle.
If you're sharing this data, a standard format such as iCalendar would be ideal, and you could store custom properties of the holidays in extension fields (starting with X-).
If you're just storing this data internally, you're better off making your own structure to store whatever you need, perhaps using ISO8601 to store the intervals.
Problem
Some reoccurring events, that don't really end at some point (like club meetings?), depend on other conditions (like holiday season). However, manually adding these exceptions would be necessary every year, as the dates might differ.
Research
I have found out about exdate (see the image of "iCalendar components and their properties" on Wikipedia (2))
Also found some possible workaround: 'just writing a script to do process such events'. This would still mean I need to process a .ics manually and import it into my calendar, which implies some limitations:
can not be determined for all time spans (e.g. holidays not fixed for more than three years)
these events would probably be separate and not reoccurring/'grouped', which makes further edits harder
Question
Is there a way to specify recurring exceptions in iCal ?
To clarify, I have a recurring event and recurring exceptions.
So for instance I have a infinitely reoccurring weekly event, that depends on the month; where it might only take place if it's not e.g. January, August, or December.
Is there a way to use another event (/calendar) to filter events by boolean logic ?
If one could use a second event (or several) to plug into exdate this would solve the first problem and add some more possibilities.
note
if this question is too specific and the original problem could be solved by other means (other calendar-formats), feel free to comment/edit/answer
RFC2445 defines an EXRULE (exception rule) property. You can use that in addition to the RRULE to define recurring exceptions.
However, RFC2445 was superseded by RFC5545, which unfortunately deprecates the EXRULE property. So, client support is questionable.
As you already proposed, automatically adding EXDATE properties is a possible solution.
BYMONTH would be another possibility, e.g. here's a rule for a club meeting that occurs the first Wednesday of every month except December (which is their Christmas party, so no business meeting)
RRULE:FREQ=MONTHLY;BYDAY=1WE;BYMONTH=1,2,3,4,5,6,7,8,9,10,11
I'm currently working with the ical format and need to handle recurring events.
I'm working directly with Icloud and have managed to create and delete recurring events.
However, I encountered some problems when trying to update a single occurence of the said recurrence.
For example, let's say I have an event called 'test' scheduled every day for a week.
How should I proceed to rename the occurence of Tuesday to 'other title'? Or even change the dates for this particular occurrence ?
I tried to simply update the occurence by using it's ID but it seems to create a clone of it and not touch the real occurence. Moreover when trying to access the cloned event from the Icloud calendar interface it crashes.
So I'm a bit stuck and would appreciate some help :)
Thanks a lot,
It is not totally clear whether you are trying to update the occurence.
In any case, you should still have only one calendar resource but it should contain
one "master" VEVENT, containing the base information,along with the RRULE,
one VEVENT for each instance that is an "exception" to the base event, where each exception is identified by its RECURRENCE-ID.
RFC5545 does not have any example of such event but RFC5546 has something pretty close at https://www.rfc-editor.org/rfc/rfc5546#section-4.4.8 (using RDATE instead of RRULE and no need for the METHOD property but you get the idea).
Posting for future readers. For some reasons it's super hard to find a working example of RECURRENCE-ID
The following resource will repeat an event 'test' (10AM - 1PM UTC) everyday for 10 days starting on Jan 13th, 2021, EXCEPT on Jan 15th 2021, the event will be called 'test except me' and starts 3PM - 6PM UTC.
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:232392939239293293#hello.me
DTSTART:20210113T100000Z
DTEND:20210113T130000Z
SUMMARY:test
RRULE:FREQ=DAILY;INTERVAL=1;COUNT=10
END:VEVENT
BEGIN:VEVENT
UID:232392939239293293#hello.me
DTSTART:20210115T150000Z
DTEND:20210115T180000Z
SUMMARY:test except me
RECURRENCE-ID;VALUE=DATE-TIME:20210115T100000Z
END:VEVENT
END:VCALENDAR
Is there a way to express the following in iCalendar? (possibly using RRULEs?)
Between 9am and 5pm every day except Sundays when it is between 10am and 4pm.
Can I create multiple RRULEs? Which ones have precedence?
iCalendar does not have a notion of events with a hole in the middle of the duration. So even without talking about recurring event, you can not create with a single event something like from 9AM to 10AM and from 4PM to 5 PM
As a consequence, you need to actually create 3 events:
DTSTART:2013xxxxT090000
DURATION:PT1H
RRULE:FREQ=DAILY
DTSTART:2013xxxxT100000
DURATION:PT6H
RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR,SA
DTSTART:2013xxxxT160000
DURATION:PT1H
RRULE:FREQ=DAILY
As far as having multiple RRULE, this was supported in RFC2445 but it has been deprecated in RFC5545 (just like EXRULE) due to lack of support and complexity.
When giving the option for something to reoccur every certain amount of time how should I treat times that don't reoccur on every interval?
For example what should happen to birthday reminders for February 29th? Or if I have a monthly appointment on the 31st what should happen on months that do not have a 31st day?
What do you believe the reasonable user would expect and be least surprised by?
My first reaction to this question would be to give the user the option of what to do if it falls on that date (go to next day, skip the day, etc.).
But to directly answer your question, I believe the reasonable user would be least surprised by the occurrence falling on the day before the "skipped" day.
I'd think you would be able to flag dates like this pretty easily. The only dates I can think of are the 29th, 30th, and 31st of a month, or February 29th.
When the user opts to be reminded of one of these dates monthly (or annually for Feb. 29), you can prompt them for an alternate date for those months.
Additionally, you could have an option to be notified "on the last day of each month."
Ideally, prompt when creating the reminder.
If you are stuck with it, I would pull them forward. That's the least harmful choice. You don't always want the least surprise, minimizing the harm of making the wrong choice is also important.