Ë Ï_�EzÀy¦ãó¨—dZddlmZddlZddlZddlZddlZddl m Z ddl m Z ddlm Z ddlmZdd lmZdd lmZgd ¢Ze Gd „d e ««Zdd„Zdd„Zddœ dd„Z d d d„Z d! d"d„Z d#d„Zd$d%d„Zd&d„Z d'd„Z d(d„Zd)d„Z d*d„Z! d+ d,d„Z"y)-zYTime humanizing functions. These are largely borrowed from Django's `contrib.humanize`. é)Ú annotationsN)ÚEnum)Útotal_ordering)ÚAnyé)Ú_gettext)Ú _ngettext)Úintcomma)Ú naturaldeltaÚ naturaltimeÚ naturaldayÚ naturaldateÚ precisedeltacó4—eZdZdZdZdZdZdZdZdZ dZ d d „Z y ) ÚUnitrréééééécóp—|j|jur|j|jkStS©N)Ú __class__ÚvalueÚNotImplemented)ÚselfÚothers ú2/usr/lib/python3.12/site-packages/humanize/time.pyÚ__lt__z Unit.__lt__'s+€Ø �>‰>˜UŸ_™_Ñ ,Ø—:‘: § ¡ Ñ+Ð +ÜÐóN)rú typing.AnyÚreturnr") Ú__name__Ú __module__Ú __qualname__Ú MICROSECONDSÚ MILLISECONDSÚSECONDSÚMINUTESÚHOURSÚDAYSÚMONTHSÚYEARSr ©r!rrrs/„à€LØ€LØ€GØ€GØ €EØ €DØ €FØ €Eôr!rcó>—tjj«Sr)ÚdtÚdatetimeÚnowr/r!rÚ_nowr4-s€Ü �;‰;�?‰?Ó Ðr!cóH—|jdkrt«}|||zz S|S)zÓReturn an "absolute" value for a timedelta, always representing a time distance. Args: delta (datetime.timedelta): Input timedelta. Returns: datetime.timedelta: Absolute timedelta. r)Údaysr4)Údeltar3s rÚ_abs_timedeltar81s*€ð ‡z�z�A‚~Ü‹fˆØ�c˜E‘kÑ"Ð"Ø €Lr!©r3có<—|s t«}t|tj«r|}||z }nIt|tj«r||z }|}n' t |«}tj|¬«}||z }|t|«fS#t tf$rd|fcYSwxYw)zˆTurn a value into a date and a timedelta which represents how long ago it was. If that's not possible, return `(None, value)`. ©ÚsecondsN) r4Ú isinstancer1r2Ú timedeltaÚintÚ ValueErrorÚ TypeErrorr8)rr3Údater7s rÚ_date_and_deltarC@s�€ñ Ü‹fˆÜ�%œŸ™Ô%؈Ø�e‘ ‰Ü �Eœ2Ÿ<™<Ô (Ø�U‰{ˆØ‰ð ܘ“JˆEÜ—L‘L¨Ô/ˆEؘ‘;ˆDð ” Ó&Ð &Ð&øôœIÐ&ò ؘ�;Ò ð úsÁ&BÂBÂBcóp—t|j«}|tjtjtjfvrd|›d�}t |«‚|}t |tj«r|}n" t|«}tj|¬«}|}t|j«}t|j«} | dz} | dz} t| dz«} | �s\| dk�rV|dk(rÁ|tjk(r3|jdkr$t!d d |j«|jzS|tjk(s5|tjk(rJd|jcxkrd kr5n t#d«S|jdz } t!d d t| ««| zSt#d«S|dk(r t#d«S|dkrt!dd|«|zSd|cxkrdkr t#d«Sd|cxkrdkrnn|dz} t!dd| «| zSd|cxkrdkr t#d«Sd|krÆ|dz}t!dd|«|zS| dk(rT| dk(r t#d«S|st!dd| «| zS| st!dd| «| zS| dk(r t#d«St!d d!| «| zS| dk(rS| s | s t#d"«S| st!d#d$| «| zS|r | dk(r t#d%«St!d&d'| «| zSt!d#d$| «| zSt!d(d)| «j%d*d+«t'| «zS#t tf$rt|«cYSwxYw),aTReturn 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, 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. 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:: 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" zMinimum unit 'z' not supportedr;émç€>@rréèú%d microsecondú%d microsecondsi@Bú%d millisecondú%d millisecondsúa momentza secondé<ú %d secondú %d secondséxza minuteéú %d minuteú %d minutesi zan hourú%d hourú%d hoursza dayú%d dayú%d daysza monthú%d monthú %d monthsza yearz1 year, %d dayz1 year, %d daysz1 year, 1 monthz1 year, %d monthz1 year, %d monthsú%d yearú%d yearsú%dú%s)rÚupperr)r(r'r@r=r1r>r?rAÚstrÚabsr<r6Ú microsecondsr Ú_Úreplacer )rÚmonthsÚ minimum_unitÚtmpÚmsgÚmin_unitr7Ú use_monthsr<r6ÚyearsÚ num_monthsÚ millisecondsÚminutesÚhourss rr r Yss€ôF ˆ|×!Ñ!Ó#Ñ $€CØ ”4—<‘<¤×!2Ñ!2´D×4EÑ4EÐFÑFؘ|˜n¨OÐ<ˆÜ˜‹oÐØ€Hä�%œŸ™Ô&؉ð ܘ“JˆEÜ—L‘L¨Ô/ˆEð€Jä�%—-‘-Ó €GÜ ˆu�z‰z‹?€DØ �C‰K€EØ �#‰:€DÜ�T˜T‘\Ó"€Jâ �T˜A“XØ �aŠ<Øœ4×,Ñ,Ò,°×1CÑ1CÀdÒ1JäÐ.Ð0AÀ5×CUÑCUÓVØ×(Ñ(ñ)ðð œ4×,Ñ,Ò,ØœD×-Ñ-Ò-°$¸%×:LÑ:LÔ2XÈyÔ2Xô�Z“=Ð ð %×1Ñ1°DÑ8� äÐ.Ð0AÄ3À|ÓCTÓUØ"ñ#ðô�Z“=Ð à �aŠ<Ü�Z“=Ð à �RŠ<ܘ[¨,¸Ó@À7ÑJÐ Jà �Ô ˜3Ò Ü�Z“=Ð ð ð �'Ô ˜DÕ Ø ‘mˆGܘ[¨,¸Ó@À7ÑJÐ Jà �7Ô %˜XÒ %Ü�Y“<Ð ð &ð �'Š>ؘt‘OˆEܘY¨ °EÓ:¸UÑBÐ Bà �!ŠØ �1Š9Ü�W“:Ð áܘX y°$Ó7¸$Ñ>Ð >áܘX y°$Ó7¸$Ñ>Ð >à ˜Š?Ü�Y“<Р䘠[°*Ó=À ÑJÐJà �!ŠÙ¡$Ü�X“;Ð áÜÐ-Ð/@À$ÓGÈ$ÑNÐ Ná Ø˜QŠÜÐ*Ó+Ð+ôÐ,Ð.AÀ:ÓNØñð ô Ð)Ð+<¸dÓCÀdÑJÐJä �Y  ¨EÓ 2× :Ñ :¸4ÀÓ FÌÐRWËÑ XÐXøôeœIÐ&ò Ü�u“:Ò ð úsÁ:!LÌL5Ì4L5cóz—t|«}t|«}|xs t«}t||¬«\}}|€ t|«St |t j t jf«r||kD}|r td«n td«}t|||«}|td«k(r td«St||z«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, 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. r9z %s from nowz%s agorLr3) Ú_convert_aware_datetimer4rCr_r=r1r2r>rbr ) rÚfuturerdreÚwhenr3rBr7Úagos rr r Ýs¦€ô4 $ EÓ *€EÜ " 4Ó (€Dà Š.”$“&€Cä! %¨SÔ1�K€Dˆ%Ø €|Ü�5‹zÐä�%œ"Ÿ+™+¤r§|¡|Ð4Ô5ؘ‘ˆá$Œ!ˆMÔ ¬!¨H«+€CÜ ˜ ¨ Ó 5€Eà ”�*“ ÒÜ�‹xˆä ˆs�U‰{Ó Ðr!có¬—t|tj«r9|j�-tjj |j ««}|S)zIConvert aware datetime to naive datetime and pass through any other type.)r=r1r2ÚtzinfoÚ fromtimestampÚ timestamp)rs rrprp s;€ô�%œŸ™Ô%¨%¯,©,Ð*BÜ— ‘ ×)Ñ)¨%¯/©/Ó*;Ó<ˆØ €Lr!cóØ— tj|j|j|j«}|tjj«z }|jdk(r td«S|jdk(r td«S|jdk(r td«S|j|«S#t $rt |«cYSttf$rt |«cYSwxYw)zÎReturn 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ÚtomorrowéÿÿÿÿÚ yesterday) r1rBÚyearÚmonthÚdayÚAttributeErrorr_Ú OverflowErrorr@ryr6rbÚstrftime)rÚformatr7s rr r s¼€ðÜ—‘˜Ÿ ™  E§K¡K°·±Ó;ˆð ”B—G‘G—M‘M“OÑ #€Eà ‡z�z�Q‚Ü�‹zÐà ‡z�z�Q‚Ü�‹}Ðà ‡z�z�RÒÜ�‹~Ðà �>‰>˜&Ó !Ð!øô# òä�5‹zÒÜ œ:Ð &òä�5‹zÒðús‚5B7Â7C)à C)Ã(C)cóx— tj|j|j|j«}t|tjj«z «}|jdk\r t|d«St|«S#t $rt |«cYSttf$rt |«cYSwxYw)zKLike `naturalday`, but append a year for dates more than ~five months away.g«ªªªªc@z%b %d %Y) r1rBr}r~rr€r_r�r@r8ryr6r )rr7s rrr3s–€ðÜ—‘˜Ÿ ™  E§K¡K°·±Ó;ˆô ˜5¤2§7¡7§=¡=£?Ñ2Ó 3€EØ ‡z�z�\Ò!ܘ% Ó,Ð,Ü �eÓ Ðøô òä�5‹zÒÜ œ:Ð &òä�5‹zÒðús‚5BÂB9ÂB9Â8B9cóB—||k(r||z dfS||vrd|fSt||«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)Údivmod)rÚdivisorÚunitreÚsuppresss rÚ_quotient_and_remainderrŠCs9€ð> ˆ|ÒØ�w‰ Ð!Ð!à ˆxÑØ�%ˆxˆä �%˜Ó !Ð!r!cóD—||k(r |||z zdfS||vr d|||zzfS||fS)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) rr/)Úvalue1Úvalue2Úratiorˆrhr‰s rÚ_carryr�ksF€ð< ˆxÒØ˜ ™Ñ&¨Ð)Ð)à ˆxÑØ�&˜6 E™>Ñ)Ð)Ð)à �6ˆ>Ðr!cóZ—||vr&tD]}||kDsŒ ||vsŒ|cSd}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)rr@)rhr‰rˆrgs rÚ_suitable_minimum_unitr‘’s@€ð$�8Ñ߈DØ�h‹ 4¨xÒ#7Ø’ ððQˆÜ˜‹oÐà €Or!cód—t|«}tD]}||k(r|S|j|«Œ|S)aExtend 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)rhr‰rˆs rÚ_suppress_lower_unitsr•¯s>€ô�8‹}€HßˆØ �8Ò Ø ð €Oð � ‰ �TÕðð €Or!c ó—t|«\}}|€ t|«S|D�chc]}t|j«’Œ}}t|j«}t ||«}~t ||«}|j } |j} |j} tt«\} } }}}}}}t| d|||«\}} t| d|||«\}} t| | d|||«\} } t| d|||«\}} t| d|||«\}} t| | d|||«\} } t| d| ||«\}} t| d d | ||«\} }d d |fd d|fdd| fdd|fdd|fdd| fdd|fdd| fg}g}ttt«|«D]Â\}}|\}}} | d kDs|s©||k(r¤d | cxkrdkrnndn t| «}!t|||!«}"||k(r.t!j"| «d d kDr|"j%d|«}"n5||k(r0|"j%dd«}"|j'|"t)| «z«Œ¨|j'|"| z«||k(sŒÂnt+|«d k(r|d Sdj-|dd«}#|d}$t/d «|#|$fzScc}w)!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' ``` NrErFi€QrQrMg€„.ArGrrrZr[rXrYrVrWrTrUrRrSrNrOrJrKrHrIrr\r]z, r{z %s and %s)rCr_rr^r‘r•r6r<raÚlistrŠr�ÚzipÚreversedr?r ÚmathÚmodfrcÚappendr ÚlenÚjoinrb)%rrer‰rƒrBr7ÚsÚ suppress_setrhr6ÚsecsÚusecsr'r(r)r*r+r,r-r.rjrdrnrmÚmsecsÚ_unusedÚfmtsÚtextsrˆÚfmtÚ singular_txtÚ plural_txtÚ fmt_valueÚ _fmt_valueÚfmt_txtÚheadÚtails% rrr¿sð€ôP" %Ó(�K€Dˆ%Ø €|Ü�5‹zÐá-5Ó6©X¨”D˜Ÿ™›“O¨X€LÐ6ô�L×&Ñ&Ó(Ñ)€HÜ% h° Ó=€HØô)¨°<Ó@€Lð �:‰:€DØ �=‰=€DØ × Ñ €EäOSÜ óPÑL€L�, ¨°%¸¸vÀuô *¨$°°U¸HÀlÓS�K€Eˆ4Ü*¨4°°v¸xÈÓV�L€FˆDô˜˜d I¨t°X¸|ÓL�J€Dˆ$ä)¨$°°e¸XÀ|ÓT�K€Eˆ4Ü+¨D°"°g¸xÈÓV�M€GˆT䘘u c¨7°H¸lÓK�K€Dˆ%ä*Ø ˆt�\ 8¨\ó�L€Eˆ5ô ˜E 1 a¨°xÀÓN�N€Eˆ7ð �J Ð&Ø �[ &Ð)Ø �9˜dÐ#Ø �J Ð&Ø �l GÐ,Ø �l DÐ)Ø Ð,¨eÐ4Ø Ð,¨eÐ4ð €Dð€EÜœ¤$›¨Ö.‰ ˆˆcØ.1Ñ+ˆ �j )Ø �qŠ=¡¨4°8Ò+;Ø )Ô/¨aÕ/™´S¸³^ˆJÜ  ¨j¸*ÓEˆGØ�xÒ¤D§I¡I¨iÓ$8¸Ñ$;¸aÒ$?Ø!Ÿ/™/¨$°Ó7‘ؘ’Ø!Ÿ/™/¨$°Ó5�Ø— ‘ ˜W¤x° Ó':Ñ:Ô;Øà �L‰L˜ 9Ñ,Ô -à �8Ó Ù ð/ô" ˆ5ƒz�Q‚Ø�Q‰xˆà �9‰9�U˜3˜B�ZÓ €DØ �‰9€Dä ˆ[‹>˜T 4˜LÑ (Ð(ùòu7s I=)r#z dt.datetime)r7ú dt.timedeltar#r¯)rr"r3údt.datetime | Noner#ztuple[typing.Any, typing.Any])Tr<)rzdt.timedelta | floatrdÚboolrer_r#r_)FTr<N) rz"dt.datetime | dt.timedelta | floatrqr±rdr±rer_rrr°r#r_)rz)dt.datetime | dt.timedelta | float | Noner#r)z%b %d)rúdt.date | dt.datetimerƒr_r#r_)rr²r#r_) rÚfloatr‡r³rˆrrerr‰zcollections.abc.Iterable[Unit]r#útuple[float, float])rŒr³r�r³rŽr³rˆrrhrr‰útyping.Iterable[Unit]r#r´)rhrr‰rµr#r)rhrr‰rµr#z set[Unit])r<r/z%0.2f) rzdt.timedelta | int | Nonerer_r‰ztyping.Iterable[str]rƒr_r#r_)#Ú__doc__Ú __future__rÚcollections.abcÚ collectionsr2r1ršÚtypingÚenumrÚ functoolsrrÚi18nrrbr Únumberr Ú__all__rr4r8rCr r rpr rrŠr�r‘r•rr/r!rÚrÀsöðñõ#ãÛÛ Û ÝÝ$ÝåÝÝò €ðô ˆ4ó óð ó ó ð 59ñ'Ø ð'Ø1ð'à"ó'ð6Ø!ðAYØ ðAYà ðAYððAYð ó AYðLØØ!Ø#ð ,Ø -ð,à ð,ð ð,ðð ,ð ð ,ð  ó ,ð^Ø 4ðàóô"ó< ð %"Ø ð%"à ð%"ð ð%"ðð %"ð -ð %"ð ó %"ðP$Ø ð$à ð$ð ð$ð ð $ð ð $ð $ð $ðó$óNó: ð$"Ø%'Øð f)Ø $ðf)àðf)ð#ðf)ð ð f)ð  ô f)r!