Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/tools.py: 91%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Utility functions for icalendar."""
3from __future__ import annotations
5from datetime import date, datetime, tzinfo
6from typing import TYPE_CHECKING, Union, cast
9if TYPE_CHECKING:
10 from icalendar.compatibility import TypeGuard, TypeIs
13def is_date(dt: Union[date, datetime]) -> bool:
14 """Whether this is a date and not a datetime."""
15 return isinstance(dt, date) and not isinstance(dt, datetime)
18def is_datetime(dt: Union[date, datetime]) -> TypeIs[datetime]:
19 """Whether this is a datetime and not just a date."""
20 return isinstance(dt, datetime)
23def to_datetime(dt: Union[date, datetime]) -> datetime:
24 """Make sure we have a datetime, not a date."""
25 if is_date(dt):
26 return datetime(dt.year, dt.month, dt.day) # noqa: DTZ001
27 return cast("datetime", dt)
30def is_pytz(tz: tzinfo) -> bool:
31 """Whether the timezone requires localize() and normalize()."""
32 return hasattr(tz, "localize")
35def is_pytz_dt(dt: Union[date, datetime]) -> TypeGuard[datetime]:
36 """Whether the time requires localize() and normalize()."""
37 return is_datetime(dt) and (tzinfo := dt.tzinfo) is not None and is_pytz(tzinfo)
40def normalize_pytz(dt: Union[date, datetime]) -> Union[date, datetime]:
41 """We have to normalize the time after a calculation if we use pytz.
43 pytz requires this function to be used in order to correctly calculate the
44 timezone's offset after calculations.
45 """
46 if is_pytz_dt(dt):
47 return dt.tzinfo.normalize(dt) # type: ignore[attr-defined]
48 return dt
51__all__ = [
52 "is_date",
53 "is_datetime",
54 "is_pytz",
55 "is_pytz_dt",
56 "normalize_pytz",
57 "to_datetime",
58]