Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/tools.py: 76%
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 Union, cast
8try:
9 from typing import TypeIs
10except ImportError:
11 from typing_extensions import TypeIs
14def is_date(dt: Union[date, datetime]) -> bool:
15 """Whether this is a date and not a datetime."""
16 return isinstance(dt, date) and not isinstance(dt, datetime)
19def is_datetime(dt: Union[date, datetime]) -> TypeIs[datetime]:
20 """Whether this is a datetime and not just a date."""
21 return isinstance(dt, datetime)
24def to_datetime(dt: Union[date, datetime]) -> datetime:
25 """Make sure we have a datetime, not a date."""
26 if is_date(dt):
27 return datetime(dt.year, dt.month, dt.day) # noqa: DTZ001
28 return cast("datetime", dt)
31def is_pytz(tz: tzinfo) -> bool:
32 """Whether the timezone requires localize() and normalize()."""
33 return hasattr(tz, "localize")
36def is_pytz_dt(dt: Union[date, datetime]) -> TypeIs[datetime]:
37 """Whether the time requires localize() and normalize()."""
38 return is_datetime(dt) and (tzinfo := dt.tzinfo) is not None and is_pytz(tzinfo)
41def normalize_pytz(dt: Union[date, datetime]) -> Union[date, datetime]:
42 """We have to normalize the time after a calculation if we use pytz.
44 pytz requires this function to be used in order to correctly calculate the
45 timezone's offset after calculations.
46 """
47 if is_pytz_dt(dt):
48 return dt.tzinfo.normalize(dt) # type: ignore[attr-defined]
49 return dt
52__all__ = [
53 "is_date",
54 "is_datetime",
55 "is_pytz",
56 "is_pytz_dt",
57 "normalize_pytz",
58 "to_datetime",
59]