From 952210e1d1c3a6f17dac1c29c3be24bf3be9bc3f Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 21 Jun 2026 16:39:08 +0200 Subject: [PATCH 1/3] add PERIOD handling --- vobject/icalendar.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vobject/icalendar.py b/vobject/icalendar.py index 52ff94b..ae30411 100644 --- a/vobject/icalendar.py +++ b/vobject/icalendar.py @@ -876,14 +876,20 @@ def transformFromNative(obj): obj.value_param = 'DATE' obj.value = ','.join([dateToString(val) for val in obj.value]) return obj - # Fixme: handle PERIOD case else: if obj.isNative: obj.isNative = False transformed = [] tzid = None for val in obj.value: - if tzid is None and type(val) == datetime.datetime: + if obj.value_param == "PERIOD": + if type(val[0]) is datetime.datetime and type(val[1]) is datetime.timedelta: + transformed.append(periodToString(val)) + continue + elif type(val[0]) is datetime.datetime and type(val[1]) is datetime.datetime: + transformed.append(dateTimeToString(val[0]) + '/' + dateTimeToString(val[1])) + continue + if tzid is None and type(val) is datetime.datetime: tzid = TimezoneComponent.registerTzinfo(val.tzinfo) if tzid is not None: obj.tzid_param = tzid From 84b8e616c7ef067f4eafeaf3c15a057d10ccda7d Mon Sep 17 00:00:00 2001 From: Peter Bieringer Date: Sun, 21 Jun 2026 16:43:52 +0200 Subject: [PATCH 2/3] make lint happy --- vobject/icalendar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vobject/icalendar.py b/vobject/icalendar.py index ae30411..ef9b430 100644 --- a/vobject/icalendar.py +++ b/vobject/icalendar.py @@ -886,7 +886,7 @@ def transformFromNative(obj): if type(val[0]) is datetime.datetime and type(val[1]) is datetime.timedelta: transformed.append(periodToString(val)) continue - elif type(val[0]) is datetime.datetime and type(val[1]) is datetime.datetime: + if type(val[0]) is datetime.datetime and type(val[1]) is datetime.datetime: transformed.append(dateTimeToString(val[0]) + '/' + dateTimeToString(val[1])) continue if tzid is None and type(val) is datetime.datetime: From 03cf614b487d51f305d1e342532e7592a5038aa0 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Wed, 5 Aug 2026 11:41:54 +1000 Subject: [PATCH 3/3] Add test for RRULE using RDATE with PERIOD. See issue py-vobject/vobject#129 and Kozea/Radicale#2165. --- tests.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests.py b/tests.py index 0c1a6e6..81d2678 100644 --- a/tests.py +++ b/tests.py @@ -284,6 +284,28 @@ def test_periodBehavior(self): 'TEST:20060216T100000/PT2H,20060516T100000/PT2H' ) + def test_rrdate_with_period(self): + """ + Test round-trip parsing and serialization of an RRULE with + an RDATE using a PERIOD. + """ + + raw = "BEGIN:VCALENDAR\r\n" \ + + "VERSION:2.0\r\n" \ + + "PRODID:test\r\n" \ + + "BEGIN:VEVENT\r\n" \ + + "UID:test\r\n" \ + + "DTSTART:20000101T000000Z\r\n" \ + + "DURATION:PT1H\r\n" \ + + "DTSTAMP:20000101T000000Z\r\n" \ + + "RDATE;VALUE=PERIOD:20000102T000000Z/PT2H\r\n" \ + + "RRULE:FREQ=WEEKLY\r\n" \ + + "END:VEVENT\r\n" \ + + "END:VCALENDAR\r\n" + obj = base.readOne(raw) + serialized = obj.serialize() + self.assertEqual(raw, serialized) + class TestVTodo(unittest.TestCase): """