Caldav在时间范围查询中未返回事件

问题描述

我的Sabre中有一个iCalendar事件:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CalDAV Client//EN
BEGIN:VEVENT
UID:5e44cec8-33ed-4f24-82c7-f33483afa50d
DTSTART:20200805T080000Z
SUMMARY:summary
STATUS:CONFIRMED
TRANSP:OPAQUE
DURATION:PT30M
CATEGORIES:RESERVATION
DTSTAMP:20200716T211928Z
END:VEVENT
END:VCALENDAR

它从'2020-08-05T08:00:00.000Z'开始,持续30分钟,到'2020-08-05T08:30:00.000Z'结束。

如果我提交以下查询

<c:calendar-query xmlns:c="urn:ietf:params:xml:ns:caldav"
    xmlns:cs="http://calendarserver.org/ns/"
    xmlns:ca="http://apple.com/ns/ical/"
    xmlns:d="DAV:">
    <d:prop>
        <c:calendar-data />
    </d:prop>
    <c:filter>
        <c:comp-filter name="VCALENDAR">
            <c:comp-filter name="VEVENT">
                <c:time-range start="20200805T080000Z" end="20200805T180000Z"/>
            </c:comp-filter>
        </c:comp-filter>
    </c:filter>
    <c:timezone>GMT</c:timezone>
</c:calendar-query>

提到的事件被返回。但是,如果我仅将start=...移动start="20200805T080001Z"一秒钟,就像(start < DTSTART+DURATION AND end > DTSTART) 这样,它就不会返回。

根据9.9 or Caldav RFC 4791部分,应将其返回。上述部分的条件:

error[E0277]: a value of type `&std::vec::Vec<graphql::ContactContent>` cannot be built from an iterator over elements of type `_`
   --> src/graphql.rs:129:89
    |
129 |                 .and_then(|contact_contents| Ok(contact_contents.into_iter().map_into().collect()))
    |                                                                                         ^^^^^^^ value of type `&std::vec::Vec<graphql::ContactContent>` cannot be built from `std::iter::Iterator<Item=_>`
    |
    = help: the trait `std::iter::FromIterator<_>` is not implemented for `&std::vec::Vec<graphql::ContactContent>`

解决方法

我发现了这一点,我使用的是Mongo Backend而不是Sabre的PDO后端​​,而提到的Mongo Backend有一个错误,那就是PDO没有。

导致错误的代码段:

$endDate = clone $component->DTSTART->getDateTime();
$endDate->add(VObject\DateTimeParser::parse($component->DURATION->getValue()));
$lastOccurence = $endDate->getTimeStamp();

endDate是不可变的日期,因此需要重新分配endDate,以使add函数生效。

固定代码:

$endDate = clone $component->DTSTART->getDateTime();
$endDate = $endDate->add(VObject\DateTimeParser::parse($component->DURATION->getValue()));
$lastOccurence = $endDate->getTimeStamp();

您还可以在PDO后端​​here的github页面上看到正确实现的内容。