mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 13:57:10 +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."""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import date, datetime, timedelta
|
||||
import logging
|
||||
import re
|
||||
|
||||
@ -185,8 +185,8 @@ class WebDavCalendarData:
|
||||
event_list.append(
|
||||
CalendarEvent(
|
||||
summary=self.get_attr_value(vevent, "summary") or "",
|
||||
start=vevent.dtstart.value,
|
||||
end=self.get_end_date(vevent),
|
||||
start=self.to_local(vevent.dtstart.value),
|
||||
end=self.to_local(self.get_end_date(vevent)),
|
||||
location=self.get_attr_value(vevent, "location"),
|
||||
description=self.get_attr_value(vevent, "description"),
|
||||
)
|
||||
@ -269,8 +269,8 @@ class WebDavCalendarData:
|
||||
)
|
||||
self.event = CalendarEvent(
|
||||
summary=summary,
|
||||
start=vevent.dtstart.value,
|
||||
end=self.get_end_date(vevent),
|
||||
start=self.to_local(vevent.dtstart.value),
|
||||
end=self.to_local(self.get_end_date(vevent)),
|
||||
location=self.get_attr_value(vevent, "location"),
|
||||
description=self.get_attr_value(vevent, "description"),
|
||||
)
|
||||
@ -308,15 +308,23 @@ class WebDavCalendarData:
|
||||
def to_datetime(obj):
|
||||
"""Return a datetime."""
|
||||
if isinstance(obj, datetime):
|
||||
if obj.tzinfo is None:
|
||||
# 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 WebDavCalendarData.to_local(obj)
|
||||
return dt.dt.datetime.combine(obj, dt.dt.time.min).replace(
|
||||
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
|
||||
def get_attr_value(obj, attribute):
|
||||
"""Return the value of the attribute if defined."""
|
||||
|
@ -226,6 +226,35 @@ DTEND:20151127T003000Z
|
||||
RRULE:FREQ=HOURLY;INTERVAL=1;COUNT=12
|
||||
END:VEVENT
|
||||
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()
|
||||
|
||||
events = await get_api_events("calendar.private")
|
||||
assert len(events) == 15
|
||||
assert len(events) == 16
|
||||
assert calendar.call
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user