Parameters
    ----------
    data : list-like
    dtype : dtype, str, or None, default None
    copy : bool, default False
    tz : tzinfo, str, or None, default None
    dayfirst : bool, default False
    yearfirst : bool, default False
    ambiguous : str, bool, or arraylike, default 'raise'
        See pandas._libs.tslibs.conversion.tz_localize_to_utc
    int_as_wall_time : bool, default False
        Whether to treat ints as wall time in specified timezone, or as
        nanosecond-precision UNIX epoch (wall time in UTC).
        This is used in DatetimeIndex.__init__ to deprecate the wall-time
        behaviour.

        ..versionadded:: 0.24.0

    Returns
    -------
    result : numpy.ndarray
        The sequence converted to a numpy array with dtype ``datetime64[ns]``.
    tz : tzinfo or None
        Either the user-provided tzinfo or one inferred from the data.
    inferred_freq : Tick or None
        The inferred frequency of the sequence.

    Raises
    ------
    TypeError : PeriodDType data is passed

def sequence_to_dt64ns(data, dtype=None, copy=False,
                       tz=None,
                       dayfirst=False, yearfirst=False, ambiguous='raise',
                       int_as_wall_time=False):
    """
    Parameters
    ----------
    data : list-like
    dtype : dtype, str, or None, default None
    copy : bool, default False
    tz : tzinfo, str, or None, default None
    dayfirst : bool, default False
    yearfirst : bool, default False
    ambiguous : str, bool, or arraylike, default 'raise'
        See pandas._libs.tslibs.conversion.tz_localize_to_utc
    int_as_wall_time : bool, default False
        Whether to treat ints as wall time in specified timezone, or as
        nanosecond-precision UNIX epoch (wall time in UTC).
        This is used in DatetimeIndex.__init__ to deprecate the wall-time
        behaviour.

        ..versionadded:: 0.24.0

    Returns
    -------
    result : numpy.ndarray
        The sequence converted to a numpy array with dtype ``datetime64[ns]``.
    tz : tzinfo or None
        Either the user-provided tzinfo or one inferred from the data.
    inferred_freq : Tick or None
        The inferred frequency of the sequence.

    Raises
    ------
    TypeError : PeriodDType data is passed
    """

    inferred_freq = None

    dtype = _validate_dt64_dtype(dtype)

    if not hasattr(data, "dtype"):
        # e.g. list, tuple
        if np.ndim(data) == 0:
            # i.e. generator
            data = list(data)
        data = np.asarray(data)
        copy = False
    elif isinstance(data, ABCSeries):
        data = data._values
    if isinstance(data, ABCPandasArray):
        data = data.to_numpy()

    if hasattr(data, "freq"):
        # i.e. DatetimeArray/Index
        inferred_freq = data.freq

    # if dtype has an embedded tz, capture it
    tz = validate_tz_from_dtype(dtype, tz)

    if isinstance(data, ABCIndexClass):
        data = data._data

    # By this point we are assured to have either a numpy array or Index
    data, copy = maybe_convert_dtype(data, copy)

    if is_object_dtype(data) or is_string_dtype(data):
        # TODO: We do not have tests specific to string-dtypes,
        #  also complex or categorical or other extension
        copy = False
        if lib.infer_dtype(data, skipna=False) == 'integer':
            data = data.astype(np.int64)
        else:
            # data comes back here as either i8 to denote UTC timestamps
            #  or M8[ns] to denote wall times
            data, inferred_tz = objects_to_datetime64ns(
                data, dayfirst=dayfirst, yearfirst=yearfirst)
            tz = maybe_infer_tz(tz, inferred_tz)
            # When a sequence of timestamp objects is passed, we always
            # want to treat the (now i8-valued) data as UTC timestamps,
            # not wall times.
            int_as_wall_time = False

    # `data` may have originally been a Categorical[datetime64[ns, tz]],
    # so we need to handle these types.
    if is_datetime64tz_dtype(data):
        # DatetimeArray -> ndarray
        tz = maybe_infer_tz(tz, data.tz)
        result = data._data

    elif is_datetime64_dtype(data):
        # tz-naive DatetimeArray or ndarray[datetime64]
        data = getattr(data, "_data", data)
        if data.dtype != _NS_DTYPE:
            data = conversion.ensure_datetime64ns(data)

        if tz is not None:
            # Convert tz-naive to UTC
            tz = timezones.maybe_get_tz(tz)
            data = conversion.tz_localize_to_utc(data.view('i8'), tz,
                                                 ambiguous=ambiguous)
            data = data.view(_NS_DTYPE)

        assert data.dtype == _NS_DTYPE, data.dtype
        result = data

    else:
        # must be integer dtype otherwise
        # assume this data are epoch timestamps
        if tz:
            tz = timezones.maybe_get_tz(tz)

        if data.dtype != _INT64_DTYPE:
            data = data.astype(np.int64, copy=False)
        if int_as_wall_time and tz is not None and not timezones.is_utc(tz):
            warnings.warn(_i8_message, FutureWarning, stacklevel=4)
            data = conversion.tz_localize_to_utc(data.view('i8'), tz,
                                                 ambiguous=ambiguous)
            data = data.view(_NS_DTYPE)
        result = data.view(_NS_DTYPE)

    if copy:
        # TODO: should this be deepcopy?
        result = result.copy()

    assert isinstance(result, np.ndarray), type(result)
    assert result.dtype == 'M8[ns]', result.dtype

    # We have to call this again after possibly inferring a tz above
    validate_tz_from_dtype(dtype, tz)

    return result, tz, inferred_freq