Skip to content

Preserve exact microsecond counts when larger units are suppressed - #500

Open
Sskift wants to merge 1 commit into
python-humanize:mainfrom
Sskift:fix/precisedelta-microsecond-precision
Open

Sskift wants to merge 1 commit into
python-humanize:mainfrom
Sskift:fix/precisedelta-microsecond-precision

Conversation

@Sskift

@Sskift Sskift commented Nov 2, 2026

Copy link
Copy Markdown

When every unit above microseconds is suppressed, precisedelta() can round the microsecond count even though the input is an exact timedelta. This occurs for durations around 285 years or longer, where the count reaches the integer precision limit of a float:

from datetime import timedelta
from humanize import precisedelta

precisedelta(
    timedelta(microseconds=2**53 + 1),
    minimum_unit="microseconds",
    suppress=["years", "months", "days", "hours", "minutes", "seconds", "milliseconds"],
)
# Before: '9007199254740992 microseconds'
# After:  '9007199254740993 microseconds'

Changes proposed in this pull request:

  • Use an integer multiplier when converting the remaining seconds to microseconds, retaining the exact count when larger units are suppressed.
  • Add boundary regressions around 2**53, including negative timedeltas under the existing absolute-duration behavior.

Validation on Windows with Python 3.12.10: the new cases produced 4 failures and 2 passing controls before the fix. Afterward, all 398 time tests and the full suite with source doctests pass (897 passed, 2 skipped). The skipped tests require GNU gettext tools; all 36 existing translation catalogs were compiled locally with polib. Project-pinned Ruff 0.16.10 and Black 26.10.0 pass on the changed files, mypy 2.4.0 passes all 14 files, and git diff --check passes.

Prepared and tested with OpenAI Codex assistance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant