U
    Cvf                  D   @  s  d Z ddlmZ ddlZddlmZmZ ddlmZ ddlm	Z	 ddl
ZddlZddlmZmZ ddlmZmZmZmZ dd	lmZmZ dd
lmZ zddlZW n ek
r   dZY nX dpddZG dd dZG dd deZdd Z dd Z!dd Z"dd Z#dqddZ$drddZ%d d! Z&G d"d# d#eZ'G d$d% d%eZ(d&d'd(d)d*d+d,d-d.d/d0d1d2Z)G d3d4 d4eZ*G d5d6 d6e*Z+G d7d8 d8e*Z,G d9d: d:eZ-G d;d< d<e-Z.G d=d> d>e-Z/G d?d@ d@eZ0G dAdB dBeZ1G dCdD dDeZ2G dEdF dFeZ3G dGdH dHeZ4G dIdJ dJeZ5e/e.e/e.ee,dKdLee+dMdLe(e'e0e1e2e2e3e4e4e5e5ee.dMdLee.dNdLee.ddLee.dOdLee.dPdLee.dQdLee.dRdLee.dSdLee.dTdLee.dUdLee.dVdLee.dKdLee/dMdLee/dNdLee/ddLee/dOdLee/dPdLee/dQdLee/dRdLee/dSdLee/dTdLee/dUdLee/dVdLee/dKdLee+dMdLee+dNdLee+ddLee+dOdLee+dPdLee+dQdLee+dRdLee+dSdLee+dTdLee+dUdLee+dVdLee+dKdLee,dMdLee,dNdLee,ddLee,dOdLee,dPdLee,dQdLee,dRdLee,dSdLee,dTdLee,dUdLee,dVdLee,dKdLdWAZ6dX7e68 Z9dYe9 dZZ:e0e1e2e3fZ;d[d\ Z<dsd]d^Z=d_d` Z>dadb Z?dcdd Z@dedf ZAdtdjdkZBdudldmZCdvdndoZDdS )wz8Time offset classes for use with cftime.datetime objects    )annotationsN)datetime	timedelta)partial)ClassVar)CFTimeIndex_parse_iso8601_with_reso)_is_standard_calendar_should_cftime_be_usedconvert_time_or_go_backformat_cftime_datetime)_contains_datetime_like_objectsis_np_datetime_like)count_not_noneTc              
   C  sZ   t dkrtdnDt| r$|s$tjS t jt jt jt jt jt j	t j
t jt jd	}||  S dS )z6Return the cftime date type for a given calendar name.Nz8cftime is required for dates with non-standard calendars)	ZnoleapZ360_dayZ365_dayZ366_dayZ	gregorianZproleptic_gregorianZjulianZall_leapstandard)cftimeImportErrorr	   pd	TimestampZDatetimeNoLeapZDatetime360DayZDatetimeAllLeapZDatetimeGregorianDatetimeProlepticGregorianZDatetimeJulian)calendar
use_cftimeZ	calendars r   @/tmp/pip-unpacked-wheel-h316xyqg/xarray/coding/cftime_offsets.pyget_date_typeD   s    
r   c                   @  s   e Zd ZU dZded< dZded< d,dddd	Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ ZdS )-BaseCFTimeOffsetNzClassVar[str | None]_freq_day_option   intnc                 C  s&   t |tstdt||| _d S )NzXThe provided multiple 'n' must be an integer. Instead a value of type {!r} was provided.)
isinstancer   	TypeErrorformattyper!   )selfr!   r   r   r   __init__^   s    
zBaseCFTimeOffset.__init__c                 C  s   | j S N)r   r&   r   r   r   	rule_codef   s    zBaseCFTimeOffset.rule_codec                 C  s   | j |j ko|  | kS r(   )r!   r*   r&   otherr   r   r   __eq__i   s    zBaseCFTimeOffset.__eq__c                 C  s
   | |k S r(   r   r+   r   r   r   __ne__l   s    zBaseCFTimeOffset.__ne__c                 C  s
   |  |S r(   )	__apply__r+   r   r   r   __add__o   s    zBaseCFTimeOffset.__add__c                 C  sR   t d krtdt|t jr&tdn(t|t| krJt| | j|j S tS d S )NNo module named 'cftime'z5Cannot subtract a cftime.datetime from a time offset.)r   ModuleNotFoundErrorr"   r   r#   r%   r!   NotImplementedr+   r   r   r   __sub__r   s    
zBaseCFTimeOffset.__sub__c                 C  s"   t |tstS t| || j dS )Nr    )r"   r   r3   r%   r!   r+   r   r   r   __mul__}   s    
zBaseCFTimeOffset.__mul__c                 C  s   | d S )Nr   r)   r   r   r   __neg__   s    zBaseCFTimeOffset.__neg__c                 C  s
   |  |S r(   )r5   r+   r   r   r   __rmul__   s    zBaseCFTimeOffset.__rmul__c                 C  s
   |  |S r(   )r0   r+   r   r   r   __radd__   s    zBaseCFTimeOffset.__radd__c                 C  s,   t |tr"t| t|kr"td|  | S )Nz1Cannot subtract cftime offsets of differing types)r"   r   r%   r#   r+   r   r   r   __rsub__   s    zBaseCFTimeOffset.__rsub__c                 C  s   t S r(   )r3   r)   r   r   r   r/      s    zBaseCFTimeOffset.__apply__c                 C  s   | | |  }||kS xCheck if the given date is in the set of possible dates created
        using a length-one version of this offset class.r   )r&   dateZ	test_dater   r   r   onOffset   s    zBaseCFTimeOffset.onOffsetc                 C  s    |  |r|S |t|   S d S r(   r>   r%   r&   r=   r   r   r   rollforward   s    
zBaseCFTimeOffset.rollforwardc                 C  s    |  |r|S |t|   S d S r(   r?   r@   r   r   r   rollback   s    
zBaseCFTimeOffset.rollbackc                 C  s   dt | j d| j dS )N<: n=>)r%   __name__r!   r)   r   r   r   __str__   s    zBaseCFTimeOffset.__str__c                 C  s   t | S r(   )strr)   r   r   r   __repr__   s    zBaseCFTimeOffset.__repr__c                 C  s   t || jS r(   )_get_day_of_monthr   r+   r   r   r   _get_offset_day   s    z BaseCFTimeOffset._get_offset_day)r   )rF   
__module____qualname__r   __annotations__r   r'   r*   r-   r.   r0   r4   r5   r7   r8   r9   r:   r/   r>   rA   rB   rG   rI   rK   r   r   r   r   r   Z   s(   
r   c                   @  s$   e Zd Zdd Zdd Zdd ZdS )Tickc                 C  s   t | }|tttttfkr"tdt | tkr<t| jd S t | tkrVt| jd S t | tkrpt| jd S t | tkrt| jd S t | tkrt| jd S d S )Nz5Could not convert to integer offset at any resolution   <   i  )	r%   DayHourMinuteSecondMillisecond
ValueErrorr!   Microsecond)r&   	self_typer   r   r   _next_higher_resolution   s    zTick._next_higher_resolutionc                 C  sj   t |ttfstS t |trV|| j }t|d drFt| t|S |  }|| S t| || j dS )Nr   r   r    )	r"   r   floatr3   r!   npiscloser%   rZ   )r&   r,   r!   Znew_selfr   r   r   r5      s    

zTick.__mul__c                 C  s   t dS )z:All Tick subclasses must implement an as_timedelta method.N)NotImplementedErrorr)   r   r   r   as_timedelta   s    zTick.as_timedeltaN)rF   rL   rM   rZ   r5   r_   r   r   r   r   rO      s   rO   c                 C  s8   |dkrdS |dkrt | S |dkr,t nt|dS )a\  Find the day in `other`'s month that satisfies a BaseCFTimeOffset's
    onOffset policy, as described by the `day_option` argument.

    Parameters
    ----------
    other : cftime.datetime
    day_option : 'start', 'end'
        'start': returns 1
        'end': returns last day of the month

    Returns
    -------
    day_of_month : int

    startr   endN)_days_in_monthr^   rW   )r,   
day_optionr   r   r   rJ      s    rJ   c                 C  sJ   | j dkr"t| | jd dd}nt| | j| j d d}|tdd jS )z1The number of days in the month of the given date   r   days)monthr%   yearr   day)r=   	referencer   r   r   rb      s    
rb   c                 C  s6   |dkr| |k r|d }n|dkr2| |kr2|d }|S )zAdjust the number of times a monthly offset is applied based
    on the day of a given date, and the reference day provided.
    r   r   r   )Z	other_dayr!   reference_dayr   r   r   _adjust_n_months   s
    
rl   c                 C  sZ   |dkr0| j |k s&| j |krV| j|k rV|d8 }n&| j |ksN| j |krV| j|krV|d7 }|S )zpAdjust the number of times an annual offset is applied based on
    another date, and the reference day providedr   r   )rg   ri   )r,   r!   rg   rk   r   r   r   _adjust_n_years  s    
rm   r`   c                 C  s   t dkrtd| j| d }| j| d }|dkr@d}|d }| j| }|dkrXd}n*|dkrzt| ||d}t|}nt|| j|||dS )	zEShift the date to a month start or end a given number of months away.Nr1   rd   r   r   r`   ra   )rh   rg   ri   )r   r2   rg   rh   r%   rb   rW   replace)r=   monthsrc   Z
delta_yearrg   rh   ri   rj   r   r   r   _shift_month  s    

rp      c                 C  sp   | j | ||  }|dkrD|dk s:|dkrl| jt| |k rl|d8 }n(|dksd|dkrl| jt| |krl|d7 }|S )a  Possibly increment or decrement the number of periods to shift
    based on rollforward/rollbackward conventions.

    Parameters
    ----------
    other : cftime.datetime
    n : number of periods to increment, before adjusting for rolling
    month : int reference month giving the first month of the year
    day_option : 'start', 'end'
        The convention to use in finding the day in a given month against
        which to compare for rollforward/rollbackward decisions.
    modby : int 3 for quarters, 12 for years

    Returns
    -------
    n : int number of periods to increment

    See Also
    --------
    _get_day_of_month : Find the day in a month provided an offset.
    r   r   )rg   ri   rJ   )r,   r!   rg   rc   modbymonths_sincer   r   r   roll_qtrday+  s    
rt   c                 C  sR   | d kr|n| }t |ts*td|n$d|  kr>dksNn td||S )Nz_'self.month' must be an integer value between 1 and 12.  Instead, it was set to a value of {!r}r   rd   )r"   r   r#   r$   rW   )rg   Zdefault_monthZresult_monthr   r   r   _validate_monthT  s    
ru   c                   @  s    e Zd ZdZdd Zdd ZdS )
MonthBeginMSc                 C  s   t |j| jd}t||dS )Nr   r`   )rl   ri   r!   rp   r&   r,   r!   r   r   r   r/   h  s    zMonthBegin.__apply__c                 C  s
   |j dkS r<   r   ri   r@   r   r   r   r>   l  s    zMonthBegin.onOffsetNrF   rL   rM   r   r/   r>   r   r   r   r   rv   e  s   rv   c                   @  s    e Zd ZdZdd Zdd ZdS )MonthEndMc                 C  s    t |j| jt|}t||dS )Nra   )rl   ri   r!   rb   rp   rx   r   r   r   r/   u  s    zMonthEnd.__apply__c                 C  s   |j t|kS r;   )ri   rb   r@   r   r   r   r>   y  s    zMonthEnd.onOffsetNr{   r   r   r   r   r|   r  s   r|   ZJANZFEBZMARZAPRZMAYZJUNZJULZAUGZSEPZOCTZNOVZDEC)r      rq                  	   
      rd   c                   @  s\   e Zd ZU dZded< ded< ddd	Zd
d Zdd Zdd Zdd Z	dd Z
dd ZdS )QuarterOffsetz>Quarter representation copied off of pandas/tseries/offsets.pyClassVar[str]r   ClassVar[int]_default_monthr   Nc                 C  s   t | | t|| j| _d S r(   r   r'   ru   r   rg   r&   r!   rg   r   r   r   r'     s    zQuarterOffset.__init__c                 C  sF   |j d | j d  }t|| j| j | jdd}|d | }t||| jS )Nrq   )rc   rr   )rg   rt   r!   r   rp   )r&   r,   rs   Zqtrsro   r   r   r   r/     s        zQuarterOffset.__apply__c                 C  s(   |j | j  d }|dko&|j| |kS )r<   rq   r   )rg   ri   rK   )r&   r=   Z	mod_monthr   r   r   r>     s    zQuarterOffset.onOffsetc                 C  sd   t d krtdt|t jr&tdn:t|t| kr\|j| jkr\t| | j|j | jdS tS d S Nr1   z,Cannot subtract cftime.datetime from offset.rg   	r   r2   r"   r   r#   r%   rg   r!   r3   r+   r   r   r   r4     s    
zQuarterOffset.__sub__c                 C  s&   t |trtS t| || j | jdS N)r!   rg   r"   r[   r3   r%   r!   rg   r+   r   r   r   r5     s    
zQuarterOffset.__mul__c                 C  s   | j  dt| j  S N-r   _MONTH_ABBREVIATIONSrg   r)   r   r   r   r*     s    zQuarterOffset.rule_codec                 C  s"   dt | j d| j d| j dS NrC   rD   z, month=rE   r%   rF   r!   rg   r)   r   r   r   rG     s    zQuarterOffset.__str__)r   N)rF   rL   rM   __doc__rN   r'   r/   r>   r4   r5   r*   rG   r   r   r   r   r     s   

r   c                   @  s(   e Zd ZdZdZdZdd Zdd ZdS )	QuarterBeginrq   QSr`   c                 C  s"   |  |r|S |t| jd S dS )z-Roll date forward to nearest start of quarterr   Nr>   r   rg   r@   r   r   r   rA     s    
zQuarterBegin.rollforwardc                 C  s"   |  |r|S |t| jd S dS )z.Roll date backward to nearest start of quarterr   Nr   r@   r   r   r   rB     s    
zQuarterBegin.rollbackNrF   rL   rM   r   r   r   rA   rB   r   r   r   r   r     s
   r   c                   @  s(   e Zd ZdZdZdZdd Zdd ZdS )	
QuarterEndrq   Qra   c                 C  s"   |  |r|S |t| jd S dS )z+Roll date forward to nearest end of quarterr   Nr>   r   rg   r@   r   r   r   rA     s    
zQuarterEnd.rollforwardc                 C  s"   |  |r|S |t| jd S dS )z,Roll date backward to nearest end of quarterr   Nr   r@   r   r   r   rB     s    
zQuarterEnd.rollbackNr   r   r   r   r   r     s
   r   c                   @  sX   e Zd ZU ded< ded< ded< ddd	Zd
d Zdd Zdd Zdd Zdd Z	dS )
YearOffsetr   r   r   r   r   r   Nc                 C  s   t | | t|| j| _d S r(   r   r   r   r   r   r'     s    zYearOffset.__init__c                 C  s@   t || j}t|| j| j|}|d | j|j  }t||| jS )Nrd   )rJ   r   rm   r!   rg   rp   )r&   r,   rk   Zyearsro   r   r   r   r/     s    zYearOffset.__apply__c                 C  sd   t d krtdt|t jr&tdn:t|t| kr\|j| jkr\t| | j|j | jdS tS d S r   r   r+   r   r   r   r4     s    
zYearOffset.__sub__c                 C  s&   t |trtS t| || j | jdS r   r   r+   r   r   r   r5     s    
zYearOffset.__mul__c                 C  s   | j  dt| j  S r   r   r)   r   r   r   r*     s    zYearOffset.rule_codec                 C  s"   dt | j d| j d| j dS r   r   r)   r   r   r   rG     s    zYearOffset.__str__)r   N)
rF   rL   rM   rN   r'   r/   r4   r5   r*   rG   r   r   r   r   r     s   

r   c                   @  s0   e Zd ZdZdZdZdd Zdd Zdd	 Zd
S )	YearBeginASr`   r   c                 C  s   |j dko|j| jkS ry   )ri   rg   r@   r   r   r   r>      s    zYearBegin.onOffsetc                 C  s"   |  |r|S |t| jd S dS )z*Roll date forward to nearest start of yearr   Nr>   r   rg   r@   r   r   r   rA   %  s    
zYearBegin.rollforwardc                 C  s"   |  |r|S |t| jd S dS )z+Roll date backward to nearest start of yearr   Nr   r@   r   r   r   rB   ,  s    
zYearBegin.rollbackN	rF   rL   rM   r   r   r   r>   rA   rB   r   r   r   r   r     s   r   c                   @  s0   e Zd ZdZdZdZdd Zdd Zdd	 Zd
S )YearEndAra   rd   c                 C  s   |j t|ko|j| jkS r;   )ri   rb   rg   r@   r   r   r   r>   9  s    zYearEnd.onOffsetc                 C  s"   |  |r|S |t| jd S dS )z(Roll date forward to nearest end of yearr   Nr>   r   rg   r@   r   r   r   rA   >  s    
zYearEnd.rollforwardc                 C  s"   |  |r|S |t| jd S dS )z)Roll date backward to nearest end of yearr   Nr   r@   r   r   r   rB   E  s    
zYearEnd.rollbackNr   r   r   r   r   r   4  s   r   c                   @  s    e Zd ZdZdd Zdd ZdS )rR   Dc                 C  s   t | jdS )Nre   r   r!   r)   r   r   r   r_   P  s    zDay.as_timedeltac                 C  s   ||    S r(   r_   r+   r   r   r   r/   S  s    zDay.__apply__NrF   rL   rM   r   r_   r/   r   r   r   r   rR   M  s   rR   c                   @  s    e Zd ZdZdd Zdd ZdS )rS   Hc                 C  s   t | jdS )N)hoursr   r)   r   r   r   r_   Z  s    zHour.as_timedeltac                 C  s   ||    S r(   r   r+   r   r   r   r/   ]  s    zHour.__apply__Nr   r   r   r   r   rS   W  s   rS   c                   @  s    e Zd ZdZdd Zdd ZdS )rT   Tc                 C  s   t | jdS )N)minutesr   r)   r   r   r   r_   d  s    zMinute.as_timedeltac                 C  s   ||    S r(   r   r+   r   r   r   r/   g  s    zMinute.__apply__Nr   r   r   r   r   rT   a  s   rT   c                   @  s    e Zd ZdZdd Zdd ZdS )rU   Sc                 C  s   t | jdS )N)secondsr   r)   r   r   r   r_   n  s    zSecond.as_timedeltac                 C  s   ||    S r(   r   r+   r   r   r   r/   q  s    zSecond.__apply__Nr   r   r   r   r   rU   k  s   rU   c                   @  s    e Zd ZdZdd Zdd ZdS )rV   Lc                 C  s   t | jdS )N)Zmillisecondsr   r)   r   r   r   r_   x  s    zMillisecond.as_timedeltac                 C  s   ||    S r(   r   r+   r   r   r   r/   {  s    zMillisecond.__apply__Nr   r   r   r   r   rV   u  s   rV   c                   @  s    e Zd ZdZdd Zdd ZdS )rX   Uc                 C  s   t | jdS )N)microsecondsr   r)   r   r   r   r_     s    zMicrosecond.as_timedeltac                 C  s   ||    S r(   r   r+   r   r   r   r/     s    zMicrosecond.__apply__Nr   r   r   r   r   rX     s   rX   rd   r   r   r~   r   r   r   r   r   r   r   r   )Ar   r   YZYSr   r   r}   rw   r   r   r   minr   r   msr   uszAS-JANzAS-FEBzAS-MARzAS-APRzAS-MAYzAS-JUNzAS-JULzAS-AUGzAS-SEPzAS-OCTzAS-NOVzAS-DECzA-JANzA-FEBzA-MARzA-APRzA-MAYzA-JUNzA-JULzA-AUGzA-SEPzA-OCTzA-NOVzA-DECzQS-JANzQS-FEBzQS-MARzQS-APRzQS-MAYzQS-JUNzQS-JULzQS-AUGzQS-SEPzQS-OCTzQS-NOVzQS-DECzQ-JANzQ-FEBzQ-MARzQ-APRzQ-MAYzQ-JUNzQ-JULzQ-AUGzQ-SEPzQ-OCTzQ-NOVzQ-DEC|z!^((?P<multiple>\d+)|())(?P<freq>(z))$c                 C  sr   t | tr| S ztt|  }W n tk
r>   tdY nX |d } |d }|dkr\dnt|}t	|  |dS )zOConvert a frequency string to the appropriate subclass of
    BaseCFTimeOffset.z!Invalid frequency string providedfreqmultipleNr   r    )
r"   r   rematch_PATTERN	groupdictAttributeErrorrW   r   _FREQUENCIES)r   Z	freq_dataZ	multiplesr   r   r   	to_offset  s    
r   c                 C  s   t d krtdt| tr@|d kr*tdtt|| \}}|S t| t jrP| S t| ttj	frnt j
|   S td| d S )Nr1   zTIf converting a string to a cftime.datetime object, a calendar type must be providedzUdate_str_or_date must be a string or a subclass of cftime.datetime. Instead got {!r}.)r   r2   r"   rH   rW   r   r   r   r   r   r   	timetupler#   r$   )Zdate_str_or_dater   r=   _r   r   r   to_cftime_datetime  s$    
r   c                 C  s   | j dddddS )z Round datetime down to midnight.r   )hourminutesecondmicrosecond)rn   )r=   r   r   r   normalize_date   s    r   c                 C  s   |rt | S | S dS )z5Round datetime down to midnight if normalize is True.N)r   )r=   	normalizer   r   r   _maybe_normalize_date  s    r   c                 C  sT   t dkrtd||   }tjd||dd}dt|  }| j}t j|||ddS )zGenerate an equally-spaced sequence of cftime.datetime objects between
    and including two dates (whose length equals the number of periods).Nr1   g        T)Zendpointzseconds since )unitsr   Zonly_use_cftime_datetimes)r   r2   total_secondsr\   Zlinspacer   r   Znum2date)r`   ra   periodsr   valuesr   r   r   r   r   _generate_linear_range  s       r   c                 c  s   | r| | } |r||}|dkr4|| k r4d}d}|dkrL| |d |  }| dkrd||d |  } | }|jdkr||kr|V  || }||krtd| d|}qrn4||kr|V  || }||krtd| d|}qdS )a   Generate a regular range of cftime.datetime objects with a
    given time offset.

    Adapted from pandas.tseries.offsets.generate_range.

    Parameters
    ----------
    start : cftime.datetime, or None
        Start of range
    end : cftime.datetime, or None
        End of range
    periods : int, or None
        Number of elements in the sequence
    offset : BaseCFTimeOffset
        An offset class designed for working with cftime.datetime objects

    Returns
    -------
    A generator object
    Nr   r   zOffset z did not increment datez did not decrement date)rA   rB   r!   rW   )r`   ra   r   offsetcurrentZ	next_dater   r   r   _generate_range  s2    


r   r   Fr   c                 C  s2  t | |||dkrtd| dk	r6t| |} t| |} |dk	rRt||}t||}|dkrht| ||}n t|}	ttt	| |||	}d}
d}|dkrd}
d}n$|dkrd}
n|dkrd}ntd|
st
|r| dk	r|d	 | kr|d
d }|s&t
|r&|dk	r&|d |kr&|dd }t||dS )a%  Return a fixed frequency CFTimeIndex.

    Parameters
    ----------
    start : str or cftime.datetime, optional
        Left bound for generating dates.
    end : str or cftime.datetime, optional
        Right bound for generating dates.
    periods : int, optional
        Number of periods to generate.
    freq : str or None, default: "D"
        Frequency strings can have multiples, e.g. "5H".
    normalize : bool, default: False
        Normalize start/end dates to midnight before generating date range.
    name : str, default: None
        Name of the resulting index
    closed : {"left", "right"} or None, default: None
        Make the interval closed with respect to the given frequency to the
        "left", "right", or both sides (None).
    calendar : str, default: "standard"
        Calendar type for the datetimes.

    Returns
    -------
    CFTimeIndex

    Notes
    -----
    This function is an analog of ``pandas.date_range`` for use in generating
    sequences of ``cftime.datetime`` objects.  It supports most of the
    features of ``pandas.date_range`` (e.g. specifying how the index is
    ``closed`` on either side, or whether or not to ``normalize`` the start and
    end bounds); however, there are some notable exceptions:

    - You cannot specify a ``tz`` (time zone) argument.
    - Start or end dates specified as partial-datetime strings must use the
      `ISO-8601 format <https://en.wikipedia.org/wiki/ISO_8601>`_.
    - It supports many, but not all, frequencies supported by
      ``pandas.date_range``.  For example it does not currently support any of
      the business-related or semi-monthly frequencies.
    - Compound sub-monthly frequencies are not supported, e.g. '1H1min', as
      these can easily be written in terms of the finest common resolution,
      e.g. '61min'.

    Valid simple frequency strings for use with ``cftime``-calendars include
    any multiples of the following.

    +--------+--------------------------+
    | Alias  | Description              |
    +========+==========================+
    | A, Y   | Year-end frequency       |
    +--------+--------------------------+
    | AS, YS | Year-start frequency     |
    +--------+--------------------------+
    | Q      | Quarter-end frequency    |
    +--------+--------------------------+
    | QS     | Quarter-start frequency  |
    +--------+--------------------------+
    | M      | Month-end frequency      |
    +--------+--------------------------+
    | MS     | Month-start frequency    |
    +--------+--------------------------+
    | D      | Day frequency            |
    +--------+--------------------------+
    | H      | Hour frequency           |
    +--------+--------------------------+
    | T, min | Minute frequency         |
    +--------+--------------------------+
    | S      | Second frequency         |
    +--------+--------------------------+
    | L, ms  | Millisecond frequency    |
    +--------+--------------------------+
    | U, us  | Microsecond frequency    |
    +--------+--------------------------+

    Any multiples of the following anchored offsets are also supported.

    +----------+--------------------------------------------------------------------+
    | Alias    | Description                                                        |
    +==========+====================================================================+
    | A(S)-JAN | Annual frequency, anchored at the end (or beginning) of January    |
    +----------+--------------------------------------------------------------------+
    | A(S)-FEB | Annual frequency, anchored at the end (or beginning) of February   |
    +----------+--------------------------------------------------------------------+
    | A(S)-MAR | Annual frequency, anchored at the end (or beginning) of March      |
    +----------+--------------------------------------------------------------------+
    | A(S)-APR | Annual frequency, anchored at the end (or beginning) of April      |
    +----------+--------------------------------------------------------------------+
    | A(S)-MAY | Annual frequency, anchored at the end (or beginning) of May        |
    +----------+--------------------------------------------------------------------+
    | A(S)-JUN | Annual frequency, anchored at the end (or beginning) of June       |
    +----------+--------------------------------------------------------------------+
    | A(S)-JUL | Annual frequency, anchored at the end (or beginning) of July       |
    +----------+--------------------------------------------------------------------+
    | A(S)-AUG | Annual frequency, anchored at the end (or beginning) of August     |
    +----------+--------------------------------------------------------------------+
    | A(S)-SEP | Annual frequency, anchored at the end (or beginning) of September  |
    +----------+--------------------------------------------------------------------+
    | A(S)-OCT | Annual frequency, anchored at the end (or beginning) of October    |
    +----------+--------------------------------------------------------------------+
    | A(S)-NOV | Annual frequency, anchored at the end (or beginning) of November   |
    +----------+--------------------------------------------------------------------+
    | A(S)-DEC | Annual frequency, anchored at the end (or beginning) of December   |
    +----------+--------------------------------------------------------------------+
    | Q(S)-JAN | Quarter frequency, anchored at the end (or beginning) of January   |
    +----------+--------------------------------------------------------------------+
    | Q(S)-FEB | Quarter frequency, anchored at the end (or beginning) of February  |
    +----------+--------------------------------------------------------------------+
    | Q(S)-MAR | Quarter frequency, anchored at the end (or beginning) of March     |
    +----------+--------------------------------------------------------------------+
    | Q(S)-APR | Quarter frequency, anchored at the end (or beginning) of April     |
    +----------+--------------------------------------------------------------------+
    | Q(S)-MAY | Quarter frequency, anchored at the end (or beginning) of May       |
    +----------+--------------------------------------------------------------------+
    | Q(S)-JUN | Quarter frequency, anchored at the end (or beginning) of June      |
    +----------+--------------------------------------------------------------------+
    | Q(S)-JUL | Quarter frequency, anchored at the end (or beginning) of July      |
    +----------+--------------------------------------------------------------------+
    | Q(S)-AUG | Quarter frequency, anchored at the end (or beginning) of August    |
    +----------+--------------------------------------------------------------------+
    | Q(S)-SEP | Quarter frequency, anchored at the end (or beginning) of September |
    +----------+--------------------------------------------------------------------+
    | Q(S)-OCT | Quarter frequency, anchored at the end (or beginning) of October   |
    +----------+--------------------------------------------------------------------+
    | Q(S)-NOV | Quarter frequency, anchored at the end (or beginning) of November  |
    +----------+--------------------------------------------------------------------+
    | Q(S)-DEC | Quarter frequency, anchored at the end (or beginning) of December  |
    +----------+--------------------------------------------------------------------+

    Finally, the following calendar aliases are supported.

    +--------------------------------+---------------------------------------+
    | Alias                          | Date type                             |
    +================================+=======================================+
    | standard, gregorian            | ``cftime.DatetimeGregorian``          |
    +--------------------------------+---------------------------------------+
    | proleptic_gregorian            | ``cftime.DatetimeProlepticGregorian`` |
    +--------------------------------+---------------------------------------+
    | noleap, 365_day                | ``cftime.DatetimeNoLeap``             |
    +--------------------------------+---------------------------------------+
    | all_leap, 366_day              | ``cftime.DatetimeAllLeap``            |
    +--------------------------------+---------------------------------------+
    | 360_day                        | ``cftime.Datetime360Day``             |
    +--------------------------------+---------------------------------------+
    | julian                         | ``cftime.DatetimeJulian``             |
    +--------------------------------+---------------------------------------+

    Examples
    --------
    This function returns a ``CFTimeIndex``, populated with ``cftime.datetime``
    objects associated with the specified calendar type, e.g.

    >>> xr.cftime_range(start="2000", periods=6, freq="2MS", calendar="noleap")
    CFTimeIndex([2000-01-01 00:00:00, 2000-03-01 00:00:00, 2000-05-01 00:00:00,
                 2000-07-01 00:00:00, 2000-09-01 00:00:00, 2000-11-01 00:00:00],
                dtype='object', length=6, calendar='noleap', freq='2MS')

    As in the standard pandas function, three of the ``start``, ``end``,
    ``periods``, or ``freq`` arguments must be specified at a given time, with
    the other set to ``None``.  See the `pandas documentation
    <https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.date_range.html>`_
    for more examples of the behavior of ``date_range`` with each of the
    parameters.

    See Also
    --------
    pandas.date_range
    rq   zZOf the arguments 'start', 'end', 'periods', and 'freq', three must be specified at a time.NFTleftrightz-Closed must be either 'left', 'right' or Noner   r   r6   )name)r   rW   r   r   r   r   r\   arraylistr   lenr   )r`   ra   r   r   r   r   closedr   datesr   Zleft_closedZright_closedr   r   r   cftime_rangeT  s<     4



 (r   c
              
   C  s   ddl m}
 |dk	rd}	|
|r|	dk	rztj| |||||||dW S  tjjk
r| } z|	dkrltd|W 5 d}~X Y qX n|	dkrtd| d	t| |||||||d
S )a  Return a fixed frequency datetime index.

    The type (:py:class:`xarray.CFTimeIndex` or :py:class:`pandas.DatetimeIndex`)
    of the returned index depends on the requested calendar and on `use_cftime`.

    Parameters
    ----------
    start : str or datetime-like, optional
        Left bound for generating dates.
    end : str or datetime-like, optional
        Right bound for generating dates.
    periods : int, optional
        Number of periods to generate.
    freq : str or None, default: "D"
        Frequency strings can have multiples, e.g. "5H".
    tz : str or tzinfo, optional
        Time zone name for returning localized DatetimeIndex, for example
        'Asia/Hong_Kong'. By default, the resulting DatetimeIndex is
        timezone-naive. Only valid with pandas DatetimeIndex.
    normalize : bool, default: False
        Normalize start/end dates to midnight before generating date range.
    name : str, default: None
        Name of the resulting index
    closed : {"left", "right"} or None, default: None
        Make the interval closed with respect to the given frequency to the
        "left", "right", or both sides (None).
    calendar : str, default: "standard"
        Calendar type for the datetimes.
    use_cftime : boolean, optional
        If True, always return a CFTimeIndex.
        If False, return a pd.DatetimeIndex if possible or raise a ValueError.
        If None (default), return a pd.DatetimeIndex if possible,
        otherwise return a CFTimeIndex. Defaults to False if `tz` is not None.

    Returns
    -------
    CFTimeIndex or pd.DatetimeIndex

    See also
    --------
    pandas.date_range
    cftime_range
    date_range_like
    r   )r	   NFT)r`   ra   r   r   tzr   r   r   zLDate range is invalid for pandas DatetimeIndex, try using `use_cftime=True`.zInvalid calendar z7 for pandas DatetimeIndex, try using `use_cftime=True`.)r`   ra   r   r   r   r   r   r   )xarray.coding.timesr	   r   
date_rangeerrorsZOutOfBoundsDatetimerW   r   )r`   ra   r   r   r   r   r   r   r   r   r	   errr   r   r   r   /  sH    8

r   c                 C  sF  ddl m} ddlm} t| tjtfsLt| |r<| jdksDt	| sLt
d|| }|dkrdt
dt| ||}| j }| j }t| jrd}t|}t|}nt| tr| j}n| jj}||krt| j|A r| S t||}	t||	}
t||	}|j|jkr.tt|ttttfr.|j|jd	}t|
 | ||d
S )aQ  Generate a datetime array with the same frequency, start and end as
    another one, but in a different calendar.

    Parameters
    ----------
    source : DataArray, CFTimeIndex, or pd.DatetimeIndex
        1D datetime array
    calendar : str
        New calendar name.
    use_cftime : bool, optional
        If True, the output uses :py:class:`cftime.datetime` objects.
        If None (default), :py:class:`numpy.datetime64` values are used if possible.
        If False, :py:class:`numpy.datetime64` values are used or an error is raised.

    Returns
    -------
    DataArray
        1D datetime coordinate with the same start, end and frequency as the
        source, but in the new calendar. The start date is assumed to exist in
        the target calendar. If the end date doesn't exist, the code tries 1
        and 2 calendar days before. There is a special case when the source time
        series is daily or coarser and the end of the input range is on the
        last day of the month. Then the output range will also end on the last
        day of the month in the new calendar.
    r   )
infer_freq)	DataArrayr   zH'source' must be a 1D array of datetime objects for inferring its range.Nz[`date_range_like` was unable to generate a range as the source frequency was not inferable.r   rz   )r`   ra   r   r   ) Zxarray.coding.frequenciesr   Zxarray.core.dataarrayr   r"   r   ZDatetimeIndexr   ndimr   rW   r
   r   r   maxr   Zdtyper   r   dtr   r   ri   Zdaysinmonthr   r   r   r|   rR   rn   r   	isoformat)sourcer   r   r   r   r   Zsource_startZ
source_endZsource_calendarZ	date_typer`   ra   r   r   r   date_range_like  sV    







 
r   )T)r`   )rq   )N)NNNr   FNNr   )
NNNr   NFNNr   N)N)Er   
__future__r   r   r   r   	functoolsr   typingr   Znumpyr\   Zpandasr   Zxarray.coding.cftimeindexr   r   r   r	   r
   r   r   Zxarray.core.commonr   r   Zxarray.core.pdcompatr   r   r   r   r   rO   rJ   rb   rl   rm   rp   rt   ru   rv   r|   r   r   r   r   r   r   r   rR   rS   rT   rU   rV   rX   r   joinkeysZ_FREQUENCY_CONDITIONr   ZCFTIME_TICKSr   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s*  )

W&	

)4&






















































E
9        
 ]          
_