iCalendar (RFC5545) recurrence rule multiple times a day - icalendar

How can I make an event occur multiple times a day using the RRULE specified in RFC5545?
Lets say I would like an event to happen every other week on Monday and Friday at 11AM and 18PM. Is it possible to format the RRULE like something as the following:
RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,FR;[TIMES=110000,180000]
Thanks

you have to use the byhour
The BYHOUR rule part specifies a COMMA-
separated list of hours of the day. Valid values are 0 to 23.
so that would be :
RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,FR;BYHOUR=11,18

Related

Is it possible to have an OR expression in a iCalendar RFC5545 recurrence rule?

I'm currently using iCalendar specification (RFC 5545) to deal with recurring events.
Until yesterday, their recurrence rules covered all my needs, but now I'm having a hard time implementing the following rule:
Every month on the first Monday OR Wednesday of the month.
Ex:
2021-05-01 is Saturday: the event will happen on Monday 2021-05-03.
2021-06-01 is Tuesday: the event will happen on Wednesday 2021-06-02.
2021-07-01 is Thursday: the event will happen on Monday 2021-07-05.
2021-08-01 is Sunday: the event will happen on Monday 2021-08-02.
Is there a way to define this kind of "conditional" rule?
If I understand the requirement correctly, it is not exactly conditional. It is that ONLY the first of the first Monday and first Wednesday is required. BYSETPOS is aimed at this.
In this example, it is being used to calculate the last working day https://icalevents.com/2555-paydays-last-working-days-and-why-bysetpos-is-useful/
For your example
RRULE:FREQ=MONTHLY;BYDAY=1MO,1WE;BYSETPOS=1
should do the trick,
Basically the RRULE will expand out all the first MONDAY and WEDNESDAYs and then 'contract' ie take the first date of each pair.
Page 43 of the specification https://www.ietf.org/rfc/rfc5545.txt shows the priorities of the 'expansions' and 'contractions'.

ICalendar recurring event starts first day of month, ends last day of month, repeats every month

Using rfc5545 is there a way to represent an event that starts on the first day of each month and ends on the last day of each month and repeats every month?
It's slightly different than a daily repeating event which is not ideal for my use case.
short answer: No
This is driven by the fact that the RFC5545 clearly states that an event cannot have a month duration, only days, weeks or seconds.
3.3.6. Duration
[...] Note that unlike
[ISO.8601.2004], this value type doesn't support the "Y" and "M"
designators to specify durations in terms of years and months.
(emphasis mine)

How can I exclude DTSTART from generated events if its day not among days specified by BYDAY?

I'm using google-rfc-2445 to generate repeating events according to according to rfc-2445:
The "DTSTART" property for a "VEVENT" specifies the inclusive start of
the event. For recurring events, it also specifies the very first
instance in the recurrence set.
So, for example RRULE for event which occures every Friday 5 times:
DTSTART;TZID=US-Eastern:20160204T090000
RRULE:FREQ=WEEKLY;COUNT=5;BYDAY=FR;INTERVAL=1;
So according to rfc-2445 it will generate 6 events. First event on Thursday 4 February 2016, second event on Friday 5 February 2016, and so on.
How can I achieve that it will exclude first event if it isn't in a pattern? In the example above it should exclude first occurrence, 4 February 2016. In case of defining DTSTART;TZID=US-Eastern:20160205T090000 which is Friday it should leave first occurrence.
Can it be done by defining such "exclusion rule" in RRULE itself or I need to make a check in a code and if DTSTART isn't the same day as defined in BYDAY I should look for closest date in code (manually) and change DTSTART accordingly?
UPDATE
Ok, according to rfc-2445 and this question on google group: https://groups.google.com/forum/#!topic/google-rfc-2445/xqYFe411ysA
The "EXDATE" property can be used to exclude the value specified in
"DTSTART". However, in such cases the original "DTSTART" date MUST
still be maintained by the calendaring and scheduling system because
the original "DTSTART" value has inherent usage dependencies by other
properties such as the "RECURRENCE-ID".
it looks that I need to use EXDATE property to achieve what do I need. Trying to achieve this by following RRULE:
EXDATE;TZID=Asia/Jerusalem:20160210T000000
RRULE:FREQ=WEEKLY;COUNT=5;BYDAY=WE;INTERVAL=1;
And start date is: 2016-02-10T00:00:00.000+02:00 in the following code:
DateTimeIterable dti = DateTimeIteratorFactory.createDateTimeIterable(RRULE, DTSTART, dateTimeZone, true);
But it returns only 4 events, so it always remove first event.
From the description of the problem you give, you will get 6 events when DTSTART is added and you would not want it to be part of the list of instances and 5 events when it is a good date.
So what you want is to only get the last 5 events, which is possible by using the BYSETPOS in your RRULE, the following should do the trick:
BYSETPOS=-5,-4,-3,-2,-1
which will return in all cases the last 5 events that your RRULE gives regardless if the DTSTART is matching the pattern of your RRULE or not.

Cron Expression: What exactly is the difference between ? and * in a cron expression?

It appears to me that both mean "any of the available values". What exactly in the difference between them?
* means every possible value in the field. ? means you don't care about the value. It's used when you have two fields that may contradict each other. The common example being the day of month and day of week fields. Consider, for example a cron specification for running at 10AM on the first day of every month:
0 0 10 1 * ? *
Now let's break it down:
Seconds: 0 - we want it to run on 10:00:00
Minutes: 0 - we want it to run on 10:00:00
Hours: 10 - we want it to run on 10:00:00
Day of month: 1 - we want it to run of the 1st of every month
Month: * - we want it to run on every month (e.g., January 1st, February 1st, etc.)
Day of week: ? - we don't care about the day of week. The cron should run on the 1st of every month, regardless of whether it's a Sunday, a Monday, etc.
Year: * - we want it to run on every year
From Quartz Scheduler
* ("all values") - used to select all values within a field. For example, "*" in the minute field means "every minute".
? ("no specific value") - useful when you need to specify something in
one of the two fields in which the character is allowed, but not the
other. For example, if I want my trigger to fire on a particular day
of the month (say, the 10th), but don't care what day of the week that
happens to be, I would put "10" in the day-of-month field, and "?" in
the day-of-week field. See the examples below for clarification.
The * character is used to specify all values. For example, "*" in the minute field means " every minute ".
The ? character is allowed for the day-of-month and day-of-week fields. It is used to specify 'no specific value'. This is useful when you need to specify something in one of the two fields, but not the other. See the examples below for clarification.
You can look more here:
http://docs.netkernel.org/book/view/book:mod:cron/doc:mod:cron:cronexpression
Also if you need to create a Cron expression you can use this: http://www.cronmaker.com/
* means every time. According to the position, it will be:
every second, minute, hour, day, month.
? means that it would be
chosen by other field. So ? doesn't add filter, but it
wouldn't run every time.
? is used for setting the day, as it might be a day of month or the day of week. So if you choose the day of month (like the 1-st day of month), than you put ? in the day of week, by which you show, that it would be not every day of week, but only those days which are allowed by other conditions. And vice versa, if you set day of week, you put ? in the day of month.

single icalendar rule for 1st weekday of multiple months every year?

Is it possible to specify an event to occur on the 1st weekday of multiple months every year in a single RRULE? Using January and June as a test case, my initial attempt was:
FREQ=YEARLY;BYDAY=MO,TU,WE,TH,FR;BYMONTH=1,6;BYSETPOS=1
but BYSETPOS reduces the set down to January only. I think splitting it out into multiple rrules would work, but it would greatly increase the complexity of this area of my app so I was hoping for one rrule with a yearly freq.
Thanks!
You could try:
FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1;BYMONTH=<SELECTED_MONTHS_FROM_UI>
Please note the order of options is different.