Skip to content

Commit 93aefff

Browse files
committed
Support floats in precisedelta and fix bugs to make new tests pass.
1 parent 5dfee4b commit 93aefff

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

src/humanize/time.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import collections.abc
1010
import datetime as dt
1111
import math
12+
import re
1213
import typing
1314
from enum import Enum
1415
from functools import total_ordering
@@ -63,7 +64,7 @@ def _abs_timedelta(delta: dt.timedelta) -> dt.timedelta:
6364

6465

6566
def _date_and_delta(
66-
value: typing.Any, *, now: dt.datetime | None = None
67+
value: typing.Any, *, now: dt.datetime | None = None, precise: bool = False
6768
) -> tuple[typing.Any, typing.Any]:
6869
"""Turn a value into a date and a timedelta which represents how long ago it was.
6970
@@ -79,7 +80,7 @@ def _date_and_delta(
7980
delta = value
8081
else:
8182
try:
82-
value = int(value)
83+
value = value if precise else int(value)
8384
delta = dt.timedelta(seconds=value)
8485
date = now - delta
8586
except (ValueError, TypeError):
@@ -414,12 +415,12 @@ def _suppress_lower_units(min_unit: Unit, suppress: typing.Iterable[Unit]) -> se
414415

415416

416417
def precisedelta(
417-
value: dt.timedelta | int,
418+
value: dt.timedelta | float,
418419
minimum_unit: str = "seconds",
419420
suppress: typing.Iterable[str] = (),
420421
format: str = "%0.2f",
421422
) -> str:
422-
"""Return a precise representation of a timedelta.
423+
"""Return a precise representation of a timedelta or number of seconds.
423424
424425
```pycon
425426
>>> import datetime as dt
@@ -485,7 +486,7 @@ def precisedelta(
485486
486487
```
487488
"""
488-
date, delta = _date_and_delta(value)
489+
date, delta = _date_and_delta(value, precise=True)
489490
if date is None:
490491
return str(value)
491492

@@ -555,9 +556,13 @@ def precisedelta(
555556
("%d microsecond", "%d microseconds", usecs),
556557
]
557558

559+
round_fmt_value = re.fullmatch(r"%\d*(d|(\.0*f))", format)
560+
558561
texts: list[str] = []
559562
for unit, fmt in zip(reversed(Unit), fmts):
560563
singular_txt, plural_txt, fmt_value = fmt
564+
if round_fmt_value:
565+
fmt_value = round(fmt_value)
561566
if fmt_value > 0 or (not texts and unit == min_unit):
562567
fmt_txt = _ngettext(singular_txt, plural_txt, fmt_value)
563568
if unit == min_unit and math.modf(fmt_value)[0] > 0:

0 commit comments

Comments
 (0)