Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When UNTIL < DSTART then event never happens #371

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
When UNTIL < DSTART then event never happens
Google Calendar generate this kind of data when the end-user create
repeating events and then edit them in a specific, unknown way.

The new interpretation to consider that the event never happens if
its UNTIL is before its DSTART matches with the interpration of
Google Calendar (when subscribed via URL) and Apple Calendar.

Unfortunately not everyone agrees on that interpretation and
Thunderbird 45, MS Calendar 17, MS Outlook 2016 and Google Calendar
via file upload (not URL subscription) thinks that the event happens
only once.

In all RFCs 5545, 5546, 6868, 7529, 7953 and 7986, the single most
relevant part  is on [page 41 of RFC 5545
](https://tools.ietf.org/html/rfc5545#page-41):

> The UNTIL rule part defines a DATE or DATE-TIME value that bounds
> the recurrence rule in an inclusive manner.  If the value
> specified by UNTIL is synchronized with the specified recurrence,
> this DATE or DATE-TIME becomes the last instance of the
> recurrence.  The value of the UNTIL rule part MUST have the same
> value type as the "DTSTART" property.  Furthermore, if the
> "DTSTART" property is specified as a date with local time, then
> the UNTIL rule part MUST also be specified as a date with local
> time.  If the "DTSTART" property is specified as a date with UTC
> time or a date with local time and time zone reference, then the
> UNTIL rule part MUST be specified as a date with UTC time.  In the
> case of the "STANDARD" and "DAYLIGHT" sub-components the UNTIL
> rule part MUST always be specified as a date with UTC time.  If
> specified as a DATE-TIME value, then it MUST be specified in a UTC
> time format.  If not present, and the COUNT rule part is also not
> present, the "RRULE" is considered to repeat forever.

While the RFC clearly states what should happen when UNTIL == DSTART,
it says nothing about UNTIL < DSTART.

So it would seems reasonnable to resort to common sense and assume
that something cannot start after it ends, and thus this patch is
needed to have the most logical behavior.

Finally, historically speaking, this project introduced the previous
beahvior via https://github.com/fruux/sabre-vobject/pull/17 (more
specifically ca06d40), before the refactoring of `RecurrenceIterator`
into `RRuleIterator`. Unfortunately that PR does not give much
information about why the change was made. And the issue it refers
to is no longer accessible. So there is no argument to keep the
previous behavior.
PowerKiKi committed Dec 7, 2017
commit 0922c8c5cff0561f9ecdf6f6179c67c56c685719
12 changes: 0 additions & 12 deletions lib/Recur/RRuleIterator.php
Original file line number Diff line number Diff line change
@@ -733,18 +733,6 @@ protected function parseRRule($rrule) {

case 'UNTIL' :
$this->until = DateTimeParser::parse($value, $this->startDate->getTimezone());

// In some cases events are generated with an UNTIL=
// parameter before the actual start of the event.
//
// Not sure why this is happening. We assume that the
// intention was that the event only recurs once.
//
// So we are modifying the parameter so our code doesn't
// break.
if ($this->until < $this->startDate) {
$this->until = $this->startDate;
}
break;

case 'INTERVAL' :
4 changes: 1 addition & 3 deletions tests/VObject/Recur/RRuleIteratorTest.php
Original file line number Diff line number Diff line change
@@ -890,9 +890,7 @@ function testUntilBeforeDtStart() {
$this->parse(
'FREQ=DAILY;UNTIL=20140101T000000Z',
'2014-08-02 00:15:00',
[
'2014-08-02 00:15:00',
]
[]
);

}