o
    iP                     @  s8  d 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dlmZ d	Zer:dd
lZddlmZ ddlmZ g dZeG dd deZdPddZdQddZd
d	ddRd d!Z	"	#dSdTd(d)Z			"	#	
dUdVd-d.ZdWd0d1ZdXdYd5d6ZdZd7d8Zd[d?d@Zd\dBdCZd]dEdFZ 	#	G	Hd^d_dKdLZ!d`dNdOZ"d
S )azYTime humanizing functions.

These are largely borrowed from Django's `contrib.humanize`.
    )annotations)Enum)total_ordering   )_gettext)	_ngettext)intcommaFN)Iterable)Any)naturaldate
naturaldaynaturaldeltanaturaltimeprecisedeltac                   @  s6   e Zd ZdZdZdZdZdZdZdZ	dZ
dddZdS )Unitr   r                     otherr
   returnc                 C  s   | j |j u r| j|jk S tS )N)	__class__valueNotImplemented)selfr    r   A/home/ubuntu/.local/lib/python3.10/site-packages/humanize/time.py__lt__)   s   zUnit.__lt__N)r   r
   r   r
   )__name__
__module____qualname__MICROSECONDSMILLISECONDSSECONDSMINUTESHOURSDAYSMONTHSYEARSr   r   r   r   r   r      s    r   r   dt.datetimec                  C  s   dd l } | j  S )Nr   )datetimenow)dtr   r   r   _now/   s   
r/   deltadt.timedeltac                 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/   )r0   r-   r   r   r   _abs_timedelta5   s   
	r3   )r-   preciser   r
   r-   dt.datetime | Noner4   booltuple[Any, Any]c             	   C  s   ddl }|s	t }t| |j r| }||  }n1t| |jr#||  }| }n$z|r(| nt| } |j| d}|| }W n ttfyF   d| f Y S w |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)`.
    r   Nseconds)r,   r/   
isinstance	timedeltaround
ValueError	TypeErrorr3   )r   r-   r4   r.   dater0   r   r   r   _date_and_deltaD   s"   
r@   Tr9   dt.timedelta | floatmonthsminimum_unitstrc              	   C  sl  ddl }t|  }|tjtjtjfvrd| d}t||}t| |jr)| }n zt	|  t
| } |j| d}W n ttfyH   t|  Y S w |}t|}|jd }	|jd }
t|
d }|	dkr|
dk r|jdkr|tjkr|jd	k rtd
d|j|j S |tjks|tjkrd	|j  krdk rn tdS |jd	 }tddt	|| S tdS |jdkrtdS |jdk rtdd|j|j S d|j  krdk rn nt|jd }|dkrtdS |dkrtdS tdd|| S d|jkrt|jd }|dkr	tdS |dkrtdS tdd|| S n|	dkr[|
dkr)tdS |s4tdd|
|
 S |dkrAtdd|
|
 S |dkrJtdS |d krStd!S td"d#|| S |	dkr|dkrn|
dkrntd!S |dkr{td$d%|
|
 S |r|dkrtd&S |d kr|	d7 }	td'd(|	|	 S td)d*|| S td$d%|
|
 S td'd(|	d+d,t|	 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.

    The timedelta will be rounded to the nearest unit that makes sense.

    Args:
        value (datetime.timedelta, int or float): 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.

    Returns:
        str (str or `value`): A natural representation of the amount of time
            elapsed unless `value` is not datetime.timedelta or cannot be
            converted to int (cannot be float due to 'inf' or 'nan').
            In that case, a `value` is returned unchanged.

    Raises:
        OverflowError: If `value` is too large to convert to datetime.timedelta.

    Examples:
        Compare two timestamps in a custom local timezone::

        ```pycon
        >>> 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 - now) == "30 minutes"
        True
        ```

    r   NzMinimum unit 'z' not supportedr8   m       >@r     %d microsecond%d microsecondsi@B %d millisecond%d millisecondsa momentza second<   	%d second
%d seconds  za minutezan hour	%d minute
%d minutes   za day%d hour%d hours%d day%d daysza month   za year%d month	%d monthsz1 year, %d dayz1 year, %d daysz1 year, 1 month%d year%d yearsz1 year, %d monthz1 year, %d months%d%s)r,   r   upperr%   r$   r#   r=   r:   r;   intfloatr>   rD   absr2   r<   r9   microsecondsr   _replacer   )r   rB   rC   r.   tmpmsgmin_unitr0   
use_monthsyearsr2   
num_monthsmillisecondsminuteshoursr   r   r   r   _   s   *



"















r   "dt.datetime | dt.timedelta | floatfuturewhenc           
      C  s   ddl }t| } t|}|pt }t| |d\}}|du r!t| S t| |j |jfr.||k}|r4tdntd}	t|||}|tdkrHtdS t|	| 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.

    The time will be rounded to the nearest unit that makes sense.

    Args:
        value (datetime.datetime, datetime.timedelta, int or float): A `datetime`, a
            `timedelta`, or a number of seconds.
        future (bool): Ignored for `datetime`s and `timedelta`s, where the tense is
            always figured out based on the current time. For integers and floats, 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   N)r-   z%s from nowz%s agorL   r-   )	r,   _convert_aware_datetimer/   r@   rD   r:   r;   rd   r   )
r   rp   rB   rC   rq   r.   r-   r?   r0   agor   r   r   r      s   
r   )dt.datetime | dt.timedelta | float | Nonec                 C  s2   ddl }t| |j r| jdur|j |  } | S )zIConvert aware datetime to naive datetime and pass through any other type.r   N)r,   r:   tzinfofromtimestamp	timestamp)r   r.   r   r   r   rr   ,  s   rr   %b %ddt.date | dt.datetimeformatc              	   C  s   ddl }z|| j| j| j} W n ty   t|  Y S  ttfy+   t|  Y S w | |j	  }|j
dkr<tdS |j
dkrEtdS |j
dkrNt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   Ntodayr   tomorrow	yesterday)r,   r?   yearmonthdayAttributeErrorrD   OverflowErrorr=   r{   r2   rd   strftime)r   rz   r.   r0   r   r   r   r   7  s    



r   c              	   C  s   ddl }z|| j| j| j} W n ty   t|  Y S  ttfy+   t|  Y S w t	| |j
  }|jdkr?t| dS t| S )zKLike `naturalday`, but append a year for dates more than ~five months away.r   Ngc@z%b %d %Y)r,   r?   r   r   r   r   rD   r   r=   r3   r{   r2   r   )r   r.   r0   r   r   r   r   W  s   

r   ra   divisorunitsuppressIterable[Unit]tuple[float, float]c                 C  sD   ||krt || | dfS ||v rd| fS t| |\}}|t|fS )a  Divide `value` by `divisor`, returning the quotient and remainder.

    If `unit` is `minimum_unit`, the quotient will be the rounding of `value / divisor`
    according to the `format` string and the remainder will be zero. The rationale 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, [], "%0.2f")
    (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.2f")
    (0, 36)

    In other cases, return the quotient and remainder as `divmod` would do it.

    >>> _quotient_and_remainder(36, 24, Unit.DAYS, Unit.HOURS, [], "%0.2f")
    (1, 12)

    r   )_rounding_by_fmtdivmodr`   )r   r   r   rC   r   rz   qrr   r   r   _quotient_and_remainderi  s    r   rh   c                 C  s:   | |v rt D ]}|| kr||vr|  S qd}t|| 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 greater 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   r=   )rh   r   r   rg   r   r   r   _suitable_minimum_unit  s   r   	set[Unit]c                 C  s.   t |}tD ]}|| kr |S || 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)rh   r   r   r   r   r   _suppress_lower_units  s   r   r   %0.2fdt.timedelta | float | NoneIterable[str]c           $   
   C  s  t | dd\}}|du rt| S dd |D }t|  }t||}~t||}|j}|j}	|j}
t	t\}}}}}}}}t
|d||||\}}t
|d||||\}}|d d	 |	 }	t
|	d
||||\}}	t
|	d	||||\}}	t
|	d||||\}}	|	d |
 }
t
|
d||||\}	}
t
|
d||||\}}
|dkr||vr|d8 }|	d7 }	|	dkr||vr|	d8 }	|d7 }|dkr||vr|d8 }|d7 }|dkr||vr|d8 }|d7 }|dkr||vr|d8 }|d7 }|dkr||vr|d8 }|d7 }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s9|s||krd|  k rEd"k rIn nd"nt|}t|||} d!dl}!||krm|!|d! d!krm| d#|} n$||kr|!|d! d!krt|}| d#d$} || t|  q#|| |  ||kr nq#t|dkr|d! S d%|dd& }"|d& }#td'|"|#f S )(a:  Return a precise representation of a timedelta or number of seconds.

    ```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'

    ```
    T)r4   Nc                 S  s   h | ]}t |  qS r   )r   r_   ).0sr   r   r   	<setcomp>  s    zprecisedelta.<locals>.<setcomp>rE   rF   rS   rP   iQ rM   g    .ArG   r      rX   r[   r\   rY   rZ   rV   rW   rT   rU   rQ   rR   rN   rO   rJ   rK   rH   rI   r   r   r]   r^   z, r}   z	%s and %s)r@   rD   r   r_   r   r   r2   r9   rc   listr   zipreversedr`   r   mathmodfre   appendr   lenjoinrd   )$r   rC   r   rz   r?   r0   suppress_setrh   r2   secsusecsr#   r$   r%   r&   r'   r(   r)   r*   rj   rB   rn   rm   msecsfmtstextsr   fmtsingular_txt
plural_txt	fmt_value
_fmt_valuefmt_txtr   headtailr   r   r   r     s   H


(

r   float | intc                 C  s4   | | }zt |}W |S  ty   t|}Y |S w )al  Round a number according to the string format provided.

    The string format is the old printf-style string formatting.

    If we are using a format which truncates the value, such as "%d" or "%i", the
    returned value will be of type `int`.

    If we are using a format which rounds the value, such as "%.2f" or even "%.0f",
    we will return a float.
    )r`   r=   ra   )rz   r   resultr   r   r   r     s   

r   )r   r+   )r0   r1   r   r1   )r   r
   r-   r5   r4   r6   r   r7   )Tr9   )r   rA   rB   r6   rC   rD   r   rD   )FTr9   N)r   ro   rp   r6   rB   r6   rC   rD   rq   r5   r   rD   )r   rt   r   r
   )rx   )r   ry   rz   rD   r   rD   )r   ry   r   rD   )r   ra   r   ra   r   r   rC   r   r   r   rz   rD   r   r   )rh   r   r   r   r   r   )rh   r   r   r   r   r   )r9   r   r   )
r   r   rC   rD   r   r   rz   rD   r   rD   )rz   rD   r   ra   r   r   )#__doc__
__future__r   enumr   	functoolsr   i18nr   rd   r   numberr   TYPE_CHECKINGr,   r.   collections.abcr	   typingr
   __all__r   r/   r3   r@   r   r   rr   r   r   r   r   r   r   r   r   r   r   r   <module>   sP    	

 
3
 

-
 L