Limit a datetime to a valid range for datetime, datetime64, and Timestamp objects
    >>> from datetime import timedelta
    >>> clip_datetime(MAX_DATETIME + timedelta(100)) == pd.Timestamp(MAX_DATETIME, tz='utc') == MAX_TIMESTAMP
    True
    >>> MAX_TIMESTAMP
    Timestamp('2262-04-11 23:47:16.854775+0000', tz='UTC')

def clip_datetime(dt, tz=DEFAULT_TZ, is_dst=None):
    """Limit a datetime to a valid range for datetime, datetime64, and Timestamp objects
    >>> from datetime import timedelta
    >>> clip_datetime(MAX_DATETIME + timedelta(100)) == pd.Timestamp(MAX_DATETIME, tz='utc') == MAX_TIMESTAMP
    True
    >>> MAX_TIMESTAMP
    Timestamp('2262-04-11 23:47:16.854775+0000', tz='UTC')
    """
    if isinstance(dt, datetime.datetime):
        # TODO: this gives up a day of datetime range due to assumptions about timezone
        #       make MIN/MAX naive and replace dt.replace(tz=None) before comparison
        #       set it back when done
        dt = make_tz_aware(dt, tz=tz, is_dst=is_dst)
        try:
            return pd.Timestamp(dt)
        except (ValueError, AttributeError):
            pass
        if dt > MAX_DATETIME:
            return MAX_TIMESTAMP
        elif dt < MIN_DATETIME:
            return MIN_TIMESTAMP
        return NAT
    return dt