from datetime import datetime


def parse_datetime(date_str: str) -> datetime:
    """
    Tries to convert a string to a datetime using one of the different date formats.

    :param date_str: A possible datetime string.
    :type date_str: str

    :raises ValueError: If the string is not a valid datetime.

    """

    # Python 3.6 doesn't handle tz in the form "+00:00" correctly (the colon is too much apparently)
    # so until we upgrade we need this hack.
    if "+" in date_str:
        first, tz = date_str.split("+", 1)
        tz = tz.replace(":", "")
        date_str = f"{first}+{tz}"

    date_styles = ("%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%dT%H:%M:%S%z", "%Y-%m-%dT%H:%M:%S")
    for styles in date_styles:
        try:
            return datetime.strptime(date_str, styles)
        except ValueError:
            continue

    raise ValueError(f"{date_str} is not a recognized datetime")