U
    dT0                     @   s  d Z ddlZddlZddlZddlZddlmZ ddl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 ddlmZ dd	lmZ d
dlmZ d
dlmZ d
dlmZ dZejddZdZ e!e"e e#dZ$dd dd dd dZ%dddd fdddd fddd d fd!d"d#d ffZ&e
dZ'dZ(G d$d% d%eZ)G d&d' d'Z*e* Zd(d) Z+d*d+ Z,dJd,d-Z-d.d/ Z.d0d1 Z/dKd4d5Z0d6d7 Z1d8d9 Z2d:d; Z3d<d= Z4d>d? Z5dLd@dAZ6G dBdC dCZ7eej8fdDdEZ9e9fdFdGZ:dMdHdIZ;dS )Nz<Utilities related to dates, times, intervals, and timezones.    N)
monthrange)datedatetime	timedeltatzinfo)reprcall)cached_property)AmbiguousTimeErrorFixedOffset)timezone)utc   )
dictfilter)parse_iso8601)	pluralize)LocalTimezoner   maybe_timedeltadelta_resolution	remainingrateweekdayhumanize_secondsmaybe_iso8601is_naive
make_awarelocalizeto_utcmaybe_make_awareffwd	utcoffsetadjust_timestamp get_exponential_backoff_interval
C_REMDEBUGF)sunmontuewedthufrisat   c                 C   s   | S N nr,   r,   5/tmp/pip-unpacked-wheel-mu1yl971/celery/utils/time.py<lambda>"       r0   c                 C   s   | d S N      N@r,   r-   r,   r,   r/   r0   #   r1   c                 C   s   | d d S r2   r,   r-   r,   r,   r/   r0   $   r1   )smhdayg     @c                 C   s
   t | dS N.2fformatr-   r,   r,   r/   r0   (   r1   hourg      @c                 C   s
   t | dS r8   r:   r-   r,   r,   r/   r0   )   r1   minuter3   c                 C   s
   t | dS r8   r:   r-   r,   r,   r/   r0   *   r1   second      ?c                 C   s
   t | dS r8   r:   r-   r,   r,   r/   r0   +   r1   c                       sT   e Zd ZdZi Z fddZdd Zdd Zdd	 Zd
d Z	dd Z
dd Z  ZS )r   zpLocal time implementation.

    Note:
        Used only when the :setting:`enable_utc` setting is disabled.
    c                    sL   t tj d| _tjr(t tj d| _n| j| _| j| j | _t 	  d S )Nseconds)
r   _timer   	STDOFFSETdaylightaltzone	DSTOFFSETDSTDIFFsuper__init__self	__class__r,   r/   rI   <   s    zLocalTimezone.__init__c                 C   s   dt | j d ddS )Nz<LocalTimezone: UTC  z+03d>)intrF   total_secondsrJ   r,   r,   r/   __repr__G   s    zLocalTimezone.__repr__c                 C   s   |  |r| jS | jS r+   )_isdstrF   rC   rK   dtr,   r,   r/   r   J   s    zLocalTimezone.utcoffsetc                 C   s   |  |r| jS tS r+   )rS   rG   ZEROrT   r,   r,   r/   dstM   s    zLocalTimezone.dstc                 C   s   t j| | S r+   )rB   tznamerS   rT   r,   r,   r/   rX   P   s    zLocalTimezone.tznamec                 C   s\   t | |jd }z| j| }W n& tk
rH   t| }| j|< Y nX ||j|dS )Nr3   r   )rP   r   rA   _offset_cacheKeyErrorr
   fromutcreplace)rK   rU   offsettzr,   r,   r/   r\   S   s    zLocalTimezone.fromutcc              	   C   sD   |j |j|j|j|j|j| ddf	}t|}t	|}|j
dkS )Nr   )yearmonthr7   r<   r=   r>   r   rB   mktime	localtimetm_isdst)rK   rU   ttZstampr,   r,   r/   rS   `   s        

zLocalTimezone._isdst)__name__
__module____qualname____doc__rZ   rI   rR   r   rW   rX   r\   rS   __classcell__r,   r,   rL   r/   r   3   s   r   c                   @   sP   e Zd ZdddZdddZdd Zdd	 Zd
d Zedd Z	edd Z
dS )_ZoneNc                 C   s   |d kr| j S | |S r+   )localget_timezone)rK   r   r,   r,   r/   tz_or_localk   s    z_Zone.tz_or_localc                 C   s(   t |rt||p| j}t|| |S r+   )r   r   r   r   rn   )rK   rU   rl   origr,   r,   r/   to_localq   s    z_Zone.to_localc                 C   s   |j d dS )N)r_   )
astimezonerT   r,   r,   r/   	to_systemv   s    z_Zone.to_systemc                 C   s    t |rt|| jS t|| jS r+   )r   r   rl   r   rT   r,   r,   r/   to_local_fallback{   s    z_Zone.to_local_fallbackc                 C   s   t |trt|S |S r+   )
isinstancestr	_timezone)rK   zoner,   r,   r/   rm      s    
z_Zone.get_timezonec                 C   s   t  S r+   )r   rJ   r,   r,   r/   rl      s    z_Zone.localc                 C   s
   |  dS )NUTC)rm   rJ   r,   r,   r/   r      s    z	_Zone.utc)N)NN)rf   rg   rh   rn   rp   rr   rs   rm   r   rl   r   r,   r,   r,   r/   rk   i   s   


rk   c                 C   s   t | tjrt| dS | S )z8Convert integer to timedelta, if argument is an integer.r@   )rt   numbersRealr   )deltar,   r,   r/   r      s    
r   c                 C   s   t | d}ddd fddd fddd ff}| j| j| j| j| j| jf}|D ]0\}}||d	krPt|d
| d| j	i  S qP| S )a  Round a :class:`~datetime.datetime` to the resolution of timedelta.

    If the :class:`~datetime.timedelta` is in days, the
    :class:`~datetime.datetime` will be rounded to the nearest days,
    if the :class:`~datetime.timedelta` is in hours the
    :class:`~datetime.datetime` will be rounded to the nearest hour,
    and so on until seconds, which will just return the original
    :class:`~datetime.datetime`.
    r      c                 S   s   | d S )NiQ r,   xr,   r,   r/   r0      r1   z"delta_resolution.<locals>.<lambda>   c                 S   s   | d S )NrN   r,   r}   r,   r,   r/   r0      r1      c                 S   s   | d S )N<   r,   r}   r,   r,   r/   r0      r1   r?   Nr   )
maxrQ   r`   ra   r7   r<   r=   r>   r   r   )rU   r{   Zresolutionsargsres	predicater,   r,   r/   r      s    



r   c                 C   s   |p
t  }t| jt|jkr>| |  kr>| j|jd} | | }|r\t||jdd}|| }tr~td	|| ||| |S )a_  Calculate the remaining time for a start date and a timedelta.

    For example, "how many seconds left for 30 seconds after start?"

    Arguments:
        start (~datetime.datetime): Starting date.
        ends_in (~datetime.timedelta): The end delta.
        relative (bool): If enabled the end time will be calculated
            using :func:`delta_resolution` (i.e., rounded to the
            resolution of `ends_in`).
        now (Callable): Function returning the current time and date.
            Defaults to :func:`datetime.utcnow`.

    Returns:
        ~datetime.timedelta: Remaining time.
    rY   r   )microsecondz8rem: NOW:{!r} START:{!r} ENDS_IN:{!r} END_DATE:{} REM:{})
r   utcnowru   r   r   r]   r   r"   printr;   )startZends_innowrelativeend_dateretr,   r,   r/   r      s     $    r   c                 C   sB   | r>t | tr6| d\}}}t|p&d t|p4dS | p<dS dS )zAConvert rate string (`"100/m"`, `"2/h"` or `"0.5/s"`) to seconds./r4   r   )rt   ru   	partitionRATE_MODIFIER_MAPfloat)rops_modifierr,   r,   r/   r      s    
r   c                 C   s<   | dd   }z
t| W S  tk
r6   t| Y nX dS )zReturn the position of a weekday: 0 - 7, where 0 is Sunday.

    Example:
        >>> weekday('sunday'), weekday('sun'), weekday('mon')
        (0, 0, 1)
    r   r|   N)lowerWEEKDAYSr[   )nameZabbreviationr,   r,   r/   r      s
    
r    r   c           	   	   C   st   t tt | d} tD ]<\}}}| |kr| t | }d||||t||  S q|rp| dkrpdj| ||dS |S )a[  Show seconds in human form.

    For example, 60 becomes "1 minute", and 7200 becomes "2 hours".

    Arguments:
        prefix (str): can be used to add a preposition to the output
            (e.g., 'in' will give 'in 1 second', but add nothing to 'now').
        now (str): Literal 'now'.
        microseconds (bool): Include microseconds.
    r9   z	{}{}{} {}g        z{prefix}{sep}{0:.2f} seconds)sepprefix)r   r;   
TIME_UNITSr   )	Zsecsr   r   r   microsecondsunitdivider	formatterwr,   r,   r/   r      s    
  r   c                 C   s   | sdS t | tr| S t| S )z:Either ``datetime | str -> datetime`` or ``None -> None``.N)rt   r   r   rU   r,   r,   r/   r      s
    
r   c                 C   s   | j dkp| j | dkS )z=Return :const:`True` if :class:`~datetime.datetime` is naive.N)r   r   r   r,   r,   r/   r     s    r   c              	   C   sn   z
|j }W n  tk
r*   | j|d Y S X z|| ddW S  tk
rh   t|| dd|| dd Y S X dS )z6Set timezone for a :class:`~datetime.datetime` object.rY   NZis_dstTF)r   AttributeErrorr]   r	   min)rU   r_   Z	_localizer,   r,   r/   r     s    

r   c              	   C   s   t | rt| |} | jtkr&| |} z
|j}W n tk
rH   |  Y S X z|| ddW S  tk
rt   ||  Y S  tk
r   t	|| dd|| dd Y S X dS )z>Convert aware :class:`~datetime.datetime` to another timezone.Nr   TF)
r   r   r   r   rq   	normalizer   	TypeErrorr	   r   )rU   r_   
_normalizer,   r,   r/   r     s     





r   c                 C   s   t | tjS )z1Convert naive :class:`~datetime.datetime` to UTC.)r   r   r   r   r,   r,   r/   r   /  s    r   c                 C   s2   t | r.t| } t| |dkr"tjnt|S | S )z@Convert dt to aware datetime, do nothing if dt is already aware.N)r   r   r   r   r   rn   )rU   r_   r,   r,   r/   r   4  s     r   c                	   @   s2   e Zd ZdZdddZdd Zdd	 Zd
d ZdS )r   zBVersion of ``dateutil.relativedelta`` that only supports addition.Nr   c
                 K   sZ   || _ || _|| _|| _|| _|| _|| _|| _|	| _|d | _	| jd k	pR| jd k	| _
d S )Nr*   )r`   ra   weeksr   r7   r<   r=   r>   r   daysZ	_has_time)rK   r`   ra   r   r   r7   r<   r=   r>   r   kwargsr,   r,   r/   rI   A  s    
zffwd.__init__c                 C   s   t dd| j| j| jdS )Nr   r,   )r   r   )r   _fieldsr   r   rJ   r,   r,   r/   rR   R  s    zffwd.__repr__c                 C   s   t |tstS | jp|j}| jp$|j}tt||d | jp>|j}|jf t	t
|  |||d}| jd k	r|td|  | j d d7 }|t| jd S )Nr   )r`   ra   r7   r*   )r   )rt   r   NotImplementedr`   ra   r   r   r7   r]   dictr   r   r   r   r   )rK   otherr`   ra   r7   r   r,   r,   r/   __radd__V  s    
  
 zffwd.__radd__c              	   K   s*   t | j| j| j| j| j| j| jdf|S )N)r`   ra   r7   r<   r=   r>   r   )r   r`   ra   r7   r<   r=   r>   r   )rK   extrar,   r,   r/   r   b  s        zffwd._fields)	NNr   NNNNNN)rf   rg   rh   ri   rI   rR   r   r   r,   r,   r,   r/   r   >  s           
r   c                 C   s   | j r| jd S | jd S )z*Return the current offset to UTC in hours.rN   )rd   rE   r   )timerc   r,   r,   r/   r   j  s    
r   c                 C   s   | ||  d  S )z-Adjust timestamp based on provided utcoffset.rN   r,   )tsr^   herer,   r,   r/   r    q  s    r    c                 C   s.   t || d|  }|r$t|d }td|S )z,Calculate the exponential backoff wait time.   r   r   )r   random	randranger   )ZfactorretriesmaximumZfull_jitterZ	countdownr,   r,   r/   r!   v  s    r!   )NF)r   r   r   F)N)F)<ri   ry   osr   r   rB   calendarr   r   r   r   r   Zkombu.utils.functionalr   Zkombu.utils.objectsr   Zpytzr	   r
   r   rv   r   Z
functionalr   Ziso8601r   textr   __all__environgetr"   ZDAYNAMESr   zipranger   r   r   rV   Z_local_timezoner   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   rc   r   r    r!   r,   r,   r,   r/   <module>   sb   	6%


	

,	 