U
    f/e(E                    @  s  d dl mZ d dlmZmZmZmZ d dlmZmZm	Z	 d dl
Z
d dlZd dlmZmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z! d dl"m#Z# d d	l$m%Z% d d
l&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9 d dl:m;Z; d dl<m=Z= d dl>m?Z? d dl@mAZAmBZC d dlDmEZE d dlFmGZG d dlHmI  mJZK d dlLmMZM d dlNmOZO d dlPmQZQmRZRmSZS erd dlmTZT d dlUmVZV d dl@mWZWmXZX ed d ZYdd ZZdIddZ[G dd deCj\eCj]Z^e	dJdd dd!d"d#Z_e	dKd$d d%d!d&d#Z_dLd d d%d!d(d#Z_dMd'd'd'd*d d d d*d+d,Z`dNd-d d d d.d/d0Zad d1d2d3Zbd4d4d4d5d6d7Zcd8d9 Zdd4d4d:d;d<Zed=d=d4d4d>d?d@ZfdAdAd dBdCdDZgdEdF ZhdddeQ fdGdHZidS )O    )annotations)datetimetime	timedeltatzinfo)TYPE_CHECKINGcastoverloadN)libtslib)NDArrayBacked)
BaseOffsetNaTNaTType
Resolution	Timestamp
conversionfieldsget_resolutioniNaTints_to_pydatetimeis_date_array_normalizednormalize_i8_timestamps	timezones	to_offsettzconversion)PerformanceWarning)astype_dt64_to_dt64tz)DT64NS_DTYPEINT64_DTYPEis_bool_dtypeis_categorical_dtypeis_datetime64_any_dtypeis_datetime64_dtypeis_datetime64_ns_dtypeis_datetime64tz_dtypeis_dtype_equalis_extension_array_dtypeis_float_dtypeis_object_dtypeis_period_dtype	is_sparseis_string_dtypeis_timedelta64_dtypepandas_dtype)DatetimeTZDtype)ABCMultiIndex)isna)checked_add_with_arr)ExtensionArraydatetimelike)generate_regular_range)IntegerArray)extract_array)get_period_alias)BDayDayTick)Literal	DataFrame)PeriodArrayTimedeltaArrayc                 C  s   | dkrt S t| dS dS )z
    Return a datetime64[ns] dtype appropriate for the given timezone.

    Parameters
    ----------
    tz : tzinfo or None

    Returns
    -------
    np.dtype or Datetime64TZDType
    Ntz)r   r/   rA    rC   @/tmp/pip-unpacked-wheel-tiezk1ph/pandas/core/arrays/datetimes.pytz_to_dtype_   s    rE   c                   s     fdd}| |_ ||_t|S )Nc                   s   |   } | jkrh drX| j}d}|rD|j}|d|dd}t| | j|}nt	| }|S  | j
krt| }| j|d d}nt	| }| j|d dd}|S )N)startend   ZstartingMonthmonth
fill_valuefloat64)rK   convert)_local_timestamps	_bool_opsendswithfreqkwdsgetr   Zget_start_end_fieldfreqstrZget_date_field_object_opsget_date_name_field_maybe_mask_results)selfvaluesrQ   Zmonth_kwrR   resultfieldrC   rD   fr   s4    

   
  z_field_accessor.<locals>.f)__name____doc__property)namer\   Z	docstringr]   rC   r[   rD   _field_accessorq   s     rb   c                      s  e Zd ZU dZdZeZeej	fZ
eZdZdddddd	d
gZded< ddgZded< ddddddddddddddddd d!gZded"< d#d$d%gZded&< ee e e Zded'< d(d)d*d+d,d-d.d/d0d1g
Zded2< d3Zd4ed5< d6Zed6d7fd8d9d:d;Zed6efd<d=d d> fd?d@Zed6d7dAd8d9dBdCZed6d7d6ejd7d7dDfd8d8d8dEdFdGZeddHdIZdd8dJdKdLdMZ dNdOdPdQZ!dd8dRdSdTZ"dNdOdUdVZ#e$d4dOdWdXZ%e$dYdOdZd[Z&e&j'd\d[ Z&e$dYdOd]d^Z(e$d8dOd_d`Z)e$dadOdbdcZ*dd<dO fdddeZ+dfdg Z,dd8d9didjZ-e.j/dd<dOdldmZ0d8dOdndoZ1dpdOdqdrZ2dsdt Z3d dOdudvZ4dwdx Z5d<dOdydzZ6d dOd{d|Z7e.j/dd dOd}d~Z8d<dOddZ9d dOddZ:e.j/dddOddZ;ddOddZ<dddZ=dddZ>e$d<dOddZ?e$d<dOddZ@e$d<dOddZAddOddZBe$dd ZCeCZDeEdddZFeEdddZGeEdddZHeEdddZIeEdddZJeEdddZKeEd ddZLeEd!ddZMdZNeEddeNZOeOZPeOZQeEdddZReRZSeEdddZTeEdddZUeUZVdZWeEddeWjXddZYeEddeWjXddZZeEdddZ[eEdddZ\eEdddZ]eEd	d	dZ^eEd
d
dZ_d<dOddZ`ddd8d8dddZa  ZbS )DatetimeArraya  
    Pandas ExtensionArray for tz-naive or tz-aware datetime data.

    .. warning::

       DatetimeArray is currently experimental, and its API may change
       without warning. In particular, :attr:`DatetimeArray.dtype` is
       expected to change to always be an instance of an ``ExtensionDtype``
       subclass.

    Parameters
    ----------
    values : Series, Index, DatetimeArray, ndarray
        The datetime data.

        For DatetimeArray `values` (or a Series or Index boxing one),
        `dtype` and `freq` will be extracted from `values`.

    dtype : numpy.dtype or DatetimeTZDtype
        Note that the only NumPy dtype allowed is 'datetime64[ns]'.
    freq : str or Offset, optional
        The frequency.
    copy : bool, default False
        Whether to copy the underlying array of values.

    Attributes
    ----------
    None

    Methods
    -------
    None
    Zdatetimearray)r   
datetime64dateis_month_startis_month_endis_quarter_startis_quarter_endis_year_startis_year_endis_leap_yearz	list[str]rO   rQ   rB   rU   yearrI   dayhourminutesecond
weekofyearweekweekday	dayofweekday_of_week	dayofyearday_of_yearquarterdays_in_monthdaysinmonthmicrosecond
nanosecond
_field_opsre   r   timetz
_other_ops_datetimelike_ops	to_periodtz_localize
tz_convert	normalizestrftimeroundfloorceil
month_nameday_name_datetimelike_methodsi  znp.dtype | DatetimeTZDtype_dtypeNFboolcopyc                 C  s  t |dd}t|tr$|jdtd}t|dd }t|t| rt|dd }|rf|jd krft|jd}nB|r|jrt	
||jsd| d	|j d
}t|n|jr|j}|d kr|j}|j}t|tjstdt|j d|jdkrtd|jdkr|t}|jtkr$td|j dt|}|dkr>td|rL| }|rZt|}t|dd rztt	|jd}tj| ||d || _|d kr|d k	rt| | | d S )NTZextract_numpyint64na_value_freqrB   rA   z1Timezone of the array and 'dtype' do not match. '' != ''zUnexpected type 'zY'. 'values' must be a DatetimeArray, ndarray, or Series or Index containing one of those.)      z.Only 1-dimensional input arrays are supported.i8zBThe dtype of 'values' is incorrect. Must be 'datetime64[ns]'. Got z	 instead.inferzTFrequency inference not allowed in DatetimeArray.__init__. Use 'pd.array()' instead.)rY   dtype)r7   
isinstancer6   to_numpyr   getattrtyperB   r/   r   
tz_compare	TypeErrorr   rQ   _ndarraynpndarray
ValueErrorr^   ndimviewr   _validate_dt64_dtyper   r   Ztz_standardizer   __init__r   _validate_frequency)rX   rY   r   rQ   r   inferred_freqdtzmsgrC   rC   rD   r      sZ    





zDatetimeArray.__init__
np.ndarrayzBaseOffset | None)rY   rQ   returnc                   s6   t |tjst|jtkstt ||}||_|S N)	r   r   r   AssertionErrorr   r   super_simple_newr   )clsrY   rQ   r   rZ   	__class__rC   rD   r   C  s
    zDatetimeArray._simple_newr   r   c                C  s   | j |||dS )Nr   )_from_sequence_not_strict)r   Zscalarsr   r   rC   rC   rD   _from_sequenceN  s    zDatetimeArray._from_sequenceraise)r   dayfirst	yearfirstc	              	   C  s   |d k}	|t jk	r|nd }t|\}}
t|||||||d\}}}t|||
\}}
|	r^d }t|}| j|||d}|d kr|d k	r| j|||d n|
rt	|j
|_|S )N)r   r   rB   r   r   	ambiguousrQ   r   r   )r
   
no_defaultdtlZmaybe_infer_freqsequence_to_dt64nsZvalidate_inferred_freqrE   r   r   r   r   r   )r   datar   r   rB   rQ   r   r   r   Zexplicit_noneZ
freq_inferZsubarrr   rZ   rC   rC   rD   r   R  s,    
z'DatetimeArray._from_sequence_not_strictc
                 C  s  t |}|d kr2tdd |||fD r2tdt||||dkrNtdt|}|d k	rft|}|d k	rvt|}|tks|tkrtdt 	|	\}
}t
|||\}}}t|||}|d k	r|d krd n|j}|d krd n|j}t|||||||}t|||||||}|d k	r0t|trN|d k	r:|d }|d k	rN|d }t|trjt||||}n*t||||d}tjdd	 |D tjd
}|d k	r|jn|j}|d}| j||t|d}|d k	rv|jd krvtj|j|||d}| |}|d k	r||||j}|d k	rv||||j}nFtjd|j|j |dd
|j }t|}|j ddd}| j|d |d}|
st!|r|d |krt"t#|dd  }|st!|r|d |krt"t#|d d }t|}| j|j$||dS )Nc                 s  s   | ]}|d kV  qd S r   rC   .0xrC   rC   rD   	<genexpr>  s     z0DatetimeArray._generate_range.<locals>.<genexpr>z1Must provide freq argument if no data is supplied   zVOf the four parameters: start, end, periods, and freq, exactly three must be specifiedz$Neither `start` nor `end` can be NaT)rF   rG   periodsoffsetc                 S  s   g | ]
}|j qS rC   )valuer   rC   rC   rD   
<listcomp>  s     z1DatetimeArray._generate_range.<locals>.<listcomp>r   M8[ns]r   r   nonexistentr   r   Fr   r   )%r   Zvalidate_periodsanyr   comZcount_not_noner   r   r   Zvalidate_endpoints_maybe_normalize_endpoints_infer_tz_from_endpointsrB   _maybe_localize_pointr   r:   r   r;   r5   generate_ranger   arrayr   r   r   rE   r   tz_localize_to_utcasi8asm8Zlinspacer   astypelenr   rc   r   )r   rF   rG   r   rQ   rB   r   r   r   closedZleft_closedZright_closed_normalizedZstart_tzZend_tzrY   ZxdrZ_tzindexZarrr   rC   rC   rD   _generate_range  s    
 
            





   

zDatetimeArray._generate_rangeznp.datetime64)setitemr   c                 C  s0   t || js|tk	rtd| j||d |jS )Nz'value' should be a Timestamp.r   )r   _scalar_typer   r   _check_compatible_withr   )rX   r   r   rC   rC   rD   _unbox_scalar  s    zDatetimeArray._unbox_scalarzTimestamp | NaTType)r   c                 C  s   t || jdS NrA   )r   rB   rX   r   rC   rC   rD   _scalar_from_string  s    z!DatetimeArray._scalar_from_stringr   c                 C  sH   |t krd S | | |rDt| j|jsDtd| j d|j dd S )NzTimezones don't match. 'r   r   )r   _assert_tzawareness_compatr   r   rB   r   )rX   otherr   rC   rC   rD   r     s    
z$DatetimeArray._check_compatible_withc                 C  s&   t || jd}|tk	r"|| j |S r   )r   rB   r   Z	_set_freqrQ   )rX   r   tsrC   rC   rD   	_box_func  s    zDatetimeArray._box_funcc                 C  s   | j S )a%  
        The dtype for the DatetimeArray.

        .. warning::

           A future version of pandas will change dtype to never be a
           ``numpy.dtype``. Instead, :attr:`DatetimeArray.dtype` will
           always be an instance of an ``ExtensionDtype`` subclass.

        Returns
        -------
        numpy.dtype or DatetimeTZDtype
            If the values are tz-naive, then ``np.dtype('datetime64[ns]')``
            is returned.

            If the values are tz-aware, then the ``DatetimeTZDtype``
            is returned.
        )r   rX   rC   rC   rD   r   	  s    zDatetimeArray.dtypetzinfo | Nonec                 C  s   t | jddS )z
        Return timezone, if any.

        Returns
        -------
        datetime.tzinfo, pytz.tzinfo.BaseTZInfo, dateutil.tz.tz.tzfile, or None
            Returns None when the array is tz-naive.
        rB   N)r   r   r   rC   rC   rD   rB   "  s    zDatetimeArray.tzc                 C  s   t dd S )NzNCannot directly set timezone. Use tz_localize() or tz_convert() as appropriate)AttributeErrorr   rC   rC   rD   rB   /  s    c                 C  s   | j S )z(
        Alias for tz attribute
        rA   r   rC   rC   rD   r   7  s    zDatetimeArray.tzinfoc                 C  s   t | j| jS )zN
        Returns True if all of the dates are at midnight ("no time")
        )r   r   rB   r   rC   rC   rD   is_normalized>  s    zDatetimeArray.is_normalizedr   c                 C  s   t | j| jS r   )r   r   rB   r   rC   rC   rD   _resolution_objE  s    zDatetimeArray._resolution_objc                   s    |d kr| j rt}t j|dS )Nr   )rB   objectr   	__array__)rX   r   r   rC   rD   r   L  s    zDatetimeArray.__array__c           	   	   c  s   | j dkr(tt| D ]}| | V  qn| j}t| }d}|| d }t b tjdtd t|D ]D}|| }t|d | |}t	||| | j
| jdd}|E dH  qfW 5 Q R X dS )zt
        Return an iterator over the boxed values

        Yields
        ------
        tstamp : Timestamp
        r   i'  ignore)category	timestamp)rB   rQ   boxN)r   ranger   r   warningscatch_warningsfilterwarningsFutureWarningminr   rB   rQ   )	rX   ir   length	chunksizechunksZstart_iZend_iZ	convertedrC   rC   rD   __iter__S  s&    


   zDatetimeArray.__iter__Tc                 C  s   t |}t|| jr$|r |  S | S t|r<t| ||ddS | jd krdt|rd|| jkrd| j	|S t
|rz| j|jdS tj	| ||S )NF)Zvia_utc)rQ   )r.   r&   r   r   r$   r   rB   r#   r   r   r*   r   rQ   r   ZDatetimeLikeArrayMixin)rX   r   r   rC   rC   rD   r   q  s    zDatetimeArray.astyper   c                 K  s,   ddl m} || |}tj| j| j||dS )Nr   )!get_format_datetime64_from_values)rB   formatna_rep)Zpandas.io.formats.formatr  r   Zformat_array_from_datetimer   rB   )rX   r  Zdate_formatkwargsr  fmtrC   rC   rD   _format_native_types  s    
   z"DatetimeArray._format_native_typesc                 C  s6   t |tjrt|}t|ds"dS |j}t| j|S )Nr   F)r   r   rd   r   hasattrr   r   r   )rX   r   other_tzrC   rC   rD   _has_same_tz  s    
zDatetimeArray._has_same_tzNonec                 C  sb   t |dd }t |dd }t|r(|jj}|tkr2n,| jd krN|d k	r^tdn|d kr^tdd S )Nr   r   z;Cannot compare tz-naive and tz-aware datetime-like objects.z:Cannot compare tz-naive and tz-aware datetime-like objects)r   r%   r   rB   r   r   )rX   r   r  Zother_dtyperC   rC   rD   r     s    
z(DatetimeArray._assert_tzawareness_compatc                 C  s   t | t |krtdt|tjr<t|s0tt| |}| |sZt	t| j
 d| j}|j}| j|jB }t|| |d}| js|jrt||t |dS )z3subtract DatetimeArray/Index or ndarray[datetime64]z$cannot add indices of unequal lengthz9 subtraction must have the same timezones or no timezonesarr_masktimedelta64[ns])r   r   r   r   r   r#   r   r   r  r   r^   r   _isnanr2   _hasnansZputmaskr   r   )rX   r   Zself_i8Zother_i8r  
new_valuesrC   rC   rD   _sub_datetime_arraylike  s     
z%DatetimeArray._sub_datetime_arraylikec                 C  s   | j dkr |  || jS t|tr.tzD| jd k	rF| 	d }n| }|
|d}t|}|	| j}W nP tk
r   tdt | d| }t| st| |	| j Y S Y nX t| |S )Nr   r   zBNon-vectorized DateOffset being applied to Series or DatetimeIndexO)r   ravel_add_offsetreshapeshaper   r;   r   rB   r   Z_apply_arrayr   rc   r   NotImplementedErrorr   warnr   r   r   r   r   )rX   r   rY   rZ   rC   rC   rD   r    s&    


 zDatetimeArray._add_offsetc                 C  sx   t |ttjfst|tk	s tt|}|tkr8| t S | |sJtd| j	}t
||j | jd}| |}|dS )NzBTimestamp subtraction must have the same timezones or no timezonesr  r  )r   r   r   rd   r   r   r   r  r   r   r2   r   r  rW   r   )rX   r   r   rZ   rC   rC   rD   _sub_datetimelike_scalar  s    

z&DatetimeArray._sub_datetimelike_scalarc                 C  s,   | j dkst| j r| jS t| j| j S )z
        Convert to an i8 (unix-like nanosecond timestamp) representation
        while keeping the local timezone and not using UTC.
        This is used to calculate time-of-day information as if the timestamps
        were timezone-naive.
        N)rB   r   is_utcr   r   tz_convert_from_utcr   rC   rC   rD   rN     s    zDatetimeArray._local_timestampsc                 C  s8   t |}| jdkrtdt|}| j| j|| jdS )a	  
        Convert tz-aware Datetime Array/Index from one time zone to another.

        Parameters
        ----------
        tz : str, pytz.timezone, dateutil.tz.tzfile or None
            Time zone for time. Corresponding timestamps would be converted
            to this time zone of the Datetime Array/Index. A `tz` of None will
            convert to UTC and remove the timezone information.

        Returns
        -------
        Array or Index

        Raises
        ------
        TypeError
            If Datetime Array/Index is tz-naive.

        See Also
        --------
        DatetimeIndex.tz : A timezone that has a variable offset from UTC.
        DatetimeIndex.tz_localize : Localize tz-naive DatetimeIndex to a
            given time zone, or remove timezone from a tz-aware DatetimeIndex.

        Examples
        --------
        With the `tz` parameter, we can change the DatetimeIndex
        to other time zones:

        >>> dti = pd.date_range(start='2014-08-01 09:00',
        ...                     freq='H', periods=3, tz='Europe/Berlin')

        >>> dti
        DatetimeIndex(['2014-08-01 09:00:00+02:00',
                       '2014-08-01 10:00:00+02:00',
                       '2014-08-01 11:00:00+02:00'],
                      dtype='datetime64[ns, Europe/Berlin]', freq='H')

        >>> dti.tz_convert('US/Central')
        DatetimeIndex(['2014-08-01 02:00:00-05:00',
                       '2014-08-01 03:00:00-05:00',
                       '2014-08-01 04:00:00-05:00'],
                      dtype='datetime64[ns, US/Central]', freq='H')

        With the ``tz=None``, we can remove the timezone (after converting
        to UTC if necessary):

        >>> dti = pd.date_range(start='2014-08-01 09:00', freq='H',
        ...                     periods=3, tz='Europe/Berlin')

        >>> dti
        DatetimeIndex(['2014-08-01 09:00:00+02:00',
                       '2014-08-01 10:00:00+02:00',
                       '2014-08-01 11:00:00+02:00'],
                        dtype='datetime64[ns, Europe/Berlin]', freq='H')

        >>> dti.tz_convert(None)
        DatetimeIndex(['2014-08-01 07:00:00',
                       '2014-08-01 08:00:00',
                       '2014-08-01 09:00:00'],
                        dtype='datetime64[ns]', freq='H')
        Nz?Cannot convert tz-naive timestamps, use tz_localize to localizer   rQ   )r   maybe_get_tzrB   r   rE   r   r   rQ   )rX   rB   r   rC   rC   rD   r     s    @

zDatetimeArray.tz_convertc                 C  s   d}||krt |tstd| jdk	rL|dkrBt| j| j}qjtdnt	|}tj
| j|||d}|t}t|}d}t|st| dkrt|d s| j}n|dkr| jdkr| j}| j|||dS )	a  
        Localize tz-naive Datetime Array/Index to tz-aware
        Datetime Array/Index.

        This method takes a time zone (tz) naive Datetime Array/Index object
        and makes this time zone aware. It does not move the time to another
        time zone.

        This method can also be used to do the inverse -- to create a time
        zone unaware object from an aware object. To that end, pass `tz=None`.

        Parameters
        ----------
        tz : str, pytz.timezone, dateutil.tz.tzfile or None
            Time zone to convert timestamps to. Passing ``None`` will
            remove the time zone information preserving local time.
        ambiguous : 'infer', 'NaT', bool array, default 'raise'
            When clocks moved backward due to DST, ambiguous times may arise.
            For example in Central European Time (UTC+01), when going from
            03:00 DST to 02:00 non-DST, 02:30:00 local time occurs both at
            00:30:00 UTC and at 01:30:00 UTC. In such a situation, the
            `ambiguous` parameter dictates how ambiguous times should be
            handled.

            - 'infer' will attempt to infer fall dst-transition hours based on
              order
            - bool-ndarray where True signifies a DST time, False signifies a
              non-DST time (note that this flag is only applicable for
              ambiguous times)
            - 'NaT' will return NaT where there are ambiguous times
            - 'raise' will raise an AmbiguousTimeError if there are ambiguous
              times.

        nonexistent : 'shift_forward', 'shift_backward, 'NaT', timedelta, default 'raise'
            A nonexistent time does not exist in a particular timezone
            where clocks moved forward due to DST.

            - 'shift_forward' will shift the nonexistent time forward to the
              closest existing time
            - 'shift_backward' will shift the nonexistent time backward to the
              closest existing time
            - 'NaT' will return NaT where there are nonexistent times
            - timedelta objects will shift nonexistent times by the timedelta
            - 'raise' will raise an NonExistentTimeError if there are
              nonexistent times.

        Returns
        -------
        Same type as self
            Array/Index converted to the specified time zone.

        Raises
        ------
        TypeError
            If the Datetime Array/Index is tz-aware and tz is not None.

        See Also
        --------
        DatetimeIndex.tz_convert : Convert tz-aware DatetimeIndex from
            one time zone to another.

        Examples
        --------
        >>> tz_naive = pd.date_range('2018-03-01 09:00', periods=3)
        >>> tz_naive
        DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00',
                       '2018-03-03 09:00:00'],
                      dtype='datetime64[ns]', freq='D')

        Localize DatetimeIndex in US/Eastern time zone:

        >>> tz_aware = tz_naive.tz_localize(tz='US/Eastern')
        >>> tz_aware
        DatetimeIndex(['2018-03-01 09:00:00-05:00',
                       '2018-03-02 09:00:00-05:00',
                       '2018-03-03 09:00:00-05:00'],
                      dtype='datetime64[ns, US/Eastern]', freq=None)

        With the ``tz=None``, we can remove the time zone information
        while keeping the local time (not converted to UTC):

        >>> tz_aware.tz_localize(None)
        DatetimeIndex(['2018-03-01 09:00:00', '2018-03-02 09:00:00',
                       '2018-03-03 09:00:00'],
                      dtype='datetime64[ns]', freq=None)

        Be careful with DST changes. When there is sequential data, pandas can
        infer the DST time:

        >>> s = pd.to_datetime(pd.Series(['2018-10-28 01:30:00',
        ...                               '2018-10-28 02:00:00',
        ...                               '2018-10-28 02:30:00',
        ...                               '2018-10-28 02:00:00',
        ...                               '2018-10-28 02:30:00',
        ...                               '2018-10-28 03:00:00',
        ...                               '2018-10-28 03:30:00']))
        >>> s.dt.tz_localize('CET', ambiguous='infer')
        0   2018-10-28 01:30:00+02:00
        1   2018-10-28 02:00:00+02:00
        2   2018-10-28 02:30:00+02:00
        3   2018-10-28 02:00:00+01:00
        4   2018-10-28 02:30:00+01:00
        5   2018-10-28 03:00:00+01:00
        6   2018-10-28 03:30:00+01:00
        dtype: datetime64[ns, CET]

        In some cases, inferring the DST is impossible. In such cases, you can
        pass an ndarray to the ambiguous parameter to set the DST explicitly

        >>> s = pd.to_datetime(pd.Series(['2018-10-28 01:20:00',
        ...                               '2018-10-28 02:36:00',
        ...                               '2018-10-28 03:46:00']))
        >>> s.dt.tz_localize('CET', ambiguous=np.array([True, True, False]))
        0   2018-10-28 01:20:00+02:00
        1   2018-10-28 02:36:00+02:00
        2   2018-10-28 03:46:00+01:00
        dtype: datetime64[ns, CET]

        If the DST transition causes nonexistent times, you can shift these
        dates forward or backwards with a timedelta object or `'shift_forward'`
        or `'shift_backwards'`.

        >>> s = pd.to_datetime(pd.Series(['2015-03-29 02:30:00',
        ...                               '2015-03-29 03:30:00']))
        >>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_forward')
        0   2015-03-29 03:00:00+02:00
        1   2015-03-29 03:30:00+02:00
        dtype: datetime64[ns, Europe/Warsaw]

        >>> s.dt.tz_localize('Europe/Warsaw', nonexistent='shift_backward')
        0   2015-03-29 01:59:59.999999999+01:00
        1   2015-03-29 03:30:00+02:00
        dtype: datetime64[ns, Europe/Warsaw]

        >>> s.dt.tz_localize('Europe/Warsaw', nonexistent=pd.Timedelta('1H'))
        0   2015-03-29 03:30:00+02:00
        1   2015-03-29 03:30:00+02:00
        dtype: datetime64[ns, Europe/Warsaw]
        )r   r   Zshift_forwardZshift_backwardzoThe nonexistent argument must be one of 'raise', 'NaT', 'shift_forward', 'shift_backward' or a timedelta objectNz,Already tz-aware, use tz_convert to convert.r   r   r   r   )r   r   r   rB   r   r  r   r   r   r!  r   r   r   rE   r  r   r1   rQ   r   )rX   rB   r   r   Znonexistent_optionsZ	new_datesr   rQ   rC   rC   rD   r   _  s8     
 


   
"zDatetimeArray.tz_localizec                 C  s   t | j| jdS )z
        Return Datetime Array/Index as object ndarray of datetime.datetime
        objects.

        Returns
        -------
        datetimes : ndarray[object]
        rA   r   r   rB   r   rC   rC   rD   to_pydatetime  s    	zDatetimeArray.to_pydatetimec                 C  s(   t | j| j}t| |d| jS )a  
        Convert times to midnight.

        The time component of the date-time is converted to midnight i.e.
        00:00:00. This is useful in cases, when the time does not matter.
        Length is unaltered. The timezones are unaffected.

        This method is available on Series with datetime values under
        the ``.dt`` accessor, and directly on Datetime Array/Index.

        Returns
        -------
        DatetimeArray, DatetimeIndex or Series
            The same type as the original data. Series will have the same
            name and index. DatetimeIndex will have the same name.

        See Also
        --------
        floor : Floor the datetimes to the specified freq.
        ceil : Ceil the datetimes to the specified freq.
        round : Round the datetimes to the specified freq.

        Examples
        --------
        >>> idx = pd.date_range(start='2014-08-01 10:00', freq='H',
        ...                     periods=3, tz='Asia/Calcutta')
        >>> idx
        DatetimeIndex(['2014-08-01 10:00:00+05:30',
                       '2014-08-01 11:00:00+05:30',
                       '2014-08-01 12:00:00+05:30'],
                        dtype='datetime64[ns, Asia/Calcutta]', freq='H')
        >>> idx.normalize()
        DatetimeIndex(['2014-08-01 00:00:00+05:30',
                       '2014-08-01 00:00:00+05:30',
                       '2014-08-01 00:00:00+05:30'],
                       dtype='datetime64[ns, Asia/Calcutta]', freq=None)
        r   )r   r   rB   r   Z
_with_freqr   )rX   r  rC   rC   rD   r     s    &zDatetimeArray.normalizer?   c                 C  sr   ddl m} | jdk	r"tdt |dkr^| jp4| j}|dkrFtdt	|}|dkrZ|}|}|j
| j|| jdS )ax  
        Cast to PeriodArray/Index at a particular frequency.

        Converts DatetimeArray/Index to PeriodArray/Index.

        Parameters
        ----------
        freq : str or Offset, optional
            One of pandas' :ref:`offset strings <timeseries.offset_aliases>`
            or an Offset object. Will be inferred by default.

        Returns
        -------
        PeriodArray/Index

        Raises
        ------
        ValueError
            When converting a DatetimeArray/Index with non-regular values,
            so that a frequency cannot be inferred.

        See Also
        --------
        PeriodIndex: Immutable ndarray holding ordinal values.
        DatetimeIndex.to_pydatetime: Return DatetimeIndex as object.

        Examples
        --------
        >>> df = pd.DataFrame({"y": [1, 2, 3]},
        ...                   index=pd.to_datetime(["2000-03-31 00:00:00",
        ...                                         "2000-05-31 00:00:00",
        ...                                         "2000-08-31 00:00:00"]))
        >>> df.index.to_period("M")
        PeriodIndex(['2000-03', '2000-05', '2000-08'],
                    dtype='period[M]')

        Infer the daily frequency

        >>> idx = pd.date_range("2017-01-01", periods=2)
        >>> idx.to_period()
        PeriodIndex(['2017-01-01', '2017-01-02'],
                    dtype='period[D]')
        r   )r?   NzNConverting to PeriodArray/Index representation will drop timezone information.z8You must pass a freq argument as current index has none.rA   )pandas.core.arraysr?   rB   r   r  UserWarningrT   r   r   r8   Z_from_datetime64r   )rX   rQ   r?   resrC   rC   rD   r   G  s"    -
zDatetimeArray.to_periodr@   c                 C  sD   t jdtdd ddlm} | j| | j }|d}||S )a5  
        Calculate TimedeltaArray of difference between index
        values and index converted to PeriodArray at specified
        freq. Used for vectorized offsets.

        Parameters
        ----------
        freq : Period frequency

        Returns
        -------
        TimedeltaArray/Index
        zto_perioddelta is deprecated and will be removed in a future version.  Use `dtindex - dtindex.to_period(freq).to_timestamp()` insteadr   
stacklevelr   r@   zm8[ns])	r   r  r   Zpandas.core.arrays.timedeltasr@   r   r   Zto_timestampr   )rX   rQ   r@   Zi8deltaZm8deltarC   rC   rD   to_perioddelta  s    
zDatetimeArray.to_perioddeltac                 C  s*   |   }tj|d|d}| j|dd}|S )a  
        Return the month names of the DateTimeIndex with specified locale.

        Parameters
        ----------
        locale : str, optional
            Locale determining the language in which to return the month name.
            Default is English locale.

        Returns
        -------
        Index
            Index of month names.

        Examples
        --------
        >>> idx = pd.date_range(start='2018-01', freq='M', periods=3)
        >>> idx
        DatetimeIndex(['2018-01-31', '2018-02-28', '2018-03-31'],
                      dtype='datetime64[ns]', freq='M')
        >>> idx.month_name()
        Index(['January', 'February', 'March'], dtype='object')
        r   localeNrJ   rN   r   rV   rW   rX   r,  rY   rZ   rC   rC   rD   r     s    zDatetimeArray.month_namec                 C  s*   |   }tj|d|d}| j|dd}|S )a  
        Return the day names of the DateTimeIndex with specified locale.

        Parameters
        ----------
        locale : str, optional
            Locale determining the language in which to return the day name.
            Default is English locale.

        Returns
        -------
        Index
            Index of day names.

        Examples
        --------
        >>> idx = pd.date_range(start='2018-01-01', freq='D', periods=3)
        >>> idx
        DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03'],
                      dtype='datetime64[ns]', freq='D')
        >>> idx.day_name()
        Index(['Monday', 'Tuesday', 'Wednesday'], dtype='object')
        r   r+  NrJ   r-  r.  rC   rC   rD   r     s    zDatetimeArray.day_namec                 C  s   |   }t|ddS )zX
        Returns numpy array of datetime.time. The time part of the Timestamps.
        r   r   rN   r   rX   Z
timestampsrC   rC   rD   r     s    zDatetimeArray.timec                 C  s   t | j| jddS )z
        Returns numpy array of datetime.time also containing timezone
        information. The time part of the Timestamps.
        r   r/  r"  r   rC   rC   rD   r     s    zDatetimeArray.timetzc                 C  s   |   }t|ddS )z
        Returns numpy array of python datetime.date objects (namely, the date
        part of Timestamps without timezone information).
        re   r/  r0  r1  rC   rC   rD   re     s    	zDatetimeArray.dater>   c                 C  sH   ddl m} |  }t|}||dddgdd}| jrDd|j| j< |S )	a  
        Returns a DataFrame with the year, week, and day calculated according to
        the ISO 8601 standard.

        .. versionadded:: 1.1.0

        Returns
        -------
        DataFrame
            with columns year, week and day

        See Also
        --------
        Timestamp.isocalendar : Function return a 3-tuple containing ISO year,
            week number, and weekday for the given Timestamp object.
        datetime.date.isocalendar : Return a named tuple object with
            three components: year, week and weekday.

        Examples
        --------
        >>> idx = pd.date_range(start='2019-12-29', freq='D', periods=4)
        >>> idx.isocalendar()
                    year  week  day
        2019-12-29  2019    52    7
        2019-12-30  2020     1    1
        2019-12-31  2020     1    2
        2020-01-01  2020     1    3
        >>> idx.isocalendar().week
        2019-12-29    52
        2019-12-30     1
        2019-12-31     1
        2020-01-01     1
        Freq: D, Name: week, dtype: UInt32
        r   r=   rm   rs   rn   ZUInt32)columnsr   N)pandasr>   rN   r   Zbuild_isocalendar_sarrayr  Zilocr  )rX   r>   rY   ZsarrayZiso_calendar_dfrC   rC   rD   isocalendar  s    #
  zDatetimeArray.isocalendarc                 C  s<   t jdtdd |  j}|jr0|jdtjdS |jddS )z
        The week ordinal of the year.

        .. deprecated:: 1.1.0

        weekofyear and week have been deprecated.
        Please use DatetimeIndex.isocalendar().week instead.
        zweekofyear and week have been deprecated, please use DatetimeIndex.isocalendar().week instead, which returns a Series.  To exactly reproduce the behavior of week and weekofyear and return an Index, you may call pd.Int64Index(idx.isocalendar().week)r   r'  rL   )r   r   r   r   )	r   r  r   r4  rs   Zhasnansr   r   nan)rX   Zweek_seriesrC   rC   rD   rr   :  s    
	
zDatetimeArray.weekofyearYa  
        The year of the datetime.

        Examples
        --------
        >>> datetime_series = pd.Series(
        ...     pd.date_range("2000-01-01", periods=3, freq="Y")
        ... )
        >>> datetime_series
        0   2000-12-31
        1   2001-12-31
        2   2002-12-31
        dtype: datetime64[ns]
        >>> datetime_series.dt.year
        0    2000
        1    2001
        2    2002
        dtype: int64
        Ma  
        The month as January=1, December=12.

        Examples
        --------
        >>> datetime_series = pd.Series(
        ...     pd.date_range("2000-01-01", periods=3, freq="M")
        ... )
        >>> datetime_series
        0   2000-01-31
        1   2000-02-29
        2   2000-03-31
        dtype: datetime64[ns]
        >>> datetime_series.dt.month
        0    1
        1    2
        2    3
        dtype: int64
        Da  
        The day of the datetime.

        Examples
        --------
        >>> datetime_series = pd.Series(
        ...     pd.date_range("2000-01-01", periods=3, freq="D")
        ... )
        >>> datetime_series
        0   2000-01-01
        1   2000-01-02
        2   2000-01-03
        dtype: datetime64[ns]
        >>> datetime_series.dt.day
        0    1
        1    2
        2    3
        dtype: int64
        ha  
        The hours of the datetime.

        Examples
        --------
        >>> datetime_series = pd.Series(
        ...     pd.date_range("2000-01-01", periods=3, freq="h")
        ... )
        >>> datetime_series
        0   2000-01-01 00:00:00
        1   2000-01-01 01:00:00
        2   2000-01-01 02:00:00
        dtype: datetime64[ns]
        >>> datetime_series.dt.hour
        0    0
        1    1
        2    2
        dtype: int64
        ma  
        The minutes of the datetime.

        Examples
        --------
        >>> datetime_series = pd.Series(
        ...     pd.date_range("2000-01-01", periods=3, freq="T")
        ... )
        >>> datetime_series
        0   2000-01-01 00:00:00
        1   2000-01-01 00:01:00
        2   2000-01-01 00:02:00
        dtype: datetime64[ns]
        >>> datetime_series.dt.minute
        0    0
        1    1
        2    2
        dtype: int64
        sa  
        The seconds of the datetime.

        Examples
        --------
        >>> datetime_series = pd.Series(
        ...     pd.date_range("2000-01-01", periods=3, freq="s")
        ... )
        >>> datetime_series
        0   2000-01-01 00:00:00
        1   2000-01-01 00:00:01
        2   2000-01-01 00:00:02
        dtype: datetime64[ns]
        >>> datetime_series.dt.second
        0    0
        1    1
        2    2
        dtype: int64
        usa  
        The microseconds of the datetime.

        Examples
        --------
        >>> datetime_series = pd.Series(
        ...     pd.date_range("2000-01-01", periods=3, freq="us")
        ... )
        >>> datetime_series
        0   2000-01-01 00:00:00.000000
        1   2000-01-01 00:00:00.000001
        2   2000-01-01 00:00:00.000002
        dtype: datetime64[ns]
        >>> datetime_series.dt.microsecond
        0       0
        1       1
        2       2
        dtype: int64
        nsa  
        The nanoseconds of the datetime.

        Examples
        --------
        >>> datetime_series = pd.Series(
        ...     pd.date_range("2000-01-01", periods=3, freq="ns")
        ... )
        >>> datetime_series
        0   2000-01-01 00:00:00.000000000
        1   2000-01-01 00:00:00.000000001
        2   2000-01-01 00:00:00.000000002
        dtype: datetime64[ns]
        >>> datetime_series.dt.nanosecond
        0       0
        1       1
        2       2
        dtype: int64
        a  
    The day of the week with Monday=0, Sunday=6.

    Return the day of the week. It is assumed the week starts on
    Monday, which is denoted by 0 and ends on Sunday which is denoted
    by 6. This method is available on both Series with datetime
    values (using the `dt` accessor) or DatetimeIndex.

    Returns
    -------
    Series or Index
        Containing integers indicating the day number.

    See Also
    --------
    Series.dt.dayofweek : Alias.
    Series.dt.weekday : Alias.
    Series.dt.day_name : Returns the name of the day of the week.

    Examples
    --------
    >>> s = pd.date_range('2016-12-31', '2017-01-08', freq='D').to_series()
    >>> s.dt.dayofweek
    2016-12-31    5
    2017-01-01    6
    2017-01-02    0
    2017-01-03    1
    2017-01-04    2
    2017-01-05    3
    2017-01-06    4
    2017-01-07    5
    2017-01-08    6
    Freq: D, dtype: int64
    ZdowZdoyz.
        The ordinal day of the year.
        qz*
        The quarter of the date.
        Zdimz2
        The number of days in the month.
        a  
        Indicates whether the date is the {first_or_last} day of the month.

        Returns
        -------
        Series or array
            For Series, returns a Series with boolean values.
            For DatetimeIndex, returns a boolean array.

        See Also
        --------
        is_month_start : Return a boolean indicating whether the date
            is the first day of the month.
        is_month_end : Return a boolean indicating whether the date
            is the last day of the month.

        Examples
        --------
        This method is available on Series with datetime values under
        the ``.dt`` accessor, and directly on DatetimeIndex.

        >>> s = pd.Series(pd.date_range("2018-02-27", periods=3))
        >>> s
        0   2018-02-27
        1   2018-02-28
        2   2018-03-01
        dtype: datetime64[ns]
        >>> s.dt.is_month_start
        0    False
        1    False
        2    True
        dtype: bool
        >>> s.dt.is_month_end
        0    False
        1    True
        2    False
        dtype: bool

        >>> idx = pd.date_range("2018-02-27", periods=3)
        >>> idx.is_month_start
        array([False, False, True])
        >>> idx.is_month_end
        array([False, True, False])
    first)Zfirst_or_lastlasta  
        Indicator for whether the date is the first day of a quarter.

        Returns
        -------
        is_quarter_start : Series or DatetimeIndex
            The same type as the original data with boolean values. Series will
            have the same name and index. DatetimeIndex will have the same
            name.

        See Also
        --------
        quarter : Return the quarter of the date.
        is_quarter_end : Similar property for indicating the quarter start.

        Examples
        --------
        This method is available on Series with datetime values under
        the ``.dt`` accessor, and directly on DatetimeIndex.

        >>> df = pd.DataFrame({'dates': pd.date_range("2017-03-30",
        ...                   periods=4)})
        >>> df.assign(quarter=df.dates.dt.quarter,
        ...           is_quarter_start=df.dates.dt.is_quarter_start)
               dates  quarter  is_quarter_start
        0 2017-03-30        1             False
        1 2017-03-31        1             False
        2 2017-04-01        2              True
        3 2017-04-02        2             False

        >>> idx = pd.date_range('2017-03-30', periods=4)
        >>> idx
        DatetimeIndex(['2017-03-30', '2017-03-31', '2017-04-01', '2017-04-02'],
                      dtype='datetime64[ns]', freq='D')

        >>> idx.is_quarter_start
        array([False, False,  True, False])
        a  
        Indicator for whether the date is the last day of a quarter.

        Returns
        -------
        is_quarter_end : Series or DatetimeIndex
            The same type as the original data with boolean values. Series will
            have the same name and index. DatetimeIndex will have the same
            name.

        See Also
        --------
        quarter : Return the quarter of the date.
        is_quarter_start : Similar property indicating the quarter start.

        Examples
        --------
        This method is available on Series with datetime values under
        the ``.dt`` accessor, and directly on DatetimeIndex.

        >>> df = pd.DataFrame({'dates': pd.date_range("2017-03-30",
        ...                    periods=4)})
        >>> df.assign(quarter=df.dates.dt.quarter,
        ...           is_quarter_end=df.dates.dt.is_quarter_end)
               dates  quarter    is_quarter_end
        0 2017-03-30        1             False
        1 2017-03-31        1              True
        2 2017-04-01        2             False
        3 2017-04-02        2             False

        >>> idx = pd.date_range('2017-03-30', periods=4)
        >>> idx
        DatetimeIndex(['2017-03-30', '2017-03-31', '2017-04-01', '2017-04-02'],
                      dtype='datetime64[ns]', freq='D')

        >>> idx.is_quarter_end
        array([False,  True, False, False])
        a~  
        Indicate whether the date is the first day of a year.

        Returns
        -------
        Series or DatetimeIndex
            The same type as the original data with boolean values. Series will
            have the same name and index. DatetimeIndex will have the same
            name.

        See Also
        --------
        is_year_end : Similar property indicating the last day of the year.

        Examples
        --------
        This method is available on Series with datetime values under
        the ``.dt`` accessor, and directly on DatetimeIndex.

        >>> dates = pd.Series(pd.date_range("2017-12-30", periods=3))
        >>> dates
        0   2017-12-30
        1   2017-12-31
        2   2018-01-01
        dtype: datetime64[ns]

        >>> dates.dt.is_year_start
        0    False
        1    False
        2    True
        dtype: bool

        >>> idx = pd.date_range("2017-12-30", periods=3)
        >>> idx
        DatetimeIndex(['2017-12-30', '2017-12-31', '2018-01-01'],
                      dtype='datetime64[ns]', freq='D')

        >>> idx.is_year_start
        array([False, False,  True])
        a{  
        Indicate whether the date is the last day of the year.

        Returns
        -------
        Series or DatetimeIndex
            The same type as the original data with boolean values. Series will
            have the same name and index. DatetimeIndex will have the same
            name.

        See Also
        --------
        is_year_start : Similar property indicating the start of the year.

        Examples
        --------
        This method is available on Series with datetime values under
        the ``.dt`` accessor, and directly on DatetimeIndex.

        >>> dates = pd.Series(pd.date_range("2017-12-30", periods=3))
        >>> dates
        0   2017-12-30
        1   2017-12-31
        2   2018-01-01
        dtype: datetime64[ns]

        >>> dates.dt.is_year_end
        0    False
        1     True
        2    False
        dtype: bool

        >>> idx = pd.date_range("2017-12-30", periods=3)
        >>> idx
        DatetimeIndex(['2017-12-30', '2017-12-31', '2018-01-01'],
                      dtype='datetime64[ns]', freq='D')

        >>> idx.is_year_end
        array([False,  True, False])
        a  
        Boolean indicator if the date belongs to a leap year.

        A leap year is a year, which has 366 days (instead of 365) including
        29th of February as an intercalary day.
        Leap years are years which are multiples of four with the exception
        of years divisible by 100 but not by 400.

        Returns
        -------
        Series or ndarray
             Booleans indicating if dates belong to a leap year.

        Examples
        --------
        This method is available on Series with datetime values under
        the ``.dt`` accessor, and directly on DatetimeIndex.

        >>> idx = pd.date_range("2012-01-01", "2015-01-01", freq="Y")
        >>> idx
        DatetimeIndex(['2012-12-31', '2013-12-31', '2014-12-31'],
                      dtype='datetime64[ns]', freq='A-DEC')
        >>> idx.is_leap_year
        array([ True, False, False])

        >>> dates_series = pd.Series(idx)
        >>> dates_series
        0   2012-12-31
        1   2013-12-31
        2   2014-12-31
        dtype: datetime64[ns]
        >>> dates_series.dt.is_leap_year
        0     True
        1    False
        2    False
        dtype: bool
        c                 C  s   t | j}t | j}t | j}|dk }||  d8  < ||  d7  < |t d| d d  d|  t |d  t |d	  t |d
  d | j| jd  | j	d  | j
d d  | jd d  d  S )z
        Convert Datetime Array to float64 ndarray of Julian Dates.
        0 Julian date is noon January 1, 4713 BC.
        https://en.wikipedia.org/wiki/Julian_day
        r   r   rH      i     im     d   i  g   C:A<   i  i@B i ʚ;   )r   asarrayrm   rI   rn   Zfixr   ro   rp   rq   r|   r}   )rX   rm   rI   rn   ZtestarrrC   rC   rD   to_julian_dateS  s@    zDatetimeArray.to_julian_dater   int)ddofkeepdimsskipnac           	      C  s2   ddl m} || jd}|j||||||dS )Nr   r)  r   )axisr   outrJ  rK  rL  )r$  r@   r   r   std)	rX   rM  r   rN  rJ  rK  rL  r@   ZtdarC   rC   rD   rO  v  s         zDatetimeArray.std)NFr   r   N)F)F)N)T)r   N)r   r   )N)N)N)NNNr   FT)cr^   
__module____qualname__r_   Z_typr   r   r   r   rd   Z_recognized_scalarsr"   Z_is_recognized_dtypeZ_infer_matchesrO   __annotations__rU   r~   r   r   r   Z__array_priority__r   r   r   classmethodr   r   r
   r   r   r   r   r   r   r   r`   r   rB   setterr   r   r   r   r  r   r   Zravel_compatr
  r  r   r  r  r  rN   r   r   r#  r   r   r*  r   r   r   r   re   r4  rr   rs   rb   rm   rI   rn   ro   rp   rq   r|   r}   Z_dayofweek_docrv   ru   rt   rx   rw   ry   rz   r{   Z_is_month_docr  rf   rg   rh   ri   rj   rk   rl   rH  rO  __classcell__rC   rC   r   rD   rc      s  
"
	I 
,     j

   L 4)G 

.
",  
  
**,,*%      rc   .zLiteral[False]r   )allow_objectrequire_iso8601r   c                 C  s   d S r   rC   r   rV  rW  rC   rC   rD   sequence_to_datetimes  s    rY  zLiteral[True]znp.ndarray | DatetimeArrayc                 C  s   d S r   rC   rX  rC   rC   rD   rY    s    Fc                 C  s@   t | |d|d\}}}|jtkr$|S t|}tj|||d}|S )zV
    Parse/convert the passed data to either DatetimeArray or np.ndarray[object].
    TrV  allow_mixedrW  r   )r   r   r   rE   rc   r   )r   rV  rW  rZ   rB   rQ   r   ZdtarC   rC   rD   rY    s    
r   rZ  c                C  s  d}
t |}t|}t||}t| dsPt| dkr@t| } t| } d}n t	| t
rdtdnt| dd} t	| tr| jdtd	} nt	| tjtfst| } t	| tr| j}
t| |\} }t| dd}t|st|st|r~d}tj| dd
dkr| tj} njt| |||||	d\} }|rP|rPt|  d|} |  t!} n(|r\|}n|rx| j"t#krx| ddfS | j"}t$|rt%|| j&}| j'}nt(|rt| d| } | j"t!krt)*| } d}|dk	r t|}tj+|  d||d} |  t!} | j"t!kst,| j"| }n6|r,t|}| j"t-krH| jtjdd} |  t!}|r`|. }t	|tjszt,t/||j"dkst,|j"t|| |||
fS )af  
    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.tzconversion.tz_localize_to_utc.
    allow_object : bool, default False
        Whether to return an object-dtype ndarray instead of raising if the
        data contains more than one timezone.
    allow_mixed : bool, default False
        Interpret integers as timestamps when datetime objects are also present.
    require_iso8601 : bool, default False
        Only consider ISO-8601 formats when parsing strings.

    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
    Nr   r   Fz0Cannot create a DatetimeArray from a MultiIndex.Tr   r   r   )rL  integer)r   r   rV  r[  rW  r   r   r   r   r   )0r   r   r!  validate_tz_from_dtyper  r   r   listrG  r   r0   r   r7   r6   r   r   r   r3   rc   rQ   maybe_convert_dtyper   r)   r,   r+   r
   Zinfer_dtyper   r   objects_to_datetime64nsr   r  r   r   r   r   r%   _maybe_infer_tzrB   r   r#   r   Zensure_datetime64nsr   r   r   r   r   )r   r   r   rB   r   r   r   rV  r[  rW  r   Z
data_dtypeinferred_tzrZ   rC   rC   rD   r     s    .















  



r   r   )r   rW  rV  r[  c                 C  s>  |dkst tj| dtjd} | j}|jr.dnd}	z6tj| d||||||d\}
}|
j	| j
|	d}
W n| tk
r } z^z<t| d\}}|j	| j
|	d}|d	|fW  W Y "S  ttfk
r   |Y nX W 5 d
}~X Y nX |d
k	 r|
d	|fS t|
r|
|fS t|
r2|r(|
|fS t|
nt|
d
S )a  
    Convert data to array of timestamps.

    Parameters
    ----------
    data : np.ndarray[object]
    dayfirst : bool
    yearfirst : bool
    utc : bool, default False
        Whether to convert timezone-aware timestamps to UTC.
    errors : {'raise', 'ignore', 'coerce'}
    require_iso8601 : bool, default False
    allow_object : bool
        Whether to return an object-dtype ndarray instead of raising if the
        data contains more than one timezone.
    allow_mixed : bool, default False
        Interpret integers as timestamps when datetime objects are also present.

    Returns
    -------
    result : ndarray
        np.int64 dtype if returned values represent UTC timestamps
        np.datetime64[ns] if returned values represent wall times
        object if mixed timezones
    inferred_tz : tzinfo or None

    Raises
    ------
    ValueError : if data cannot be converted to datetimes
    )r   r   ZcoerceF)r   r   FCK)errorsutcr   r   rW  r[  )orderr   N)r   r   r   object_flagsf_contiguousr   Zarray_to_datetimer  r  r  r   r   Zdatetime_to_datetime64r   r   r#   r)   )r   r   r   rg  rf  rW  rV  r[  rj  rh  rZ   Z	tz_parsederrrY   rC   rC   rD   r`  O  s>    (
	



r`  r   c                 C  s   t | ds| |fS t| jr,| t} d}nt| js@t| jrTtd| j dn`t| jrhtdnLt	| jr| j
j| jtdj} d}n(t| jrt| jstj| tjd} d}| |fS )aN  
    Convert data based on dtype conventions, issuing deprecation warnings
    or errors where appropriate.

    Parameters
    ----------
    data : np.ndarray or pd.Index
    copy : bool

    Returns
    -------
    data : np.ndarray or pd.Index
    copy : bool

    Raises
    ------
    TypeError : PeriodDType data is passed
    r   Fzdtype z& cannot be converted to datetime64[ns]zFPassing PeriodDtype data is invalid. Use `data.to_timestamp()` insteadrJ   r   )r  r(   r   r   r   r-   r    r   r*   r!   
categoriesZtakecodesr   Z_valuesr'   r%   r   r   ri  )r   r   rC   rC   rD   r_    s$    




r_  r   )rB   rb  r   c                 C  s<   | dkr|} n*|dkrn t | |s8td| d|  | S )aV  
    If a timezone is inferred from data, check that it is compatible with
    the user-provided timezone, if any.

    Parameters
    ----------
    tz : tzinfo or None
    inferred_tz : tzinfo or None

    Returns
    -------
    tz : tzinfo or None

    Raises
    ------
    TypeError : if both timezones are present but do not match
    Nzdata is already tz-aware z, unable to set specified tz: )r   r   r   )rB   rb  rC   rC   rD   ra    s    ra  c                 C  sd   | dk	r`t | } t| tdr,d}t|t| tjr@| tksPt| tjtfs`td|  d| S )a  
    Check that a dtype, if passed, represents either a numpy datetime64[ns]
    dtype or a pandas DatetimeTZDtype.

    Parameters
    ----------
    dtype : object

    Returns
    -------
    dtype : None, numpy.dtype, or DatetimeTZDtype

    Raises
    ------
    ValueError : invalid dtype

    Notes
    -----
    Unlike validate_tz_from_dtype, this does _not_ allow non-existent
    tz errors to go through
    NZM8zhPassing in 'datetime64' dtype with no precision is not allowed. Please pass in 'datetime64[ns]' instead.zUnexpected value for 'dtype': 'z0'. Must be 'datetime64[ns]' or DatetimeTZDtype'.)r.   r&   r   r   r   r   r   r/   )r   r   rC   rC   rD   r   	  s     
r   )rB   r   c                 C  s   | dk	rt | tr6zt| } W n tk
r4   Y nX t| dd}|dk	rj|dk	rft||sftd|}|dk	rt	| r|dk	rt||std|S )aU  
    If the given dtype is a DatetimeTZDtype, extract the implied
    tzinfo object from it and check that it does not conflict with the given
    tz.

    Parameters
    ----------
    dtype : dtype, str
    tz : None, tzinfo

    Returns
    -------
    tz : consensus tzinfo

    Raises
    ------
    ValueError : on tzinfo mismatch
    NrB   z-cannot supply both a tz and a dtype with a tzzHcannot supply both a tz and a timezone-naive dtype (i.e. datetime64[ns]))
r   strr/   Zconstruct_from_stringr   r   r   r   r   r#   )r   rB   r   rC   rC   rD   r]  0	  s"    
r]  r   )rF   rG   rB   r   c              
   C  s   zt | |}W n, tk
r< } ztd|W 5 d}~X Y nX t |}t |}|dk	rx|dk	rxt ||stdn|dk	r|}|S )a  
    If a timezone is not explicitly given via `tz`, see if one can
    be inferred from the `start` and `end` endpoints.  If more than one
    of these inputs provides a timezone, require that they all agree.

    Parameters
    ----------
    start : Timestamp
    end : Timestamp
    tz : tzinfo or None

    Returns
    -------
    tz : tzinfo or None

    Raises
    ------
    TypeError : if start and end timezones do not agree
    z>Start and end cannot both be tz-aware with different timezonesNz0Inferred time zone not equal to passed time zone)r   Zinfer_tzinfor   r   r!  r   )rF   rG   rB   rb  rl  rC   rC   rD   r   _	  s     


r   zTimestamp | None)rF   rG   r   c                 C  sb   d}| d k	r.|r|   } d}n|o,|  tk}|d k	rX|rH|  }d}n|oV| tk}| ||fS )NT)r   r   	_midnight)rF   rG   r   r   rC   rC   rD   r   	  s    r   c                 C  sV   |dkrR|dk	rR|dkr|nd}||dd}t |ts>|dkrF||d< | jf |} | S )a  
    Localize a start or end Timestamp to the timezone of the corresponding
    start or end Timestamp

    Parameters
    ----------
    ts : start or end Timestamp to potentially localize
    is_none : argument that should be None
    is_not_none : argument that should not be None
    freq : Tick, DateOffset, or None
    tz : str, timezone object or None
    ambiguous: str, localization behavior for ambiguous times
    nonexistent: str, localization behavior for nonexistent times

    Returns
    -------
    ts : Timestamp
    Nr   F)r   r   rB   rB   )r   r;   r   )r   Zis_noneZis_not_nonerQ   rB   r   r   Zlocalize_argsrC   rC   rD   r   	  s    r   c                 c  sb  t |}t| } | tk	r| nd} t|}|tk	r4|nd}| rR|| sR|| } n|rj||sj||}|dkr|| k r|jdkrd}d}|dkr| |d |  }| dkr||d |  } | }|jdkr||kr^|V  ||krq^||}||krtd| d|}qnJ||kr^|V  ||kr2q^||}||krVtd| d|}qdS )a  
    Generates a sequence of dates corresponding to the specified time
    offset. Similar to dateutil.rrule except uses pandas DateOffset
    objects to represent time increments.

    Parameters
    ----------
    start : datetime, (default None)
    end : datetime, (default None)
    periods : int, (default None)
    offset : DateOffset, (default BDay())

    Notes
    -----
    * This method is faster for generating weekdays than dateutil.rrule
    * At least two of (start, end, periods) must be specified.
    * If both start and end are specified, the returned dates will
    satisfy start <= date <= end.

    Returns
    -------
    dates : generator object
    Nr   r   zOffset z did not increment datez did not decrement date)	r   r   r   Zis_on_offsetZrollforwardrollbacknapplyr   )rF   rG   r   r   curZ	next_daterC   rC   rD   r   	  sD    







r   )N)..)..)FF)NFNFFr   )Fr   FFF)j
__future__r   r   r   r   r   typingr   r   r	   r   Znumpyr   Zpandas._libsr
   r   Zpandas._libs.arraysr   Zpandas._libs.tslibsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zpandas.errorsr   Zpandas.core.dtypes.castr   Zpandas.core.dtypes.commonr   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   Zpandas.core.dtypes.dtypesr/   Zpandas.core.dtypes.genericr0   Zpandas.core.dtypes.missingr1   Zpandas.core.algorithmsr2   r$  r3   r4   r   Zpandas.core.arrays._rangesr5   Zpandas.core.arrays.integerr6   Zpandas.core.commoncorecommonr   Zpandas.core.constructionr7   Zpandas.tseries.frequenciesr8   Zpandas.tseries.offsetsr9   r:   r;   r<   r3  r>   r?   r@   rp  rE   rb   ZTimelikeOpsZDatelikeOpsrc   rY  r   r`  r_  ra  r   r]  r   r   r   r   rC   rC   rC   rD   <module>   s   DL

&                             	 $     \=*/+!