def parse_datetime( # pylint: disable=function-redefined to_parse: object, allow_none: bool = False, ) -> t.Optional[DatetimeWithTimezone]: """Parse a datetime string using dateutil. :param to_parse: The object to parse, if this is not a string the parsing will always fail. :param allow_none: Allow ``None`` to be passed without raising a exception. if ``to_parse`` is ``None`` and this option is ``True`` the result will be ``None``. :returns: The parsed DatetimeWithTimezone object. :raises APIException: If the parsing fails for whatever reason. """ if to_parse is None and allow_none: return None if isinstance(to_parse, str): try: parsed = dateutil.parser.parse(to_parse) except (ValueError, OverflowError): pass else: # This assumes that datetimes without tzinfo are in UTC. That is # not correct according to the ISO spec, however it is what we used # to do so we need to do this because of backwards compatibility. return DatetimeWithTimezone.from_datetime(parsed, default_tz=timezone.utc) raise APIException('The given date is not valid!', '{} cannot be parsed by dateutil.'.format(to_parse), APICodes.INVALID_PARAM, 400)
def __transform_to_datetime(self, value: str) -> DatetimeWithTimezone: try: parsed = dateutil.parser.isoparse(value) except (ValueError, OverflowError) as exc: raise SimpleParseError( self, value, extra={ 'message': "which can't be parsed as a valid datetime", }, ) from exc else: return DatetimeWithTimezone.from_datetime( parsed, default_tz=datetime.timezone.utc)