mirror of
https://github.com/home-assistant/core.git
synced 2025-07-09 14:27:07 +00:00
Fix caldav calendars with custom timezones (#84955)
* Fix caldav calendars with custom timezones * Revert whitespace change
This commit is contained in:
parent
6220804639
commit
a1588cd6af
@ -1,7 +1,7 @@
|
|||||||
"""Support for WebDav Calendar."""
|
"""Support for WebDav Calendar."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@ -185,8 +185,8 @@ class WebDavCalendarData:
|
|||||||
event_list.append(
|
event_list.append(
|
||||||
CalendarEvent(
|
CalendarEvent(
|
||||||
summary=self.get_attr_value(vevent, "summary") or "",
|
summary=self.get_attr_value(vevent, "summary") or "",
|
||||||
start=vevent.dtstart.value,
|
start=self.to_local(vevent.dtstart.value),
|
||||||
end=self.get_end_date(vevent),
|
end=self.to_local(self.get_end_date(vevent)),
|
||||||
location=self.get_attr_value(vevent, "location"),
|
location=self.get_attr_value(vevent, "location"),
|
||||||
description=self.get_attr_value(vevent, "description"),
|
description=self.get_attr_value(vevent, "description"),
|
||||||
)
|
)
|
||||||
@ -269,8 +269,8 @@ class WebDavCalendarData:
|
|||||||
)
|
)
|
||||||
self.event = CalendarEvent(
|
self.event = CalendarEvent(
|
||||||
summary=summary,
|
summary=summary,
|
||||||
start=vevent.dtstart.value,
|
start=self.to_local(vevent.dtstart.value),
|
||||||
end=self.get_end_date(vevent),
|
end=self.to_local(self.get_end_date(vevent)),
|
||||||
location=self.get_attr_value(vevent, "location"),
|
location=self.get_attr_value(vevent, "location"),
|
||||||
description=self.get_attr_value(vevent, "description"),
|
description=self.get_attr_value(vevent, "description"),
|
||||||
)
|
)
|
||||||
@ -308,15 +308,23 @@ class WebDavCalendarData:
|
|||||||
def to_datetime(obj):
|
def to_datetime(obj):
|
||||||
"""Return a datetime."""
|
"""Return a datetime."""
|
||||||
if isinstance(obj, datetime):
|
if isinstance(obj, datetime):
|
||||||
if obj.tzinfo is None:
|
return WebDavCalendarData.to_local(obj)
|
||||||
# floating value, not bound to any time zone in particular
|
|
||||||
# represent same time regardless of which time zone is currently being observed
|
|
||||||
return obj.replace(tzinfo=dt.DEFAULT_TIME_ZONE)
|
|
||||||
return obj
|
|
||||||
return dt.dt.datetime.combine(obj, dt.dt.time.min).replace(
|
return dt.dt.datetime.combine(obj, dt.dt.time.min).replace(
|
||||||
tzinfo=dt.DEFAULT_TIME_ZONE
|
tzinfo=dt.DEFAULT_TIME_ZONE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def to_local(obj: datetime | date) -> datetime | date:
|
||||||
|
"""Return a datetime as a local datetime, leaving dates unchanged.
|
||||||
|
|
||||||
|
This handles giving floating times a timezone for comparison
|
||||||
|
with all day events and dropping the custom timezone object
|
||||||
|
used by the caldav client and dateutil so the datetime can be copied.
|
||||||
|
"""
|
||||||
|
if isinstance(obj, datetime):
|
||||||
|
return dt.as_local(obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_attr_value(obj, attribute):
|
def get_attr_value(obj, attribute):
|
||||||
"""Return the value of the attribute if defined."""
|
"""Return the value of the attribute if defined."""
|
||||||
|
@ -226,6 +226,35 @@ DTEND:20151127T003000Z
|
|||||||
RRULE:FREQ=HOURLY;INTERVAL=1;COUNT=12
|
RRULE:FREQ=HOURLY;INTERVAL=1;COUNT=12
|
||||||
END:VEVENT
|
END:VEVENT
|
||||||
END:VCALENDAR
|
END:VCALENDAR
|
||||||
|
""",
|
||||||
|
"""BEGIN:VCALENDAR
|
||||||
|
VERSION:2.0
|
||||||
|
PRODID:-//Global Corp.//CalDAV Client//EN
|
||||||
|
BEGIN:VTIMEZONE
|
||||||
|
TZID:Europe/London
|
||||||
|
BEGIN:STANDARD
|
||||||
|
DTSTART:19961027T020000
|
||||||
|
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
|
||||||
|
TZNAME:GMT
|
||||||
|
TZOFFSETFROM:+0100
|
||||||
|
TZOFFSETTO:+0000
|
||||||
|
END:STANDARD
|
||||||
|
BEGIN:DAYLIGHT
|
||||||
|
DTSTART:19810329T010000
|
||||||
|
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
|
||||||
|
TZNAME:BST
|
||||||
|
TZOFFSETFROM:+0000
|
||||||
|
TZOFFSETTO:+0100
|
||||||
|
END:DAYLIGHT
|
||||||
|
END:VTIMEZONE
|
||||||
|
BEGIN:VEVENT
|
||||||
|
UID:15
|
||||||
|
DTSTAMP:20221125T000000Z
|
||||||
|
DTSTART;TZID=Europe/London:20221127T000000
|
||||||
|
DTEND;TZID=Europe/London:20221127T003000
|
||||||
|
SUMMARY:Event with a provided Timezone
|
||||||
|
END:VEVENT
|
||||||
|
END:VCALENDAR
|
||||||
""",
|
""",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -929,7 +958,7 @@ async def test_get_events(hass, calendar, get_api_events):
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
events = await get_api_events("calendar.private")
|
events = await get_api_events("calendar.private")
|
||||||
assert len(events) == 15
|
assert len(events) == 16
|
||||||
assert calendar.call
|
assert calendar.call
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user