Skip to content

Commit 5b5ff47

Browse files
tobixenclaude
andcommitted
fix: VTODO with only CREATED should match any range where end > CREATED
RFC4791 section 9.9 states that for a VTODO with no DTSTART/DUE/DURATION and no COMPLETED, the time-range match condition is simply (end > CREATED). The previous implementation incorrectly treated CREATED as a zero-duration point event (requiring start <= CREATED AND end > CREATED) by setting comp_end = comp_start before the range check. Fix by setting comp_end = DATE_MAX_DT when only CREATED is present, making the task open-ended from its creation date onward, so the standard range check reduces correctly to (end > CREATED). prompt: tests are broken with my last changes, but please verify if the correct thing is asserted. As I understand the relevant RFC-section, a VTODO with CREATED set but no other time-related properties should match if and only if the search interval covers the CREATED timestamp. followup-prompt: and read through section 9.9 in the caldav RFC as well. followup-prompt: commit this Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 2c14e0d commit 5b5ff47

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

src/icalendar_searcher/filters.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,23 @@ def _check_range(
9696
## is "Y" may be removed.
9797
##
9898
## * The matrix says that if NEITHER DTSTART, DUE nor DURATION
99-
## is given, then CREATED and COMPLETED should be considered
100-
## as start and end.
99+
## is given, then CREATED and COMPLETED serve as the time bounds.
100+
## When both are present, treat them as a [CREATED, COMPLETED] range.
101+
## When only COMPLETED is present, treat it as a point event.
102+
## When only CREATED is present, the RFC condition is just (end > CREATED)
103+
## — the task is open-ended from CREATED onward, so comp_end = DATE_MAX_DT.
101104
if not comp_start and not comp_end:
102105
if "CREATED" in component:
103106
comp_start = _normalize_dt(component["CREATED"].dt)
104107
if "COMPLETED" in component:
105108
comp_end = _normalize_dt(component["COMPLETED"].dt)
109+
if comp_start and not comp_end:
110+
comp_end = _normalize_dt(DATE_MAX_DT)
106111

107-
## * If only a start or only an end is given, assume the
108-
## duration to be 0
112+
## * If only COMPLETED is given (no DTSTART/DUE/CREATED), treat as a point event
109113
if comp_end and not comp_start:
110114
comp_start = comp_end
115+
## * If only DTSTART is given (no DUE/DURATION), treat as a zero-duration event
111116
if comp_start and not comp_end:
112117
comp_end = comp_start
113118

0 commit comments

Comments
 (0)