'Parse the date/time string into a datetime object.
:param timestr:
Any date/time string using the supported formats.
:param default:
The default datetime object, if this is a datetime object and not
`None`, elements specified in `timestr` replace elements in the
default object.
:param ignoretz:
Whether or not to ignore the time zone.
:param tzinfos:
A time zone, to be applied to the date, if `ignoretz` is `True`.
This can be either a subclass of `tzinfo`, a time zone string or an
integer offset.
:param **kwargs:
Keyword arguments as passed to `_parse()`.
:return:
Returns a `datetime.datetime` object or, if the `fuzzy_with_tokens`
option is `True`, returns a tuple, the first element being a
`datetime.datetime` object, the second a tuple containing the
fuzzy tokens.
:raises ValueError:
Raised for invalid or unknown string format, if the provided
`tzinfo` is not in a valid format, or if an invalid date would
be created.
:raises OverFlowError:
Raised if the parsed date exceeds the largest valid C integer on
your system.'

def parse(self, timestr, default=None, ignoretz=False, tzinfos=None, **kwargs):

    default_specified = (default is not None)
    if (not default_specified):
        default = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
    if kwargs.get(u'fuzzy_with_tokens', False):
        (res, skipped_tokens) = self._parse(timestr, **kwargs)
    else:
        res = self._parse(timestr, **kwargs)
    if (res is None):
        raise ValueError(u'Unknown    string    format')
    repl = {}
    for attr in [u'year', u'month', u'day', u'hour', u'minute', u'second', u'microsecond']:
        value = getattr(res, attr)
        if (value is not None):
            repl[attr] = value
    ret = default.replace(**repl)
    if ((res.weekday is not None) and (not res.day)):
        ret = (ret + relativedelta.relativedelta(weekday=res.weekday))
    if (not ignoretz):
        if (isinstance(tzinfos, collections.Callable) or (tzinfos and (res.tzname in tzinfos))):
            if isinstance(tzinfos, collections.Callable):
                tzdata = tzinfos(res.tzname, res.tzoffset)
            else:
                tzdata = tzinfos.get(res.tzname)
            if isinstance(tzdata, datetime.tzinfo):
                tzinfo = tzdata
            elif isinstance(tzdata, text_type):
                tzinfo = tz.tzstr(tzdata)
            elif isinstance(tzdata, integer_types):
                tzinfo = tz.tzoffset(res.tzname, tzdata)
            else:
                raise ValueError(u'Offset    must    be    tzinfo    subclass,    tz    string,    or    int    offset.')
            ret = ret.replace(tzinfo=tzinfo)
        elif (res.tzname and (res.tzname in time.tzname)):
            ret = ret.replace(tzinfo=tz.tzlocal())
        elif (res.tzoffset == 0):
            ret = ret.replace(tzinfo=tz.tzutc())
        elif res.tzoffset:
            ret = ret.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset))
    if kwargs.get(u'fuzzy_with_tokens', False):
        return (ret, skipped_tokens)
    else:
        return ret
