
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
U
    su]aB                     @   s   d Z ddlZddlZddlmZ ddlmZ ddlm	Z
 ddlmZ dd	d
ddgZeG dd deZdd Zdd ZddddZd*edddZd+eddd	Zd,eddd
ZedddZdd  Zd!d" Zd#d$ Zd%d& Zd-edd)dZdS ).zYTime humanizing functions.

These are largely borrowed from Django's `contrib.humanize`.
    N)Enum)total_ordering   )gettext)ngettextnaturaldeltanaturaltime
naturaldaynaturaldateprecisedeltac                   @   s4   e Zd ZdZdZdZdZdZdZdZ	dZ
d	d
 ZdS )Unitr   r                     c                 C   s   | j |j kr| j|jk S tS N)	__class__valueNotImplemented)selfother r   >/opt/alt/python38/lib/python3.8/site-packages/humanize/time.py__lt__#   s    zUnit.__lt__N)__name__
__module____qualname__MICROSECONDSMILLISECONDSSECONDSMINUTESHOURSDAYSMONTHSYEARSr   r   r   r   r   r      s   r   c                   C   s
   t j S r   )dtdatetimenowr   r   r   r   _now)   s    r*   c                 C   s    | j dk rt }|||   S | S )zReturn an "absolute" value for a timedelta, always representing a time distance.

    Args:
        delta (datetime.timedelta): Input timedelta.

    Returns:
        datetime.timedelta: Absolute timedelta.
    r   )daysr*   )deltar)   r   r   r   abs_timedelta-   s    	
r-   r)   c             	   C   s   |s
t  }t| tjr$| }||  }n\t| tjr>||  }| }nBz t| } tj| d}|| }W n  ttfk
r~   d| f Y S X |t|fS )zTurn a value into a date and a timedelta which represents how long ago it was.

    If that's not possible, return `(None, value)`.
    )secondsN)	r*   
isinstancer'   r(   	timedeltaint
ValueError	TypeErrorr-   )r   r)   dater,   r   r   r   date_and_delta<   s    
r6   Tr/   )returnc                 C   s  t |  }|t jt jt jfkr0td| d|}t| |d\}}|dkrP| S |}t|j}t|j	}	|	d }
|	d }	t
|	d }|
s|	dk r|dkr|t jkr|jd	k rtd
d|j|j S |t jks|t jkrd	|j  krdk rn n|jd	 }tdd|| S tdS |dkr,tdS |dk rFtdd|| S d|  kr^dk rjn ntdS d|  krdk rn n|d }tdd|| S d|  krdk rn ntdS d|k r|d }tdd|| S n|
dkrR|	dkrtdS |stdd|	|	 S |s.tdd|	|	 S |dkr@td S td!d"|| S n|
dkr|sp|	sptd#S |std$d%|	|	 S |r|dkrtd&S td'd(|| S ntd$d%|	|	 S ntd)d*|
|
 S dS )+a  Return a natural representation of a timedelta or number of seconds.

    This is similar to `naturaltime`, but does not add tense to the result.

    Args:
        value (datetime.timedelta): A timedelta or a number of seconds.
        months (bool): If `True`, then a number of months (based on 30.5 days) will be
            used for fuzziness between years.
        minimum_unit (str): The lowest unit that can be used.
        when (datetime.datetime): Point in time relative to which _value_ is
            interpreted.  Defaults to the current time in the local timezone.

    Returns:
        str: A natural representation of the amount of time elapsed.

    Examples
        Compare two timestamps in a custom local timezone::

        import datetime as dt
        from dateutil.tz import gettz

        berlin = gettz("Europe/Berlin")
        now = dt.datetime.now(tz=berlin)
        later = now + dt.timedelta(minutes=30)

        assert naturaldelta(later, when=now) == "30 minutes"
    zMinimum unit 'z' not supportedr.   Nm       >@r   r     %d microsecond%d microsecondsi@B %d millisecond%d millisecondsa momentza second<   	%d second
%d secondsx   za minute  	%d minute
%d minutesi   zan hour%d hour%d hoursza day%d day%d daysza month%d month	%d monthsza yearz1 year, %d dayz1 year, %d daysz1 year, 1 monthz1 year, %d monthz1 year, %d months%d year%d years)r   upperr!   r    r   r3   r6   absr/   r+   r2   microsecondsr   _)r   monthsminimum_unitwhentmpr5   r,   Z
use_monthsr/   r+   yearsZmillisecondsminuteshoursr   r   r   r   S   s    !



 









Fc           	      C   s   |pt  }t| |d\}}|dkr&| S t| tjtjfr@||k}|rLtdntd}t||||d}|tdkrxtdS || S )a  Return a natural representation of a time in a resolution that makes sense.

    This is more or less compatible with Django's `naturaltime` filter.

    Args:
        value (datetime.datetime, int): A `datetime` or a number of seconds.
        future (bool): Ignored for `datetime`s, where the tense is always figured out
            based on the current time. For integers, the return value will be past tense
            by default, unless future is `True`.
        months (bool): If `True`, then a number of months (based on 30.5 days) will be
            used for fuzziness between years.
        minimum_unit (str): The lowest unit that can be used.
        when (datetime.datetime): Point in time relative to which _value_ is
            interpreted.  Defaults to the current time in the local timezone.

    Returns:
        str: A natural representation of the input in a resolution that makes sense.
    r.   Nz%s from nowz%s ago)rU   r?   r)   )r*   r6   r0   r'   r(   r1   rR   r   )	r   futurerS   rT   rU   r)   r5   r,   Zagor   r   r   r      s    
%b %dc              	   C   s   zt | j| j| j} W n2 tk
r0   |  Y S  ttfk
rJ   |  Y S X | t j  }|j	dkrlt
dS |j	dkr~t
dS |j	dkrt
dS | |S )zReturn a natural day.

    For date values that are tomorrow, today or yesterday compared to
    present day return representing string. Otherwise, return a string
    formatted according to `format`.

    r   todayr   ZtomorrowZ	yesterday)r'   r5   yearmonthdayAttributeErrorOverflowErrorr3   r\   r+   rR   strftime)r   formatr,   r   r   r   r	      s    



c              	   C   sz   zt | j| j| j} W n2 tk
r0   |  Y S  ttfk
rJ   |  Y S X t| t j	  }|j
dkrrt| dS t| S )zKLike `naturalday`, but append a year for dates more than ~five months away.gc@z%b %d %Y)r'   r5   r^   r_   r`   ra   rb   r3   r-   r\   r+   r	   )r   r,   r   r   r   r
     s    


c                 C   s2   ||kr| | dfS ||kr$d| fS t | |S dS )a  Divide `value` by `divisor` returning the quotient and remainder.

    If `unit` is `minimum_unit`, makes the quotient a float number and the remainder
    will be zero. The rational is that if `unit` is the unit of the quotient, we cannot
    represent the remainder because it would require a unit smaller than the
    `minimum_unit`.

    >>> from humanize.time import _quotient_and_remainder, Unit
    >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.DAYS, [])
    (1.5, 0)

    If unit is in `suppress`, the quotient will be zero and the remainder will be the
    initial value. The idea is that if we cannot use `unit`, we are forced to use a
    lower unit so we cannot do the division.

    >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [Unit.DAYS])
    (0, 36)

    In other case return quotient and remainder as `divmod` would do it.

    >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [])
    (1, 12)

    r   N)divmod)r   ZdivisorunitrT   suppressr   r   r   _quotient_and_remainder  s
    rh   c                 C   s<   ||kr| ||  dfS ||kr0d|| |  fS | |fS dS )a  Return a tuple with two values.

    If the unit is in `suppress`, multiply `value1` by `ratio` and add it to `value2`
    (carry to right). The idea is that if we cannot represent `value1` we need to
    represent it in a lower unit.

    >>> from humanize.time import _carry, Unit
    >>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, [Unit.DAYS])
    (0, 54)

    If the unit is the minimum unit, `value2` is divided by `ratio` and added to
    `value1` (carry to left). We assume that `value2` has a lower unit so we need to
    carry it to `value1`.

    >>> _carry(2, 6, 24, Unit.DAYS, Unit.DAYS, [])
    (2.25, 0)

    Otherwise, just return the same input:

    >>> _carry(2, 6, 24, Unit.DAYS, Unit.SECONDS, [])
    (2, 6)
    r   Nr   )Zvalue1Zvalue2Zratiorf   min_unitrg   r   r   r   _carry7  s
    rj   c                 C   s6   | |kr2t D ]}|| kr||kr|  S qtd| S )a  Return a minimum unit suitable that is not suppressed.

    If not suppressed, return the same unit:

    >>> from humanize.time import _suitable_minimum_unit, Unit
    >>> _suitable_minimum_unit(Unit.HOURS, []).name
    'HOURS'

    But if suppressed, find a unit greather than the original one that is not
    suppressed:

    >>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS]).name
    'DAYS'

    >>> _suitable_minimum_unit(Unit.HOURS, [Unit.HOURS, Unit.DAYS]).name
    'MONTHS'
    z@Minimum unit is suppressed and no suitable replacement was found)r   r3   )ri   rg   rf   r   r   r   _suitable_minimum_unitV  s    
rk   c                 C   s,   t |}tD ]}|| kr q(|| q|S )a  Extend suppressed units (if any) with all units lower than the minimum unit.

    >>> from humanize.time import _suppress_lower_units, Unit
    >>> [x.name for x in sorted(_suppress_lower_units(Unit.SECONDS, [Unit.DAYS]))]
    ['MICROSECONDS', 'MILLISECONDS', 'DAYS']
    )setr   add)ri   rg   ur   r   r   _suppress_lower_unitst  s    ro   r   %0.2fc           !   
   C   s2  t | \}}|dkr| S dd |D }t|  }t||}~t||}|j}|j}|j}	tt\}
}}}}}}}t	|d|||\}}t	|d|||\}}t
||d|||\}}t	|d|||\}}t	|d|||\}}t
||	d	|||\}}	t	|	d
|||\}}	t
|	dd|
||\}	}dd|fdd|fdd|fdd|fdd|fdd|fdd|fdd|	fg}g }ttt|D ]\}}|\}}} | dks|s||krt||| }||krt| d dkr|d|}|||   ||krn qqnt|dkr|d S d|dd }|d } td || f S )!a%  Return a precise representation of a timedelta.

    ```pycon
    >>> import datetime as dt
    >>> from humanize.time import precisedelta

    >>> delta = dt.timedelta(seconds=3633, days=2, microseconds=123000)
    >>> precisedelta(delta)
    '2 days, 1 hour and 33.12 seconds'

    ```

    A custom `format` can be specified to control how the fractional part
    is represented:

    ```pycon
    >>> precisedelta(delta, format="%0.4f")
    '2 days, 1 hour and 33.1230 seconds'

    ```

    Instead, the `minimum_unit` can be changed to have a better resolution;
    the function will still readjust the unit to use the greatest of the
    units that does not lose precision.

    For example setting microseconds but still representing the date with milliseconds:

    ```pycon
    >>> precisedelta(delta, minimum_unit="microseconds")
    '2 days, 1 hour, 33 seconds and 123 milliseconds'

    ```

    If desired, some units can be suppressed: you will not see them represented and the
    time of the other units will be adjusted to keep representing the same timedelta:

    ```pycon
    >>> precisedelta(delta, suppress=['days'])
    '49 hours and 33.12 seconds'

    ```

    Note that microseconds precision is lost if the seconds and all
    the units below are suppressed:

    ```pycon
    >>> delta = dt.timedelta(seconds=90, microseconds=100)
    >>> precisedelta(delta, suppress=['seconds', 'milliseconds', 'microseconds'])
    '1.50 minutes'

    ```

    If the delta is too small to be represented with the minimum unit,
    a value of zero will be returned:

    ```pycon
    >>> delta = dt.timedelta(seconds=1)
    >>> precisedelta(delta, minimum_unit="minutes")
    '0.02 minutes'

    >>> delta = dt.timedelta(seconds=0.1)
    >>> precisedelta(delta, minimum_unit="minutes")
    '0 minutes'

    ```
    Nc                 S   s   g | ]}t |  qS r   )r   rO   ).0sr   r   r   
<listcomp>  s     z precisedelta.<locals>.<listcomp>r8   r9   iQ rD   r@   g    .Ar:   r   r   rM   rN   rK   rL   rI   rJ   rG   rH   rE   rF   rA   rB   r=   r>   r;   r<   z%dz, r]   z	%s and %s)r6   r   rO   rk   ro   r+   r/   rQ   listrh   rj   zipreversedr   mathmodfreplaceappendlenjoinrR   )!r   rT   rg   rd   r5   r,   ri   r+   ZsecsZusecsr   r    r!   r"   r#   r$   r%   r&   rW   rS   rY   rX   msecsZ_unusedZfmtsZtextsrf   fmtZsingular_txtZ
plural_txtZfmt_txtheadtailr   r   r   r     sh    C

    


)Tr/   N)FTr/   N)r[   )r/   r   rp   )__doc__r(   r'   rw   enumr   	functoolsr   Zi18nr   rR   r   __all__r   r*   r-   r6   strr   r   r	   r
   rh   rj   rk   ro   r   r   r   r   r   <module>   sJ   	   q    *!