Skip to main content
`Ctrl`+`K`

# Source code for icalendar.tools

    """Utility functions for icalendar."""

    from __future__ import annotations

    import random
    from datetime import date, datetime, tzinfo
    from string import ascii_letters, digits
    from warnings import warn

    from icalendar.parser_tools import to_unicode

    from .error import WillBeRemovedInVersion7

    class UIDGenerator:
        """Use this only if you're too lazy to create real UUIDs.

        .. deprecated:: 6.2.1

            Use the Python standard library's :func:`uuid.uuid4` instead.
        """

        chars = list(ascii_letters + digits)

        @staticmethod
        def rnd_string(length=16) -> str:
            """Generates a string with random characters of length.

             .. deprecated:: 6.2.1

                 Use the Python standard library's :func:`uuid.uuid4` instead.
            """
            warn(
                "Use https://docs.python.org/3/library/uuid.html#uuid.uuid4 instead.",
                WillBeRemovedInVersion7,
                stacklevel=1
            )
            return "".join([random.choice(UIDGenerator.chars) for _ in range(length)])

        @staticmethod
        def uid(host_name="example.com", unique=""):
            """Generates a unique ID consisting of ``datetime-uniquevalue@host``.

            For example:

                .. code-block:: text

                    20050105T225746Z-HKtJMqUgdO0jDUwm@example.com

            .. deprecated:: 6.2.1

                Use the Python standard library's :func:`uuid.uuid5` instead.
            """
            from icalendar.prop import vDatetime, vText
            warn(
                "Use https://docs.python.org/3/library/uuid.html#uuid.uuid5 instead.",
                WillBeRemovedInVersion7,
                stacklevel=1
            )

            host_name = to_unicode(host_name)
            unique = unique or UIDGenerator.rnd_string()
            today = to_unicode(vDatetime(datetime.today()).to_ical())
            return vText(f"{today}-{unique}@{host_name}")

    def is_date(dt: date) -> bool:
        """Whether this is a date and not a datetime."""
        return isinstance(dt, date) and not isinstance(dt, datetime)

    def is_datetime(dt: date) -> bool:
        """Whether this is a date and not a datetime."""
        return isinstance(dt, datetime)

    def to_datetime(dt: date) -> datetime:
        """Make sure we have a datetime, not a date."""
        if is_date(dt):
            return datetime(dt.year, dt.month, dt.day)  # noqa: DTZ001
        return dt

    def is_pytz(tz: tzinfo):
        """Whether the timezone requires localize() and normalize()."""
        return hasattr(tz, "localize")

    def is_pytz_dt(dt: date):
        """Whether the time requires localize() and normalize()."""
        return is_datetime(dt) and is_pytz(dt.tzinfo)

    def normalize_pytz(dt: date):
        """We have to normalize the time after a calculation if we use pytz.

        pytz requires this function to be used in order to correctly calculate the
        timezone's offset after calculations.
        """
        if is_pytz_dt(dt):
            return dt.tzinfo.normalize(dt)
        return dt

    __all__ = [
        "UIDGenerator",
        "is_date",
        "is_datetime",
        "to_datetime",
        "is_pytz",
        "is_pytz_dt",
        "normalize_pytz",
    ]