def normalize_time_input(t, future=False, default_unit='ms'):
    """
    :param default_unit: units of the input time *t*; must be one of "s" or
        "ms". This param is only respected if *t* looks like an int (e.g.
        "12345", 12345).
    :type default_unit: string

    Converts inputs such as:
       "2012-05-01"
       "-5d"
       1352863174
       "1352863174"
    to milliseconds since epoch. See http://labix.org/python-dateutil and :meth:`normalize_timedelta`.
    """
    error_msg = 'Error: Expected an int timestamp, a date format (e.g. YYYY-MM-DD), or an int with a single-letter suffix (s=seconds, m=minutes, h=hours, d=days, w=weeks, M=months, y=years; e.g. "-10d" indicates 10 days ago); but got {t}'
    if isinstance(t, basestring) and t.isdigit():
        t = int(t)

    if isinstance(t, basestring):
        try:
            t = normalize_timedelta(t)
        except ValueError:
            try:
                t = int(time.mktime(dateutil.parser.parse(t).timetuple())*1000)
                assert t > 0
            except (ValueError, OverflowError, AssertionError):
                raise ValueError(error_msg.format(t=t))
    elif isinstance(t, numbers.Integral):
        units_multipliers = {'ms': 1, 's': 1000}
        if default_unit not in units_multipliers:
            raise ValueError("Expected default_unit to be one of 's' or 'ms'")
        t = t * units_multipliers[default_unit]
    else:
        raise ValueError(error_msg.format(t=t))
    now = int(time.time()*1000)
    if t < 0 or (future and t < now):
        t += now
    return t